-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[compiler-rt][nsan] Add lit config for tests #100286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
alexander-shaposhnikov
merged 1 commit into
llvm:main
from
alexander-shaposhnikov:add_nsan_tests
Jul 24, 2024
Merged
[compiler-rt][nsan] Add lit config for tests #100286
alexander-shaposhnikov
merged 1 commit into
llvm:main
from
alexander-shaposhnikov:add_nsan_tests
Jul 24, 2024
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Alexander Shaposhnikov (alexander-shaposhnikov) ChangesAdd a lit config for tests (and first tests as well). Test plan: ninja check-nsan Full diff: https://github.com/llvm/llvm-project/pull/100286.diff 6 Files Affected:
diff --git a/compiler-rt/test/nsan/CMakeLists.txt b/compiler-rt/test/nsan/CMakeLists.txt
index d702e122a85ef..78a1f4baee116 100644
--- a/compiler-rt/test/nsan/CMakeLists.txt
+++ b/compiler-rt/test/nsan/CMakeLists.txt
@@ -3,6 +3,22 @@ set(NSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(NSAN_TESTSUITES)
set(NSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} nsan)
+macro(add_nsan_testsuite arch)
+ set(NSAN_TEST_TARGET_ARCH ${arch})
+ get_test_cc_for_arch(${arch} NSAN_TEST_TARGET_CC NSAN_TEST_TARGET_CFLAGS)
+
+ string(TOUPPER ${arch} CONFIG_NAME)
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py)
+ list(APPEND NSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
+endmacro()
+
+set(NSAN_TEST_ARCH ${NSAN_SUPPORTED_ARCH})
+foreach(arch ${NSAN_TEST_ARCH})
+ add_nsan_testsuite(${arch})
+endforeach()
+
if(COMPILER_RT_LIBCXX_PATH AND COMPILER_RT_LIBCXXABI_PATH)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in
diff --git a/compiler-rt/test/nsan/alloca.cpp b/compiler-rt/test/nsan/alloca.cpp
new file mode 100644
index 0000000000000..33f7c1364e664
--- /dev/null
+++ b/compiler-rt/test/nsan/alloca.cpp
@@ -0,0 +1,26 @@
+// RUN: %clangxx_nsan -O0 -g %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx_nsan -O3 -g %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#include <cstddef>
+
+#include "helpers.h"
+
+extern "C" void __nsan_dump_shadow_mem(const char *addr, size_t size_bytes,
+ size_t bytes_per_line, size_t reserved);
+
+int main() {
+ int size = 3 * sizeof(float);
+ // Make sure we allocate dynamically: https://godbolt.org/z/T3h998.
+ DoNotOptimize(size);
+ float *array = reinterpret_cast<float *>(__builtin_alloca(size));
+ DoNotOptimize(array);
+ array[0] = 1.0;
+ array[1] = 2.0;
+ // The third float is uninitialized.
+ __nsan_dump_shadow_mem((const char *)array, 3 * sizeof(float), 16, 0);
+ // CHECK: {{.*}} f0 f1 f2 f3 f0 f1 f2 f3 __ __ __ __ (1.00000000000000000000) (2.00000000000000000000)
+ return 0;
+}
diff --git a/compiler-rt/test/nsan/helpers.h b/compiler-rt/test/nsan/helpers.h
new file mode 100644
index 0000000000000..f0a95a23a33be
--- /dev/null
+++ b/compiler-rt/test/nsan/helpers.h
@@ -0,0 +1,15 @@
+// Prevents the compiler from optimizing everything away.
+template <class T> void DoNotOptimize(const T &var) {
+ asm volatile("" : "+m"(const_cast<T &>(var)));
+}
+
+// Writes a single double with inconsistent shadow to v.
+void CreateInconsistency(double *data) {
+ double num = 0.6;
+ double denom = 0.2;
+ // Prevent the compiler from constant-folding this.
+ DoNotOptimize(num);
+ DoNotOptimize(denom);
+ // Both values are very close to 0.0, but shadow value is closer.
+ *data = 1.0 / (num / denom - 3.0);
+}
diff --git a/compiler-rt/test/nsan/lit.cfg.py b/compiler-rt/test/nsan/lit.cfg.py
index 8b137891791fe..a625412559e75 100644
--- a/compiler-rt/test/nsan/lit.cfg.py
+++ b/compiler-rt/test/nsan/lit.cfg.py
@@ -1 +1,29 @@
+config.name = 'NSan' + config.name_suffix
+# Setup source root.
+config.test_source_root = os.path.dirname(__file__)
+
+# Test suffixes.
+config.suffixes = ['.c', '.cpp', '.test']
+
+# C & CXX flags.
+c_flags = ([config.target_cflags])
+
+# CXX flags
+cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++17"])
+
+nsan_flags = ["-fsanitize=numerical", "-g",
+ "-mno-omit-leaf-frame-pointer",
+ "-fno-omit-frame-pointer"]
+
+def build_invocation(compile_flags):
+ return " " + " ".join([config.clang] + compile_flags) + " "
+
+# Add substitutions.
+config.substitutions.append(("%clang ", build_invocation(c_flags)))
+config.substitutions.append(("%clang_nsan ", build_invocation(c_flags + nsan_flags)))
+config.substitutions.append(("%clangxx_nsan ", build_invocation(cxx_flags + nsan_flags)))
+
+# NSan tests are currently supported on Linux only.
+if config.host_os not in ['Linux']:
+ config.unsupported = True
diff --git a/compiler-rt/test/nsan/lit.site.cfg.py.in b/compiler-rt/test/nsan/lit.site.cfg.py.in
index 69fd057e75748..496a9d5277a06 100644
--- a/compiler-rt/test/nsan/lit.site.cfg.py.in
+++ b/compiler-rt/test/nsan/lit.site.cfg.py.in
@@ -4,8 +4,6 @@
config.name_suffix = "-@CONFIG_NAME@"
config.target_cflags = "@NSAN_TEST_TARGET_CFLAGS@"
config.target_arch = "@NSAN_TEST_TARGET_ARCH@"
-config.use_lld = @NSAN_TEST_USE_LLD@
-config.use_thinlto = @NSAN_TEST_USE_THINLTO@
# Load common config for all compiler-rt lit tests.
lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
diff --git a/compiler-rt/test/nsan/sum.cpp b/compiler-rt/test/nsan/sum.cpp
new file mode 100644
index 0000000000000..31bd62e73966b
--- /dev/null
+++ b/compiler-rt/test/nsan/sum.cpp
@@ -0,0 +1,70 @@
+// RUN: %clangxx_nsan -O0 -mllvm -nsan-shadow-type-mapping=dqq -g -DSUM=NaiveSum -DFLT=float %s -o %t
+// RUN: NSAN_OPTIONS=halt_on_error=1,log2_max_relative_error=19 not %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx_nsan -O3 -mllvm -nsan-shadow-type-mapping=dqq -g -DSUM=NaiveSum -DFLT=float %s -o %t
+// RUN: NSAN_OPTIONS=halt_on_error=1,log2_max_relative_error=19 not %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx_nsan -O0 -mllvm -nsan-shadow-type-mapping=dqq -g -DSUM=KahanSum -DFLT=float %s -o %t
+// RUN: NSAN_OPTIONS=halt_on_error=1,log2_max_relative_error=19 %run %t
+
+// RUN: %clangxx_nsan -O3 -mllvm -nsan-shadow-type-mapping=dqq -g -DSUM=KahanSum -DFLT=float %s -o %t
+// RUN: NSAN_OPTIONS=halt_on_error=1,log2_max_relative_error=19 %run %t
+
+#include <chrono>
+#include <iostream>
+#include <random>
+#include <vector>
+
+// A naive, unstable summation.
+template <typename T>
+__attribute__((noinline)) // To check call stack reporting.
+T NaiveSum(const std::vector<T>& values) {
+ T sum = 0;
+ for (T v : values) {
+ sum += v;
+ }
+ return sum;
+ // CHECK: WARNING: NumericalStabilitySanitizer: inconsistent shadow results while checking return
+ // CHECK: float{{ *}}precision (native):
+ // CHECK: double{{ *}}precision (shadow):
+ // CHECK: {{#0 .*in .* NaiveSum}}
+}
+
+// Kahan's summation is a numerically stable sum.
+// https://en.wikipedia.org/wiki/Kahan_summation_algorithm
+template <typename T>
+__attribute__((noinline)) T KahanSum(const std::vector<T> &values) {
+ T sum = 0;
+ T c = 0;
+ for (T v : values) {
+ T y = v - c;
+ T t = sum + y;
+ c = (t - sum) - y;
+ sum = t;
+ }
+ return sum;
+}
+
+int main() {
+ std::vector<FLT> values;
+ constexpr int kNumValues = 1000000;
+ values.reserve(kNumValues);
+ // Using a seed to avoid flakiness.
+ constexpr uint32_t kSeed = 0x123456;
+ std::mt19937 gen(kSeed);
+ std::uniform_real_distribution<FLT> dis(0.0f, 1000.0f);
+ for (int i = 0; i < kNumValues; ++i) {
+ values.push_back(dis(gen));
+ }
+
+ const auto t1 = std::chrono::high_resolution_clock::now();
+ const auto sum = SUM(values);
+ const auto t2 = std::chrono::high_resolution_clock::now();
+ printf("sum: %.8f\n", sum);
+ std::cout << "runtime: "
+ << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1)
+ .count() /
+ 1000.0
+ << "ms\n";
+ return 0;
+}
|
7676bff
to
2e3f5e0
Compare
✅ With the latest revision this PR passed the Python code formatter. |
2e3f5e0
to
c36b2af
Compare
vitalybuka
approved these changes
Jul 24, 2024
MaskRay
approved these changes
Jul 24, 2024
chestnykh
approved these changes
Jul 24, 2024
yuxuanchen1997
pushed a commit
that referenced
this pull request
Jul 25, 2024
Summary: Initial setup for tests. Test Plan: ninja check-nsan Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250720
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add a lit config for tests (and first tests as well).
Test plan: ninja check-nsan