[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-26 Thread Alexander Shaposhnikov via cfe-commits

alexander-shaposhnikov wrote:

@vitalybuka , @arsenm - thanks a lot, yeah, sure, I can split the patch.
P.S. will update/address comments soon.

https://github.com/llvm/llvm-project/pull/85916
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-26 Thread Vitaly Buka via cfe-commits

vitalybuka wrote:

clang changes LGTM, but they are missing testst

https://github.com/llvm/llvm-project/pull/85916
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-26 Thread Vitaly Buka via cfe-commits

vitalybuka wrote:

Can we split the patch into smaller pieces?
e.g. clang, transform, runtime ?

This one has transform, comments, so we can keep it for transform.


https://github.com/llvm/llvm-project/pull/85916
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-21 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,2261 @@
+//===-- NumericalStabilitySanitizer.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file is a part of NumericalStabilitySanitizer.
+//
+//===--===//
+
+#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"
+
+#include 
+#include 
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/EscapeEnumerator.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "nsan"
+
+STATISTIC(NumInstrumentedFTLoads,
+  "Number of instrumented floating-point loads");
+
+STATISTIC(NumInstrumentedFTCalls,
+  "Number of instrumented floating-point calls");
+STATISTIC(NumInstrumentedFTRets,
+  "Number of instrumented floating-point returns");
+STATISTIC(NumInstrumentedFTStores,
+  "Number of instrumented floating-point stores");
+STATISTIC(NumInstrumentedNonFTStores,
+  "Number of instrumented non floating-point stores");
+STATISTIC(
+NumInstrumentedNonFTMemcpyStores,
+"Number of instrumented non floating-point stores with memcpy semantics");
+STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");
+
+// Using smaller shadow types types can help improve speed. For example, `dlq`
+// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared 
to
+// `dqq`.
+static cl::opt ClShadowMapping(
+"nsan-shadow-type-mapping", cl::init("dqq"),
+cl::desc("One shadow type id for each of `float`, `double`, `long double`. 
"
+ "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
+ "ppc_fp128 (extended double) respectively. The default is to "
+ "shadow `float` as `double`, and `double` and `x86_fp80` as "
+ "`fp128`"),
+cl::Hidden);
+
+static cl::opt
+ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
+ cl::desc("Instrument floating-point comparisons"),
+ cl::Hidden);
+
+static cl::opt ClCheckFunctionsFilter(
+"check-functions-filter",
+cl::desc("Only emit checks for arguments of functions "
+ "whose names match the given regular expression"),
+cl::value_desc("regex"));
+
+static cl::opt ClTruncateFCmpEq(
+"nsan-truncate-fcmp-eq", cl::init(true),
+cl::desc(
+"This flag controls the behaviour of fcmp equality comparisons:"
+"For equality comparisons such as `x == 0.0f`, we can perform the "
+"shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app 
"
+" domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
+"catch the case when `x_shadow` is accurate enough (and therefore "
+"close enough to zero) so that `trunc(x_shadow)` is zero even though "
+"both `x` and `x_shadow` are not. "),
+cl::Hidden);
+
+// When there is external, uninstrumented code writing to memory, the shadow
+// memory can get out of sync with the application memory. Enabling this flag
+// emits consistency checks for loads to catch this situation.
+// When everything is instrumented, this is not strictly necessary because any
+// load should have a corresponding store, but can help debug cases when the
+// framework did a bad job at tracking shadow memory modifications by failing 
on
+// load rather than store.
+// FIXME: provide a way to resume computations from the FT value when the load
+// is inconsistent. This ensures that further computations are not polluted.
+static cl::opt ClCheckLoads("nsan-check-loads", cl::init(false),
+  cl::desc("Check floating-point load"),
+  cl::Hidden);
+
+static 

[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-20 Thread Alexander Shaposhnikov via cfe-commits

https://github.com/alexander-shaposhnikov edited 
https://github.com/llvm/llvm-project/pull/85916
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-20 Thread via cfe-commits

github-actions[bot] wrote:




:warning: Python code formatter, darker found issues in your code. :warning:



You can test this locally with the following command:


``bash
darker --check --diff -r 
9fd1c4121f7c797ff7222161cb40cd68ecf0fbc8...f932900890ba96ae01f8c4d762aca5023d0b7fce
 compiler-rt/test/nsan/lit.cfg.py
``





View the diff from darker here.


``diff
--- lit.cfg.py  2024-03-20 09:59:30.00 +
+++ lit.cfg.py  2024-03-20 10:39:52.135628 +
@@ -1,45 +1,53 @@
 # -*- Python -*-
 
 import os
 
 # Setup config name.
-config.name = 'NSan' + config.name_suffix
+config.name = "NSan" + config.name_suffix
 
 # Setup source root.
 config.test_source_root = os.path.dirname(__file__)
 
 # Test suffixes.
-config.suffixes = ['.c', '.cc', '.test']
+config.suffixes = [".c", ".cc", ".test"]
 
 # C & CXX flags.
-c_flags = ([config.target_cflags])
+c_flags = [config.target_cflags]
 
 # Android doesn't want -lrt.
 if not config.android:
-  c_flags += ["-lrt"]
+c_flags += ["-lrt"]
 
-cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++17"])
+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"]
+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) + " "
+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)))
+config.substitutions.append(
+("%clangxx_nsan ", build_invocation(cxx_flags + nsan_flags))
+)
 
 # Platform-specific default NSAN for lit tests.
-default_nsan_options = ''
+default_nsan_options = ""
 
-config.environment['NSAN_OPTIONS'] = default_nsan_options
-default_nsan_options += ':'
-config.substitutions.append(('%env_nsan_options=',
- 'env NSAN_OPTIONS=' + default_nsan_options))
+config.environment["NSAN_OPTIONS"] = default_nsan_options
+default_nsan_options += ":"
+config.substitutions.append(
+("%env_nsan_options=", "env NSAN_OPTIONS=" + default_nsan_options)
+)
 
 # NSan tests are currently supported on Linux only.
-if config.host_os not in ['Linux']:
-   config.unsupported = True
+if config.host_os not in ["Linux"]:
+config.unsupported = True

``




https://github.com/llvm/llvm-project/pull/85916
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-20 Thread Alexander Shaposhnikov via cfe-commits

https://github.com/alexander-shaposhnikov edited 
https://github.com/llvm/llvm-project/pull/85916
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [compiler-rt] [llvm] Add numerical sanitizer (PR #85916)

2024-03-20 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-clang-codegen

Author: Alexander Shaposhnikov (alexander-shaposhnikov)


Changes

This PR introduces the numerical sanitizer originally proposed by Clement 
Courbet on https://reviews.llvm.org/D97854
(https://arxiv.org/abs/2102.12782).

The main additions include:
- Migration to LLVM opaque pointers
- Migration to various updated APIs
- Extended coverage for LLVM instructions/intrinsics, that enabled us to have a 
green run of tests again



---

Patch is 344.35 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/85916.diff


77 Files Affected:

- (modified) clang/include/clang/Basic/Features.def (+1) 
- (modified) clang/include/clang/Basic/Sanitizers.def (+3) 
- (modified) clang/include/clang/Driver/SanitizerArgs.h (+3) 
- (modified) clang/lib/CodeGen/BackendUtil.cpp (+7) 
- (modified) clang/lib/CodeGen/CGDeclCXX.cpp (+4) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+2) 
- (modified) clang/lib/Driver/SanitizerArgs.cpp (+5-2) 
- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+3) 
- (modified) clang/lib/Driver/ToolChains/Linux.cpp (+4) 
- (modified) clang/runtime/CMakeLists.txt (+2-1) 
- (modified) compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake (+1) 
- (modified) compiler-rt/cmake/config-ix.cmake (+12-1) 
- (added) compiler-rt/include/sanitizer/nsan_interface.h (+75) 
- (added) compiler-rt/lib/nsan/CMakeLists.txt (+61) 
- (added) compiler-rt/lib/nsan/nsan.cc (+828) 
- (added) compiler-rt/lib/nsan/nsan.h (+224) 
- (added) compiler-rt/lib/nsan/nsan.syms.extra (+2) 
- (added) compiler-rt/lib/nsan/nsan_flags.cc (+78) 
- (added) compiler-rt/lib/nsan/nsan_flags.h (+35) 
- (added) compiler-rt/lib/nsan/nsan_flags.inc (+49) 
- (added) compiler-rt/lib/nsan/nsan_interceptors.cc (+363) 
- (added) compiler-rt/lib/nsan/nsan_platform.h (+135) 
- (added) compiler-rt/lib/nsan/nsan_stats.cc (+158) 
- (added) compiler-rt/lib/nsan/nsan_stats.h (+92) 
- (added) compiler-rt/lib/nsan/nsan_suppressions.cc (+76) 
- (added) compiler-rt/lib/nsan/nsan_suppressions.h (+31) 
- (added) compiler-rt/lib/nsan/tests/CMakeLists.txt (+54) 
- (added) compiler-rt/lib/nsan/tests/NSanUnitTest.cpp (+67) 
- (added) compiler-rt/lib/nsan/tests/nsan_unit_test_main.cpp (+18) 
- (added) compiler-rt/test/nsan/CMakeLists.txt (+33) 
- (added) compiler-rt/test/nsan/alloca.cc (+24) 
- (added) compiler-rt/test/nsan/cadna_ex1.cc (+21) 
- (added) compiler-rt/test/nsan/cadna_ex2.cc (+52) 
- (added) compiler-rt/test/nsan/cadna_ex3.cc (+48) 
- (added) compiler-rt/test/nsan/cadna_ex4.cc (+37) 
- (added) compiler-rt/test/nsan/cadna_ex5.cc (+97) 
- (added) compiler-rt/test/nsan/cadna_ex6.cc (+67) 
- (added) compiler-rt/test/nsan/cadna_ex7.cc (+110) 
- (added) compiler-rt/test/nsan/cancellation_fn_ptr.cc (+66) 
- (added) compiler-rt/test/nsan/cancellation_libm.cc (+51) 
- (added) compiler-rt/test/nsan/cancellation_ok.cc (+53) 
- (added) compiler-rt/test/nsan/compare.cc (+28) 
- (added) compiler-rt/test/nsan/compute_pi.cc (+45) 
- (added) compiler-rt/test/nsan/helpers.h (+15) 
- (added) compiler-rt/test/nsan/infinity.cc (+24) 
- (added) compiler-rt/test/nsan/intercept_libc_str.cc (+149) 
- (added) compiler-rt/test/nsan/interface_dump_shadow_mem.cc (+62) 
- (added) compiler-rt/test/nsan/jmmuller.cc (+35) 
- (added) compiler-rt/test/nsan/lit.cfg.py (+45) 
- (added) compiler-rt/test/nsan/lit.site.cfg.py.in (+11) 
- (added) compiler-rt/test/nsan/memcpy.cc (+83) 
- (added) compiler-rt/test/nsan/memset_nonzero.cc (+23) 
- (added) compiler-rt/test/nsan/memset_zero.cc (+24) 
- (added) compiler-rt/test/nsan/rump_royal_pain.cc (+37) 
- (added) compiler-rt/test/nsan/simd.cc (+25) 
- (added) compiler-rt/test/nsan/stable_sort.cc (+52) 
- (added) compiler-rt/test/nsan/stack.cc (+20) 
- (added) compiler-rt/test/nsan/sums.cc (+82) 
- (added) compiler-rt/test/nsan/swap.cc (+46) 
- (added) compiler-rt/test/nsan/type_punning.cc (+26) 
- (added) compiler-rt/test/nsan/uninstrumented_write.cc (+22) 
- (added) compiler-rt/test/nsan/vector_push_back.cc (+17) 
- (added) compiler-rt/test/nsan/verificarlo_case4.cc (+29) 
- (modified) llvm/include/llvm/Bitcode/LLVMBitCodes.h (+1) 
- (modified) llvm/include/llvm/IR/Attributes.td (+4) 
- (added) 
llvm/include/llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h 
(+40) 
- (modified) llvm/lib/Bitcode/Reader/BitcodeReader.cpp (+2) 
- (modified) llvm/lib/Bitcode/Writer/BitcodeWriter.cpp (+2) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1) 
- (modified) llvm/lib/Passes/PassRegistry.def (+2) 
- (modified) llvm/lib/Transforms/Instrumentation/CMakeLists.txt (+1) 
- (added) llvm/lib/Transforms/Instrumentation/NumericalStabilitySanitizer.cpp 
(+2261) 
- (modified) llvm/lib/Transforms/Utils/CodeExtractor.cpp (+1) 
- (added) llvm/test/Instrumentation/NumericalStabilitySanitizer/basic.ll (+930) 
- (added) llvm/test/Instrumentation/NumericalStabilitySanitizer/cfg.ll (+113) 
- (added)