Work around arm64 clang codegen issues breaking CI
CI / build-image (arm64, ubuntu-latest-arm64) (push) Successful in 22s
CI / build-image (amd64, ubuntu-latest-amd64) (push) Successful in 42s
CI / pre-commit (push) Successful in 34s
CI / release (arm64, ubuntu-latest-arm64) (push) Failing after 1m7s
CI / test (-DCMAKE_BUILD_TYPE=Debug, debug) (push) Successful in 2m35s
CI / test (-DCMAKE_CXX_FLAGS=-DUSE_64_BIT=1, 64-bit-versions) (push) Successful in 2m27s
CI / test (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc) (push) Successful in 2m35s
CI / test (-DUSE_SIMD_FALLBACK=ON, simd-fallback) (push) Successful in 2m27s
CI / release (amd64, ubuntu-latest-amd64) (push) Failing after 2m32s
CI / coverage (push) Failing after 2m20s
CI / build-image (arm64, ubuntu-latest-arm64) (push) Successful in 22s
CI / build-image (amd64, ubuntu-latest-amd64) (push) Successful in 42s
CI / pre-commit (push) Successful in 34s
CI / release (arm64, ubuntu-latest-arm64) (push) Failing after 1m7s
CI / test (-DCMAKE_BUILD_TYPE=Debug, debug) (push) Successful in 2m35s
CI / test (-DCMAKE_CXX_FLAGS=-DUSE_64_BIT=1, 64-bit-versions) (push) Successful in 2m27s
CI / test (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc) (push) Successful in 2m35s
CI / test (-DUSE_SIMD_FALLBACK=ON, simd-fallback) (push) Successful in 2m27s
CI / release (amd64, ubuntu-latest-amd64) (push) Failing after 2m32s
CI / coverage (push) Failing after 2m20s
Disable preserve_none under ASan on aarch64: every clang tested (20, 21, trunk 22) miscompiles the continuation chains with that combination, crashing ~97% of fuzz corpus tests. The chains still work with the default calling convention. See #38. Mark the masked Node3 scan results defined for valgrind on aarch64: clang 21+ lowers the in-bounds tests through flags+csel, which memcheck models imprecisely, tainting bits the mask provably clears. See #39. Skip valgrind tests in the arm64 release job, since -DNVALGRIND compiles out the client requests the workaround relies on. Both issues track filing upstream bugs.
This commit is contained in:
@@ -149,7 +149,11 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
ctest --no-compress-output --test-output-size-passed 100000 --test-output-size-failed 100000 -T Test -j "$(nproc)" --timeout 90 > /dev/null
|
# On arm64, valgrind needs the MAKE_MEM_DEFINED client requests for
|
||||||
|
# https://git.weaselab.dev/weaselab/conflict-set/issues/39, but this
|
||||||
|
# build has -DNVALGRIND, which compiles them out. Skip valgrind
|
||||||
|
# tests here; they run annotated in the test job.
|
||||||
|
ctest --no-compress-output --test-output-size-passed 100000 --test-output-size-failed 100000 ${{ matrix.arch == 'arm64' && '-E valgrind' || '' }} -T Test -j "$(nproc)" --timeout 90 > /dev/null
|
||||||
|
|
||||||
- name: Package
|
- name: Package
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+28
-2
@@ -52,6 +52,14 @@ limitations under the License.
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __SANITIZE_ADDRESS__
|
||||||
|
#if defined(__has_feature)
|
||||||
|
#if __has_feature(address_sanitizer)
|
||||||
|
#define __SANITIZE_ADDRESS__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <memcheck.h>
|
#include <memcheck.h>
|
||||||
|
|
||||||
using namespace weaselab;
|
using namespace weaselab;
|
||||||
@@ -2246,6 +2254,13 @@ bool checkMaxBetweenExclusiveImpl(Node3 *n, int begin, int end,
|
|||||||
mask |= inBounds(self->index[i]) << i;
|
mask |= inBounds(self->index[i]) << i;
|
||||||
}
|
}
|
||||||
mask &= (1 << self->numChildren) - 1;
|
mask &= (1 << self->numChildren) - 1;
|
||||||
|
#ifdef __aarch64__
|
||||||
|
// The bits surviving the mask above don't derive from uninitialized slots,
|
||||||
|
// but clang 21+ on aarch64 lowers inBounds through flags+csel, which
|
||||||
|
// memcheck models imprecisely, tainting bits the mask provably clears.
|
||||||
|
// https://git.weaselab.dev/weaselab/conflict-set/issues/39
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(&mask, sizeof(mask));
|
||||||
|
#endif
|
||||||
if (!mask) {
|
if (!mask) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2257,7 +2272,13 @@ bool checkMaxBetweenExclusiveImpl(Node3 *n, int begin, int end,
|
|||||||
compared |= (self->childMaxVersion[i] > readVersion) << i;
|
compared |= (self->childMaxVersion[i] > readVersion) << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !(compared & mask) && firstRangeOk;
|
uint32_t compared_masked = compared & mask;
|
||||||
|
#ifdef __aarch64__
|
||||||
|
// Same imprecise csel modeling as above.
|
||||||
|
// https://git.weaselab.dev/weaselab/conflict-set/issues/39
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(&compared_masked, sizeof(compared_masked));
|
||||||
|
#endif
|
||||||
|
return !compared_masked && firstRangeOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool kAVX512>
|
template <bool kAVX512>
|
||||||
@@ -3048,7 +3069,12 @@ Node *firstGeqPhysical(Node *n, const TrivialSpan key) {
|
|||||||
#define MUSTTAIL
|
#define MUSTTAIL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __has_attribute(preserve_none)
|
// ASan + preserve_none miscompiles the continuation chains on aarch64 with
|
||||||
|
// every clang tested (20, 21, trunk 22). The chains work with the default
|
||||||
|
// calling convention, so use that under ASan on aarch64.
|
||||||
|
// https://git.weaselab.dev/weaselab/conflict-set/issues/38
|
||||||
|
#if __has_attribute(preserve_none) && \
|
||||||
|
!(defined(__aarch64__) && defined(__SANITIZE_ADDRESS__))
|
||||||
#define PRESERVE_NONE __attribute__((preserve_none))
|
#define PRESERVE_NONE __attribute__((preserve_none))
|
||||||
#else
|
#else
|
||||||
#define PRESERVE_NONE
|
#define PRESERVE_NONE
|
||||||
|
|||||||
Reference in New Issue
Block a user