[llvm] [lldb] [compiler-rt] [libcxx] [clang] [mlir] [lld] [clang-tools-extra] [hwasan] Add `__hwasan_get_tag_from_pointer` (PR #75267)

2023-12-13 Thread Thurston Dang via cfe-commits


@@ -0,0 +1,24 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t && %run %t
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int main() {
+  auto p = std::make_unique();
+  std::set ptrs;
+  for (unsigned i = 0;; ++i) {
+void *ptr = __hwasan_tag_pointer(p.get(), i);
+if (!ptrs.insert(ptr).second)
+  break;
+fprintf(stderr, "%p, %u, %u\n", ptr, i, 
__hwasan_get_tag_from_pointer(ptr));
+assert(__hwasan_get_tag_from_pointer(ptr) == i);
+  }
+#ifdef __x86_64__
+  assert(ptrs.size() == 8);

thurstond wrote:

Is this assuming aliasing mode with 3-bit tags? If so, can the assumption be 
added to a `// REQUIRES` or similar?

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


[libcxx] [lldb] [mlir] [clang] [compiler-rt] [lld] [llvm] [clang-tools-extra] [hwasan] Add `__hwasan_get_tag_from_pointer` (PR #75267)

2023-12-13 Thread Thurston Dang via cfe-commits

https://github.com/thurstond approved this pull request.


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


[lld] [llvm] [clang-tools-extra] [lldb] [mlir] [clang] [libcxx] [compiler-rt] [hwasan] Add `__hwasan_get_tag_from_pointer` (PR #75267)

2023-12-13 Thread Thurston Dang via cfe-commits

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


[libc] [clang-tools-extra] [flang] [clang] [libcxx] [mlir] [llvm] [compiler-rt] [AsmWriter] Ensure getMnemonic doesn't return invalid pointers (PR #75783)

2023-12-19 Thread Thurston Dang via cfe-commits

https://github.com/thurstond approved this pull request.


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


[compiler-rt] [clang] [hwasan] Separate sections in report (PR #76130)

2023-12-21 Thread Thurston Dang via cfe-commits

https://github.com/thurstond approved this pull request.


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


[clang] [Driver, sanitizer] Remove RequiresPIE and msan's RequiresPIE setting (PR #77689)

2024-01-10 Thread Thurston Dang via cfe-commits

https://github.com/thurstond approved this pull request.


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


[clang] [clang] move -Wcast-function-type under -Wextra (PR #77178)

2024-03-21 Thread Thurston Dang via cfe-commits

thurstond wrote:

> > I believe this patch is causing some issues on two PPC bots. Would you be 
> > able to help take a look? 
> > https://lab.llvm.org/buildbot/#/builders/57/builds/33601/steps/5/logs/stdio 
> > https://lab.llvm.org/buildbot/#/builders/36/builds/43759/steps/12/logs/stdio
> 
> I guess adding this flag (-Wno-cast-function-type-strict) will make the error 
> go away. But it is caused by the conversion of the second argument "void*" to 
> "siginfo_t _" when casting from "SignalHandlerType" i.e. "void 
> (___sanitizer::SignalHandlerType)(int, void *, void *);" to "void 
> (*sa_sigaction) (int, siginfo_t *, void *);". If you are sure that this 
> conversion is valid, I guess we can add this flag. Might be similar for 
> others.

The reason for the weird cast: SignalHandlerType has 'void*' instead of 
'siginfo_t*' because it is typedef'ed in sanitizer_common/sanitizer_common.h, 
which does not have access to the header (signal.h) that defines siginfo_t; we 
therefore cannot fix SignalHandlerType.

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


[llvm] [clang] [clang-tools-extra] [compiler-rt] Re-exec TSan with no ASLR if memory layout is incompatible on Linux (PR #78351)

2024-01-18 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/78351

>From 74d320657671ee64650d96cbc33fef7d414c0ec1 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 16 Jan 2024 21:06:01 +
Subject: [PATCH 1/6] Re-exec TSan with no ASLR if memory layout is
 incompatible

TSan's shadow mappings only support 30-bits of ASLR entropy on x86, and
it is not practical to support the maximum of 32-bits (due to pointer
compression and the overhead of shadow mappings). Instead, this patch
changes TSan to re-exec without ASLR if it encounters an incompatible
memory layout, as suggested by Dmitry in 
https://github.com/google/sanitizers/issues/1716.
If ASLR is already disabled, it will abort.

This patch involves a bit of refactoring, because the old code is:
InitializePlatformEarly()
InitializeAllocator()
InitializePlatform(): CheckAndProtect()
but it may already segfault during InitializeAllocator() if the memory
layout is incompatible, before we get a chance to check in
CheckAndProtect.

This patch adds CheckAndProtect during InitializePlatformEarly(), before
the allocator is initialized. Naturally, it is necessary to ensure that
CheckAndProtect does *not* allow the heap regions to be occupied there,
hence we generalize CheckAndProtect to optionally check the heap
regions. We keep the original behavior of CheckAndProtect() in 
InitializePlatform()
as a last line of defense.

We need to careful not to prematurely abort if ASLR is disabled but TSan was 
going to re-exec
for other reasons (e.g., unlimited stack size); we implement this by
moving all the re-exec logic into ReExecIfNeeded().
---
 compiler-rt/lib/tsan/rtl/tsan_platform.h  |   2 +-
 .../lib/tsan/rtl/tsan_platform_linux.cpp  | 140 --
 .../lib/tsan/rtl/tsan_platform_posix.cpp  |  43 +-
 3 files changed, 136 insertions(+), 49 deletions(-)

diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h 
b/compiler-rt/lib/tsan/rtl/tsan_platform.h
index 84ff4bfade09ac..377f8aeb8d66e0 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h
@@ -1024,7 +1024,7 @@ inline uptr RestoreAddr(uptr addr) {
 
 void InitializePlatform();
 void InitializePlatformEarly();
-void CheckAndProtect();
+bool CheckAndProtect(bool protect, bool ignore_heap, bool print_warnings);
 void InitializeShadowMemoryPlatform();
 void WriteMemoryProfile(char *buf, uptr buf_size, u64 uptime_ns);
 int ExtractResolvFDs(void *state, int *fds, int nfd);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp 
b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
index b45adea45b27ad..bc1be49dd41513 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
@@ -214,6 +214,88 @@ void InitializeShadowMemoryPlatform() {
 
 #endif  // #if !SANITIZER_GO
 
+#  if !SANITIZER_GO
+static void ReExecIfNeeded() {
+  // Go maps shadow memory lazily and works fine with limited address space.
+  // Unlimited stack is not a problem as well, because the executable
+  // is not compiled with -pie.
+  {
+bool reexec = false;
+// TSan doesn't play well with unlimited stack size (as stack
+// overlaps with shadow memory). If we detect unlimited stack size,
+// we re-exec the program with limited stack size as a best effort.
+if (StackSizeIsUnlimited()) {
+  const uptr kMaxStackSize = 32 * 1024 * 1024;
+  VReport(1,
+  "Program is run with unlimited stack size, which wouldn't "
+  "work with ThreadSanitizer.\n"
+  "Re-execing with stack size limited to %zd bytes.\n",
+  kMaxStackSize);
+  SetStackSizeLimitInBytes(kMaxStackSize);
+  reexec = true;
+}
+
+if (!AddressSpaceIsUnlimited()) {
+  Report(
+  "WARNING: Program is run with limited virtual address space,"
+  " which wouldn't work with ThreadSanitizer.\n");
+  Report("Re-execing with unlimited virtual address space.\n");
+  SetAddressSpaceUnlimited();
+  reexec = true;
+}
+
+// ASLR personality check.
+int old_personality = personality(0x);
+bool aslr_on =
+(old_personality != -1) && ((old_personality & ADDR_NO_RANDOMIZE) == 
0);
+
+#if SANITIZER_ANDROID && (defined(__aarch64__) || defined(__x86_64__))
+// After patch "arm64: mm: support ARCH_MMAP_RND_BITS." is introduced in
+// linux kernel, the random gap between stack and mapped area is increased
+// from 128M to 36G on 39-bit aarch64. As it is almost impossible to cover
+// this big range, we should disable randomized virtual space on aarch64.
+if (aslr_on) {
+  VReport(1,
+  "WARNING: Program is run with randomized virtual address "
+  "space, which wouldn't work with ThreadSanitizer on Android.\n"
+  "Re-execing with fixed virtual address space.\n");
+  CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
+  

[clang] fc06cce - Revert "Respect integer overflow handling in abs builtin"

2023-08-18 Thread Thurston Dang via cfe-commits

Author: Thurston Dang
Date: 2023-08-18T19:59:34Z
New Revision: fc06cce30d2b7d49778b9a27420ca239e0c49856

URL: 
https://github.com/llvm/llvm-project/commit/fc06cce30d2b7d49778b9a27420ca239e0c49856
DIFF: 
https://github.com/llvm/llvm-project/commit/fc06cce30d2b7d49778b9a27420ca239e0c49856.diff

LOG: Revert "Respect integer overflow handling in abs builtin"

This reverts commit 1783185790de29b24d3850d33d9a9d586e6bbd39,
which broke the buildbots, starting with when it was first built in 
https://lab.llvm.org/buildbot/#/builders/85/builds/18390

(N.B. I think the patch is uncovering real bugs; the revert
is simply to keep the tree green and the buildbots useful, because I'm not 
confident how to
fix-forward all the found bugs.)

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/CodeGen/CGBuiltin.cpp

Removed: 
clang/test/CodeGen/abs-overflow.c
clang/test/ubsan/TestCases/Misc/abs.cpp



diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e34fc2e10b2df0..054c06ffa0f5c9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -154,10 +154,6 @@ Bug Fixes in This Version
 - Fix a hang on valid C code passing a function type as an argument to
   ``typeof`` to form a function declaration.
   (`#64713 _`)
-- Clang now respects ``-fwrapv`` and ``-ftrapv`` for ``__builtin_abs`` and
-  ``abs`` builtins.
-  (`#45129 `_,
-  `#45794 `_)
 
 Bug Fixes to Compiler Builtins
 ^^
@@ -293,9 +289,6 @@ Static Analyzer
 
 Sanitizers
 --
-- ``-fsanitize=signed-integer-overflow`` now instruments ``__builtin_abs`` and
-  ``abs`` builtins.
-
 
 Python Binding Changes
 --

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 4ded5a10d529ae..5a183d3553279e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -1768,49 +1768,6 @@ Value *CodeGenFunction::EmitCheckedArgForBuiltin(const 
Expr *E,
   return ArgValue;
 }
 
-static Value *EmitAbs(CodeGenFunction &CGF, Value *ArgValue, bool HasNSW) {
-  // X < 0 ? -X : X
-  // TODO: Use phi-node (for better SimplifyCFGPass)
-  Value *NegOp = CGF.Builder.CreateNeg(ArgValue, "neg", false, HasNSW);
-  Constant *Zero = llvm::Constant::getNullValue(ArgValue->getType());
-  Value *CmpResult = CGF.Builder.CreateICmpSLT(ArgValue, Zero, "abscond");
-  return CGF.Builder.CreateSelect(CmpResult, NegOp, ArgValue, "abs");
-}
-
-static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
- bool SanitizeOverflow) {
-  Value *ArgValue = CGF.EmitScalarExpr(E->getArg(0));
-
-  // Try to eliminate overflow check.
-  if (const auto *VCI = dyn_cast(ArgValue)) {
-if (!VCI->isMinSignedValue()) {
-  return EmitAbs(CGF, ArgValue, true);
-}
-  }
-
-  CodeGenFunction::SanitizerScope SanScope(&CGF);
-
-  Constant *Zero = Constant::getNullValue(ArgValue->getType());
-  Value *ResultAndOverflow = CGF.Builder.CreateBinaryIntrinsic(
-  Intrinsic::ssub_with_overflow, Zero, ArgValue);
-  Value *Result = CGF.Builder.CreateExtractValue(ResultAndOverflow, 0);
-  Value *NotOverflow = CGF.Builder.CreateNot(
-  CGF.Builder.CreateExtractValue(ResultAndOverflow, 1));
-
-  // TODO: support -ftrapv-handler.
-  if (SanitizeOverflow) {
-CGF.EmitCheck({{NotOverflow, SanitizerKind::SignedIntegerOverflow}},
-  SanitizerHandler::NegateOverflow,
-  {CGF.EmitCheckSourceLocation(E->getArg(0)->getExprLoc()),
-   CGF.EmitCheckTypeDescriptor(E->getType())},
-  {ArgValue});
-  } else
-CGF.EmitTrapCheck(NotOverflow, SanitizerHandler::SubOverflow);
-
-  Value *CmpResult = CGF.Builder.CreateICmpSLT(ArgValue, Zero, "abscond");
-  return CGF.Builder.CreateSelect(CmpResult, Result, ArgValue, "abs");
-}
-
 /// Get the argument type for arguments to os_log_helper.
 static CanQualType getOSLogArgType(ASTContext &C, int Size) {
   QualType UnsignedTy = C.getIntTypeForBitwidth(Size * 8, /*Signed=*/false);
@@ -2669,29 +2626,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const 
GlobalDecl GD, unsigned BuiltinID,
 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), {DstPtr, SrcPtr});
 return RValue::get(nullptr);
   }
-  case Builtin::BIabs:
-  case Builtin::BIlabs:
-  case Builtin::BIllabs:
   case Builtin::BI__builtin_abs:
   case Builtin::BI__builtin_labs:
   case Builtin::BI__builtin_llabs: {
-bool SanitizeOverflow = SanOpts.has(SanitizerKind::SignedIntegerOverflow);
-
-Value *Result;
-switch (getLangOpts().getSignedOverflowBehavior()) {
-case LangOptions::SOB_Defined:
-  Result = EmitAbs(*this, EmitScalarExpr(E->getArg(0)), false);
-  break;
-case LangOptions

[clang] [Interp] Mark the test unsupported with Asan (PR #102859)

2024-08-12 Thread Thurston Dang via cfe-commits

https://github.com/thurstond approved this pull request.


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


[clang] e398da2 - Revert "[Clang] Overflow Pattern Exclusions (#100272)"

2024-08-15 Thread Thurston Dang via cfe-commits

Author: Thurston Dang
Date: 2024-08-15T10:18:52-07:00
New Revision: e398da2b37fcc2696e1f5c661e5372844f4e1550

URL: 
https://github.com/llvm/llvm-project/commit/e398da2b37fcc2696e1f5c661e5372844f4e1550
DIFF: 
https://github.com/llvm/llvm-project/commit/e398da2b37fcc2696e1f5c661e5372844f4e1550.diff

LOG: Revert "[Clang] Overflow Pattern Exclusions (#100272)"

This reverts commit 9a666deecb9ff6ca3a6b12e6c2877e19b74b54da.

Reason: broke buildbots

e.g., fork-ubsan.test started failing at
https://lab.llvm.org/buildbot/#/builders/66/builds/2819/steps/9/logs/stdio

  Clang :: CodeGen/compound-assign-overflow.c
  Clang :: CodeGen/sanitize-atomic-int-overflow.c
started failing with https://lab.llvm.org/buildbot/#/builders/52/builds/1570

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/docs/UndefinedBehaviorSanitizer.rst
clang/include/clang/AST/Expr.h
clang/include/clang/AST/Stmt.h
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Driver/Options.td
clang/include/clang/Driver/SanitizerArgs.h
clang/lib/AST/Expr.cpp
clang/lib/CodeGen/CGExprScalar.cpp
clang/lib/Driver/SanitizerArgs.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp

Removed: 
clang/test/CodeGen/overflow-idiom-exclusion-fp.c



diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b6b7dd5705637a..4872dbb7a556ad 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -395,36 +395,6 @@ Moved checkers
 Sanitizers
 --
 
-- Added the ``-fsanitize-overflow-pattern-exclusion=`` flag which can be used
-  to disable specific overflow-dependent code patterns. The supported patterns
-  are: ``add-overflow-test``, ``negated-unsigned-const``, and
-  ``post-decr-while``. The sanitizer instrumentation can be toggled off for all
-  available patterns by specifying ``all``. Conversely, you can disable all
-  exclusions with ``none``.
-
-  .. code-block:: c++
-
- /// specified with 
``-fsanitize-overflow-pattern-exclusion=add-overflow-test``
- int common_overflow_check_pattern(unsigned base, unsigned offset) {
-   if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, 
and other re-orderings, won't be instrumented
- }
-
- /// specified with 
``-fsanitize-overflow-pattern-exclusion=negated-unsigned-const``
- void negation_overflow() {
-   unsigned long foo = -1UL; // No longer causes a negation overflow 
warning
-   unsigned long bar = -2UL; // and so on...
- }
-
- /// specified with 
``-fsanitize-overflow-pattern-exclusion=post-decr-while``
- void while_post_decrement() {
-   unsigned char count = 16;
-   while (count--) { /* ... */} // No longer causes 
unsigned-integer-overflow sanitizer to trip
- }
-
-  Many existing projects have a large amount of these code patterns present.
-  This new flag should allow those projects to enable integer sanitizers with
-  less noise.
-
 Python Binding Changes
 --
 - Fixed an issue that led to crashes when calling 
``Type.get_exception_specification_kind``.

diff  --git a/clang/docs/UndefinedBehaviorSanitizer.rst 
b/clang/docs/UndefinedBehaviorSanitizer.rst
index 9f3d980eefbea7..531d56e313826c 100644
--- a/clang/docs/UndefinedBehaviorSanitizer.rst
+++ b/clang/docs/UndefinedBehaviorSanitizer.rst
@@ -293,48 +293,6 @@ To silence reports from unsigned integer overflow, you can 
set
 ``-fsanitize-recover=unsigned-integer-overflow``, is particularly useful for
 providing fuzzing signal without blowing up logs.
 
-Disabling instrumentation for common overflow patterns
---
-
-There are certain overflow-dependent or overflow-prone code patterns which
-produce a lot of noise for integer overflow/truncation sanitizers. Negated
-unsigned constants, post-decrements in a while loop condition and simple
-overflow checks are accepted and pervasive code patterns. However, the signal
-received from sanitizers instrumenting these code patterns may be too noisy for
-some projects. To disable instrumentation for these common patterns one should
-use ``-fsanitize-overflow-pattern-exclusion=``.
-
-Currently, this option supports three overflow-dependent code idioms:
-
-``negated-unsigned-const``
-
-.. code-block:: c++
-
-/// -fsanitize-overflow-pattern-exclusion=negated-unsigned-const
-unsigned long foo = -1UL; // No longer causes a negation overflow warning
-unsigned long bar = -2UL; // and so on...
-
-``post-decr-while``
-
-.. code-block:: c++
-
-/// -fsanitize-overflow-pattern-exclusion=post-decr-while
-unsigned char count = 16;
-while (count--) { /* ... */ } // No longer causes 
unsigned-integer-overflow sanitizer to

[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)

2024-08-15 Thread Thurston Dang via cfe-commits

thurstond wrote:

One of the tests is failing:
```
compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c:31:15: error: 
CHECK-NOT: excluded string found in input
// CHECK-NOT: runtime error:
  ^
:1:110: note: found here
compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c:11:10: runtime error: 
implicit conversion from type '_BitInt(37)' of value 60129542145 (64-bit, 
signed) to type 'uint32_t' (aka 'unsigned int') changed the value to 1 (32-bit, 
unsigned)

 ^~
```

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


[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)

2024-08-15 Thread Thurston Dang via cfe-commits

thurstond wrote:

> > One of the tests is failing:
> > ```
> > $ LIT_FILTER=bit-int-pass ninja check-ubsan
> > 
> > compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c:31:15: error: 
> > CHECK-NOT: excluded string found in input
> > // CHECK-NOT: runtime error:
> >   ^
> > :1:110: note: found here
> > compiler-rt/test/ubsan/TestCases/Integer/bit-int-pass.c:11:10: runtime 
> > error: implicit conversion from type '_BitInt(37)' of value 60129542145 
> > (64-bit, signed) to type 'uint32_t' (aka 'unsigned int') changed the value 
> > to 1 (32-bit, unsigned)
> > 
> >  ^~
> > ```
> 
> On what target you observe the failure?

x86-64 Linux

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


[clang] [compiler-rt] [ubsan] Display correct runtime messages for negative _BitInt (PR #96240)

2024-08-15 Thread Thurston Dang via cfe-commits

thurstond wrote:

> Added #104494 to address failures with non-x86 targets as those platforms 
> might produce failures.

Thank you!

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


[clang] [clang][Interp] Call move function for certain primitive types (PR #104437)

2024-08-15 Thread Thurston Dang via cfe-commits

thurstond wrote:

This might have broken a buildbot: 
https://lab.llvm.org/buildbot/#/builders/52/builds/1578/steps/10/logs/stdio

```
RUN: at line 8: cat 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
 | 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm_build_asan/bin/clang-repl
 -Xcc -fno-rtti -Xcc -fno-sized-deallocation  -Xcc -O2 | 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm_build_asan/bin/FileCheck
 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ cat 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm_build_asan/bin/FileCheck
 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp
+ 
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm_build_asan/bin/clang-repl
 -Xcc -fno-rtti -Xcc -fno-sized-deallocation -Xcc -O2
JIT session error: In graph incr_module_24-jitted-objectbuffer, section 
.text.startup: relocation target "_ZTV1A" at address 0x779ab082e000 is out of 
range of Delta32 fixup at 0x739aaff0f013 ( @ 0x739aaff0f010 + 
0x3)
error: Failed to materialize symbols: { (main, { a2, 
__orc_init_func.incr_module_24, $.incr_module_24.__inits.0 }) }
error: Failed to materialize symbols: { (main, { __orc_init_func.incr_module_24 
}) }
/home/b/sanitizer-x86_64-linux-bootstrap-asan/build/llvm-project/clang/test/Interpreter/inline-virtual.cpp:26:11:
 error: CHECK: expected string not found in input
```

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


[clang] [docs][msan] List common cases reported by msan (PR #101105)

2024-07-29 Thread Thurston Dang via cfe-commits

https://github.com/thurstond approved this pull request.


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


[clang] [docs][msan] List common cases reported by msan (PR #101105)

2024-07-29 Thread Thurston Dang via cfe-commits


@@ -8,11 +8,18 @@ MemorySanitizer
 Introduction
 
 
-MemorySanitizer is a detector of uninitialized reads. It consists of a
+MemorySanitizer is a detector of uninitialized memory use. It consists of a
 compiler instrumentation module and a run-time library.
 
 Typical slowdown introduced by MemorySanitizer is **3x**.
 
+Here is a not comprehensive list cases when MemorySanitizer will report an 
error:
+
+* A code uses uninitialized value in a conditional branch.

thurstond wrote:

Nit: use consistent tense (e.g., be consistent about "uses" vs. "was used" in 
each bullet point)

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


[clang] [docs][msan] List common cases reported by msan (PR #101105)

2024-07-29 Thread Thurston Dang via cfe-commits


@@ -8,11 +8,18 @@ MemorySanitizer
 Introduction
 
 
-MemorySanitizer is a detector of uninitialized reads. It consists of a
+MemorySanitizer is a detector of uninitialized memory use. It consists of a
 compiler instrumentation module and a run-time library.
 
 Typical slowdown introduced by MemorySanitizer is **3x**.
 
+Here is a not comprehensive list cases when MemorySanitizer will report an 
error:

thurstond wrote:

Nit: "list of cases"

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


[clang] [docs][msan] List common cases reported by msan (PR #101105)

2024-07-29 Thread Thurston Dang via cfe-commits


@@ -8,11 +8,18 @@ MemorySanitizer
 Introduction
 
 
-MemorySanitizer is a detector of uninitialized reads. It consists of a
+MemorySanitizer is a detector of uninitialized memory use. It consists of a
 compiler instrumentation module and a run-time library.
 
 Typical slowdown introduced by MemorySanitizer is **3x**.
 
+Here is a not comprehensive list cases when MemorySanitizer will report an 
error:
+
+* A code uses uninitialized value in a conditional branch.
+* Uninitialized pointer was used for memory accesses.
+* Uninitialized value passed or returned from a function call, when it 
considered an undefined behavior. The check can be disabled with 
``-fno-sanitize-memory-param-retval``.

thurstond wrote:

Nit: "which is"?

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


[clang] [llvm] [msan] Precommit MSan Arm NEON vst tests (PR #98247)

2024-07-16 Thread Thurston Dang via cfe-commits

thurstond wrote:

Updated to IR tests

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


[clang] [llvm] [msan] Precommit MSan Arm NEON vst tests (PR #98247)

2024-07-17 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-17 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-17 Thread Thurston Dang via cfe-commits


@@ -2483,13 +2484,21 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
   using OriginCombiner = Combiner;
 
   /// Propagate origin for arbitrary operation.
-  void setOriginForNaryOp(Instruction &I) {
+  ///
+  /// Optionally skips n trailing operands.
+  void setOriginForNaryOp(Instruction &I, unsigned int skipLastOperands = 0) {

thurstond wrote:

> I prefer instead of extending this function we just to do
> 
> ```
> OriginCombiner OC(this, IRB);
> for (args)
>   OC.Add(I.getOperand(i));
> ```
> 
> inside of handleNEONVectorStoreIntrinsic

Done in 
https://github.com/llvm/llvm-project/pull/99360/commits/1970568ab31879094666b20d6f09b39682c20864

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-17 Thread Thurston Dang via cfe-commits


@@ -3865,6 +3866,125 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 setOriginForNaryOp(I);
   }
 
+  // Given two shadows ..., ..., return the interleaved value
+  // ABABABAB ...
+  //
+  // Width == number of elements in A == number of elements in B
+  Value *interleaveAB(IRBuilder<> &IRB, Value *left, Value *right, uint Width) 
{
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == Width);
+assert(cast(right->getType())->getNumElements() == Width);
+
+SmallVector Idxs;
+
+for (uint i = 0; i < Width; i++) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + Width));
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  // Given three shadows, which are already interleaved into two shadows
+  // ABABABAB and CxCxCxCx (x is undef), return the interleaved value 
ABCABCABC.
+  //
+  // Note: Width == number of elements in A == number of elements in B
+  // == number of elements in C
+  Value *interleaveABCx(IRBuilder<> &IRB, Value *left, Value *right,
+uint Width) {
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == 2 * 
Width);
+assert(cast(right->getType())->getNumElements() == 2 * 
Width);
+
+SmallVector Idxs;
+
+// Width parameter is the width of a single shadow (e.g., A).
+// The width of AB (or Cx) is Width * 2.
+for (uint i = 0; i < Width * 2; i += 2) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + 1));
+  Idxs.push_back(IRB.getInt32(i + Width));
+  // Index (i + 1 + Width) contains Undef; don't copy
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  /// Calculates the shadow for interleaving 2, 3 or 4 vectors
+  /// (e.g., for Arm NEON vector store).
+  Value *interleaveShadow(IRBuilder<> &IRB, IntrinsicInst &I) {
+// Don't use getNumOperands() because it includes the callee
+int numArgOperands = I.arg_size();
+assert(numArgOperands >= 1);
+
+// The last arg operand is the output
+int numVectors = numArgOperands - 1;
+
+for (int i = 0; i < numVectors; i++) {
+  assert(isa(I.getArgOperand(i)->getType()));
+}
+
+// Last operand is the destination
+assert(isa(I.getArgOperand(numArgOperands - 1)->getType()));
+
+uint16_t Width =
+cast(I.getArgOperand(0)->getType())->getNumElements();
+
+Value *interleaved = nullptr;
+if (numVectors == 2) {
+  interleaved =
+  interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+} else if (numVectors == 3) {
+  Value *UndefV = UndefValue::get(getShadow(&I, 0)->getType());
+  Value *AB = interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+  Value *Cx = interleaveAB(IRB, getShadow(&I, 2), UndefV, Width);
+  interleaved = interleaveABCx(IRB, AB, Cx, Width);
+} else if (numVectors == 4) {
+  Value *AB = interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+  Value *CD = interleaveAB(IRB, getShadow(&I, 2), getShadow(&I, 3), Width);
+  interleaved = interleaveAB(IRB, AB, CD, Width * 2);
+} else {
+  assert((numVectors >= 2) && (numVectors <= 4));
+}
+
+return interleaved;
+  }
+
+  /// Handle Arm NEON vector store intrinsics (vst{2,3,4}).
+  ///
+  /// Arm NEON vector store intrinsics have the output address (pointer) as the
+  /// last argument, with the initial arguments being the inputs. They return
+  /// void.
+  void handleNEONVectorStoreIntrinsic(IntrinsicInst &I) {
+IRBuilder<> IRB(&I);
+
+Value *interleavedShadow = interleaveShadow(IRB, I);
+
+// Don't use getNumOperands() because it includes the callee
+int numArgOperands = I.arg_size();
+assert(numArgOperands >= 1);
+
+// The last arg operand is the output
+Value *Addr = I.getArgOperand(numArgOperands - 1);
+
+Value *ShadowPtr, *OriginPtr;
+std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
+Addr, IRB, interleavedShadow->getType(), Align(1), /*isStore*/ true);
+IRB.CreateAlignedStore(interleavedShadow, ShadowPtr, Align(1));
+
+if (MS.TrackOrigins) {
+  OriginCombiner OC(this, IRB);
+  for (int i = 0; i < numArgOperands - 1; i++)
+OC.Add(I.getOperand(i));

thurstond wrote:

Fixed in 
https://github.com/llvm/llvm-project/pull/99360/commits/7a770ddec98c9dac7fac2e79ca4903272625cac7

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-17 Thread Thurston Dang via cfe-commits


@@ -3742,6 +3751,124 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 setOriginForNaryOp(I);
   }
 
+  // Given two shadows ..., ..., return the interleaved value
+  // ABABABAB ...
+  //
+  // Width == number of elements in A == number of elements in B
+  Value *interleaveAB(IRBuilder<> &IRB, Value *left, Value *right, uint Width) 
{
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == Width);
+assert(cast(right->getType())->getNumElements() == Width);
+
+SmallVector Idxs;
+
+for (uint i = 0; i < Width; i++) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + Width));
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  // Given three shadows, which are already interleaved into two shadows
+  // ABABABAB and CxCxCxCx (x is undef), return the interleaved value 
ABCABCABC.
+  //
+  // Note: Width == number of elements in A == number of elements in B
+  // == number of elements in C
+  Value *interleaveABCx(IRBuilder<> &IRB, Value *left, Value *right,
+uint Width) {
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == 2 * 
Width);
+assert(cast(right->getType())->getNumElements() == 2 * 
Width);
+
+SmallVector Idxs;
+
+// Width parameter is the width of a single shadow (e.g., A).
+// The width of AB (or Cx) is Width * 2.
+for (uint i = 0; i < Width * 2; i += 2) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + 1));
+  Idxs.push_back(IRB.getInt32(i + Width));
+  // Index (i + 1 + Width) contains Undef; don't copy
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  /// Calculates the shadow for interleaving 2, 3 or 4 vectors
+  /// (e.g., for Arm NEON vector store).
+  Value *interleaveShadow(IRBuilder<> &IRB, IntrinsicInst &I) {
+// Call arguments only
+int numArgOperands = I.getNumOperands() - 1;
+assert(numArgOperands >= 1);
+
+int numVectors = numArgOperands - 1;
+
+for (int i = 0; i < numVectors; i++) {
+  assert(isa(I.getArgOperand(i)->getType()));
+}
+
+// Last operand is the destination
+assert(isa(I.getArgOperand(numArgOperands - 1)->getType()));
+
+uint16_t Width =
+cast(I.getArgOperand(0)->getType())->getNumElements();
+
+Value *interleaved = nullptr;
+if (numVectors == 2) {
+  interleaved =
+  interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+} else if (numVectors == 3) {
+  Value *UndefV = UndefValue::get(getShadow(&I, 0)->getType());
+  Value *AB = interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+  Value *Cx = interleaveAB(IRB, getShadow(&I, 2), UndefV, Width);
+  interleaved = interleaveABCx(IRB, AB, Cx, Width);
+} else if (numVectors == 4) {
+  Value *AB = interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+  Value *CD = interleaveAB(IRB, getShadow(&I, 2), getShadow(&I, 3), Width);
+  interleaved = interleaveAB(IRB, AB, CD, Width * 2);
+} else {
+  assert((numVectors >= 2) && (numVectors <= 4));
+}
+
+return interleaved;
+  }
+
+  /// Handle Arm NEON vector store intrinsics (vst{2,3,4}).
+  ///
+  /// Arm NEON vector store intrinsics have the output address (pointer) as the
+  /// last argument, with the initial arguments being the inputs. They return
+  /// void.
+  void handleNEONVectorStoreIntrinsic(IntrinsicInst &I) {
+IRBuilder<> IRB(&I);
+
+Value *interleavedShadow = interleaveShadow(IRB, I);
+
+// Call arguments only
+int numArgOperands = I.getNumOperands() - 1;

thurstond wrote:

I've moved the pointer check earlier in 
https://github.com/llvm/llvm-project/pull/99360/commits/1cebde812e77dadbe38a39cd21878a79605e409c

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-17 Thread Thurston Dang via cfe-commits


@@ -3742,6 +3751,124 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 setOriginForNaryOp(I);
   }
 
+  // Given two shadows ..., ..., return the interleaved value
+  // ABABABAB ...
+  //
+  // Width == number of elements in A == number of elements in B
+  Value *interleaveAB(IRBuilder<> &IRB, Value *left, Value *right, uint Width) 
{
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == Width);
+assert(cast(right->getType())->getNumElements() == Width);
+
+SmallVector Idxs;
+
+for (uint i = 0; i < Width; i++) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + Width));
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  // Given three shadows, which are already interleaved into two shadows
+  // ABABABAB and CxCxCxCx (x is undef), return the interleaved value 
ABCABCABC.
+  //
+  // Note: Width == number of elements in A == number of elements in B
+  // == number of elements in C
+  Value *interleaveABCx(IRBuilder<> &IRB, Value *left, Value *right,
+uint Width) {
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == 2 * 
Width);
+assert(cast(right->getType())->getNumElements() == 2 * 
Width);
+
+SmallVector Idxs;
+
+// Width parameter is the width of a single shadow (e.g., A).
+// The width of AB (or Cx) is Width * 2.
+for (uint i = 0; i < Width * 2; i += 2) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + 1));
+  Idxs.push_back(IRB.getInt32(i + Width));
+  // Index (i + 1 + Width) contains Undef; don't copy
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  /// Calculates the shadow for interleaving 2, 3 or 4 vectors
+  /// (e.g., for Arm NEON vector store).
+  Value *interleaveShadow(IRBuilder<> &IRB, IntrinsicInst &I) {

thurstond wrote:

Good idea! Done in 
https://github.com/llvm/llvm-project/pull/99360/commits/41d3a53f770bd78cc5ab7325ac1f8f62437dd73c

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-17 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-18 Thread Thurston Dang via cfe-commits


@@ -3865,6 +3866,42 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 setOriginForNaryOp(I);
   }
 
+  /// Handle Arm NEON vector store intrinsics (vst{2,3,4}).
+  ///
+  /// Arm NEON vector store intrinsics have the output address (pointer) as the
+  /// last argument, with the initial arguments being the inputs. They return
+  /// void.
+  void handleNEONVectorStoreIntrinsic(IntrinsicInst &I) {
+IRBuilder<> IRB(&I);
+
+// Don't use getNumOperands() because it includes the callee
+int numArgOperands = I.arg_size();
+assert(numArgOperands >= 1);
+
+// The last arg operand is the output
+Value *Addr = I.getArgOperand(numArgOperands - 1);
+if (ClCheckAccessAddress)
+  insertShadowCheck(Addr, &I);
+
+IntrinsicInst *ShadowI = cast(I.clone());
+for (int i = 0; i < numArgOperands - 1; i++) {

thurstond wrote:

I ended up making it a two-liner, to assert that the arg operand is a fixed 
vector type

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-18 Thread Thurston Dang via cfe-commits


@@ -3865,6 +3866,42 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 setOriginForNaryOp(I);
   }
 
+  /// Handle Arm NEON vector store intrinsics (vst{2,3,4}).
+  ///
+  /// Arm NEON vector store intrinsics have the output address (pointer) as the
+  /// last argument, with the initial arguments being the inputs. They return
+  /// void.
+  void handleNEONVectorStoreIntrinsic(IntrinsicInst &I) {
+IRBuilder<> IRB(&I);
+
+// Don't use getNumOperands() because it includes the callee
+int numArgOperands = I.arg_size();
+assert(numArgOperands >= 1);
+
+// The last arg operand is the output
+Value *Addr = I.getArgOperand(numArgOperands - 1);
+if (ClCheckAccessAddress)
+  insertShadowCheck(Addr, &I);
+
+IntrinsicInst *ShadowI = cast(I.clone());
+for (int i = 0; i < numArgOperands - 1; i++) {
+  ShadowI->setArgOperand(i, getShadow(&I, i));
+}
+
+Value *ShadowPtr, *OriginPtr;
+std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
+Addr, IRB, ShadowI->getType(), Align(1), /*isStore*/ true);
+ShadowI->setArgOperand(numArgOperands - 1, ShadowPtr);
+ShadowI->insertAfter(&I);
+
+if (MS.TrackOrigins) {
+  OriginCombiner OC(this, IRB);
+  for (int i = 0; i < numArgOperands - 1; i++)
+OC.Add(I.getArgOperand(i));
+  OC.Done(&I);

thurstond wrote:

Done in https://github.com/llvm/llvm-project/pull/99360/files

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-18 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-18 Thread Thurston Dang via cfe-commits


@@ -3742,6 +3751,124 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 setOriginForNaryOp(I);
   }
 
+  // Given two shadows ..., ..., return the interleaved value
+  // ABABABAB ...
+  //
+  // Width == number of elements in A == number of elements in B
+  Value *interleaveAB(IRBuilder<> &IRB, Value *left, Value *right, uint Width) 
{
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == Width);
+assert(cast(right->getType())->getNumElements() == Width);
+
+SmallVector Idxs;
+
+for (uint i = 0; i < Width; i++) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + Width));
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  // Given three shadows, which are already interleaved into two shadows
+  // ABABABAB and CxCxCxCx (x is undef), return the interleaved value 
ABCABCABC.
+  //
+  // Note: Width == number of elements in A == number of elements in B
+  // == number of elements in C
+  Value *interleaveABCx(IRBuilder<> &IRB, Value *left, Value *right,
+uint Width) {
+assert(isa(left->getType()));
+assert(isa(right->getType()));
+assert(cast(left->getType())->getNumElements() == 2 * 
Width);
+assert(cast(right->getType())->getNumElements() == 2 * 
Width);
+
+SmallVector Idxs;
+
+// Width parameter is the width of a single shadow (e.g., A).
+// The width of AB (or Cx) is Width * 2.
+for (uint i = 0; i < Width * 2; i += 2) {
+  Idxs.push_back(IRB.getInt32(i));
+  Idxs.push_back(IRB.getInt32(i + 1));
+  Idxs.push_back(IRB.getInt32(i + Width));
+  // Index (i + 1 + Width) contains Undef; don't copy
+}
+
+return IRB.CreateShuffleVector(left, right, ConstantVector::get(Idxs));
+  }
+
+  /// Calculates the shadow for interleaving 2, 3 or 4 vectors
+  /// (e.g., for Arm NEON vector store).
+  Value *interleaveShadow(IRBuilder<> &IRB, IntrinsicInst &I) {
+// Call arguments only
+int numArgOperands = I.getNumOperands() - 1;
+assert(numArgOperands >= 1);
+
+int numVectors = numArgOperands - 1;
+
+for (int i = 0; i < numVectors; i++) {
+  assert(isa(I.getArgOperand(i)->getType()));
+}
+
+// Last operand is the destination
+assert(isa(I.getArgOperand(numArgOperands - 1)->getType()));
+
+uint16_t Width =
+cast(I.getArgOperand(0)->getType())->getNumElements();
+
+Value *interleaved = nullptr;
+if (numVectors == 2) {
+  interleaved =
+  interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+} else if (numVectors == 3) {
+  Value *UndefV = UndefValue::get(getShadow(&I, 0)->getType());
+  Value *AB = interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+  Value *Cx = interleaveAB(IRB, getShadow(&I, 2), UndefV, Width);
+  interleaved = interleaveABCx(IRB, AB, Cx, Width);
+} else if (numVectors == 4) {
+  Value *AB = interleaveAB(IRB, getShadow(&I, 0), getShadow(&I, 1), Width);
+  Value *CD = interleaveAB(IRB, getShadow(&I, 2), getShadow(&I, 3), Width);
+  interleaved = interleaveAB(IRB, AB, CD, Width * 2);
+} else {
+  assert((numVectors >= 2) && (numVectors <= 4));
+}
+
+return interleaved;
+  }
+
+  /// Handle Arm NEON vector store intrinsics (vst{2,3,4}).
+  ///
+  /// Arm NEON vector store intrinsics have the output address (pointer) as the
+  /// last argument, with the initial arguments being the inputs. They return
+  /// void.
+  void handleNEONVectorStoreIntrinsic(IntrinsicInst &I) {
+IRBuilder<> IRB(&I);
+
+Value *interleavedShadow = interleaveShadow(IRB, I);
+
+// Call arguments only
+int numArgOperands = I.getNumOperands() - 1;
+assert(numArgOperands >= 1);
+Value *Addr = I.getArgOperand(numArgOperands - 1);
+
+Value *ShadowPtr, *OriginPtr;
+std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
+Addr, IRB, interleavedShadow->getType(), Align(1), /*isStore*/ true);
+IRB.CreateAlignedStore(interleavedShadow, ShadowPtr, Align(1));
+
+if (MS.TrackOrigins) {
+  // We don't use the last two operands to compute the origin, because:
+  // - the last operand is the callee

thurstond wrote:

Done

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-18 Thread Thurston Dang via cfe-commits


@@ -2498,6 +2499,15 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 MSV->setOrigin(I, Origin);
   }
 }
+
+/// Store the current combined value at the specified origin
+/// location.
+void DoneAndStoreOrigin(TypeSize TS, Value *OriginPtr) {
+  if (MSV->MS.TrackOrigins) {
+assert(Origin);
+MSV->paintOrigin(IRB, Origin, OriginPtr, TS, Align(1));

thurstond wrote:

Updated to kMinOriginAlignment in 
https://github.com/llvm/llvm-project/pull/99360/commits/2d0abae869d0c565dc6230ec8adbaf5067edfc03

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-18 Thread Thurston Dang via cfe-commits


@@ -2498,6 +2499,15 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
 MSV->setOrigin(I, Origin);
   }
 }
+
+/// Store the current combined value at the specified origin
+/// location.
+void DoneAndStoreOrigin(TypeSize TS, Value *OriginPtr) {
+  if (MSV->MS.TrackOrigins) {
+assert(Origin);
+MSV->paintOrigin(IRB, Origin, OriginPtr, TS, Align(1));

thurstond wrote:

Changed back to 1-byte alignment in 
https://github.com/llvm/llvm-project/pull/99360/commits/af86d86e1d00f09c4e8c8f425a5bca6522636820
 per offline discussion

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


[clang] [llvm] [msan] Implement support for Arm NEON vst{2,3,4} instructions (PR #99360)

2024-07-19 Thread Thurston Dang via cfe-commits

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


[clang] [ubsan] Suppression by type for `-fsanitize=enum` (PR #114754)

2024-11-04 Thread Thurston Dang via cfe-commits

https://github.com/thurstond approved this pull request.


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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 1/9] [ubsan] Change ubsan-unique-traps to use nomerge instead
 of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SAME

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits


@@ -3919,18 +3919,16 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 Builder.CreateCondBr(Checked, Cont, TrapBB);
 EmitBlock(TrapBB);
 
-llvm::CallInst *TrapCall = Builder.CreateCall(
-CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::CallInst *TrapCall =
+Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
+   llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);

thurstond wrote:

Ah, I see, thanks. I've fixed it (and the test) in 
https://github.com/llvm/llvm-project/pull/117651/commits/5107ce194c9b03c2f32eb1508df0c92b13b3e2fd

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 01/10] [ubsan] Change ubsan-unique-traps to use nomerge
 instead of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SA

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits


@@ -3919,18 +3919,16 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 Builder.CreateCondBr(Checked, Cont, TrapBB);
 EmitBlock(TrapBB);
 
-llvm::CallInst *TrapCall = Builder.CreateCall(
-CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::CallInst *TrapCall =
+Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
+   llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);

thurstond wrote:

https://github.com/llvm/llvm-project/commit/5107ce194c9b03c2f32eb1508df0c92b13b3e2fd
 doesn't work because of inlining: none of the ubsantraps in function m() have 
nomerge, because they were each unique ubsantraps in the non-inlined functions.

Is there a downside to emitting nomerge for every ubsantrap (even the first 
instance)?

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 01/12] [ubsan] Change ubsan-unique-traps to use nomerge
 instead of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SA

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From cffa7c3081a1d7b9cb64ac129109cb358d11a751 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 01/14] [ubsan] Change ubsan-unique-traps to use nomerge
 instead of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp|  6 ++--
 clang/test/CodeGen/bounds-checking.c|  4 +--
 clang/test/CodeGen/ubsan-trap-merge.c   | 24 +++
 llvm/test/CodeGen/X86/ubsan-trap-merge.ll   | 31 ++-
 llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll | 33 ++---
 5 files changed, 47 insertions(+), 51 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
index b4de97b5e08f33..ef32605c73174a 100644
--- a/clang/test/CodeGen/ubsan-trap-merge.c
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -1,20 +1,20 @@
 // NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
 // The most important assertion is the attributes at the end of the file, which
-// shows that ubsan does not currently attach 'nomerge'.
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
 //
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm 
-fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 
-mllvm -ubsan-unique-traps %s -o - \
 // RUN: | FileCheck %s
 //
 // REQUIRES: x86-registered-target
 
-// CHECK-LABEL: define dso_local noundef i32 @f(
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
 // CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
 // CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
 // CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
 // CHECK:   [[TRAP]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-

[clang] Reapply "[NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge" (#117804) (PR #117805)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From e635c76812eb8a6346e8602ec2eb6e4c389fcf6c Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 01/15] [ubsan] Change ubsan-unique-traps to use nomerge
 instead of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp|  6 ++--
 clang/test/CodeGen/bounds-checking.c|  4 +--
 clang/test/CodeGen/ubsan-trap-merge.c   | 18 +--
 llvm/test/CodeGen/X86/ubsan-trap-merge.ll   | 31 ++-
 llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll | 33 ++---
 5 files changed, 44 insertions(+), 48 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
index 0f50d8c1ff47f2..ef32605c73174a 100644
--- a/clang/test/CodeGen/ubsan-trap-merge.c
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -1,6 +1,6 @@
 // NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
 // The most important assertion is the attributes at the end of the file, which
-// shows that ubsan does not currently attach 'nomerge'.
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
 //
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm 
-fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 
-mllvm -ubsan-unique-traps %s -o - \
 // RUN: | FileCheck %s
@@ -14,7 +14,7 @@
 // CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
 // CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
 // CHECK:   [[TRAP]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
 // CHECK-NEXT:unreachable, !nosanitize [[META2]]
 // CHECK:   [[CONT]]:
 // CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META2]]
@@ -31,7 +31,7 @@ int f(int x) {
 // CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
 // CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits


@@ -3919,18 +3919,16 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 Builder.CreateCondBr(Checked, Cont, TrapBB);
 EmitBlock(TrapBB);
 
-llvm::CallInst *TrapCall = Builder.CreateCall(
-CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::CallInst *TrapCall =
+Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
+   llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);

thurstond wrote:

Thanks, fixed in 
https://github.com/llvm/llvm-project/pull/117651/commits/0e8a4143ddc7b5c6e9ca7e64729ba5adcb0d92fb

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From e635c76812eb8a6346e8602ec2eb6e4c389fcf6c Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 01/16] [ubsan] Change ubsan-unique-traps to use nomerge
 instead of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp|  6 ++--
 clang/test/CodeGen/bounds-checking.c|  4 +--
 clang/test/CodeGen/ubsan-trap-merge.c   | 18 +--
 llvm/test/CodeGen/X86/ubsan-trap-merge.ll   | 31 ++-
 llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll | 33 ++---
 5 files changed, 44 insertions(+), 48 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
index 0f50d8c1ff47f2..ef32605c73174a 100644
--- a/clang/test/CodeGen/ubsan-trap-merge.c
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -1,6 +1,6 @@
 // NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
 // The most important assertion is the attributes at the end of the file, which
-// shows that ubsan does not currently attach 'nomerge'.
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
 //
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm 
-fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 
-mllvm -ubsan-unique-traps %s -o - \
 // RUN: | FileCheck %s
@@ -14,7 +14,7 @@
 // CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
 // CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
 // CHECK:   [[TRAP]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
 // CHECK-NEXT:unreachable, !nosanitize [[META2]]
 // CHECK:   [[CONT]]:
 // CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META2]]
@@ -31,7 +31,7 @@ int f(int x) {
 // CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
 // CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 1/7] [ubsan] Change ubsan-unique-traps to use nomerge instead
 of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SAME

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge (PR #117649)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge (PR #117649)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits


@@ -3919,18 +3919,16 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 Builder.CreateCondBr(Checked, Cont, TrapBB);
 EmitBlock(TrapBB);
 
-llvm::CallInst *TrapCall = Builder.CreateCall(
-CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::CallInst *TrapCall =
+Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
+   llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);

thurstond wrote:

Doesn't line 3918 (`TrapBB = createBasicBlock("trap");`) guarantee that `TrapBB 
!= nullptr`?

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 01/13] [ubsan] Change ubsan-unique-traps to use nomerge
 instead of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SA

[clang] [NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge (PR #117649)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] Revert "[NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge" (PR #117804)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond created 
https://github.com/llvm/llvm-project/pull/117804

Reverts llvm/llvm-project#117649

Reason: buildbot breakage:  
https://lab.llvm.org/buildbot/#/builders/144/builds/12581

>From 638427b08f7308f388b7f0bdaf426ca1f58e1b18 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 14:27:18 -0800
Subject: [PATCH] =?UTF-8?q?Revert=20"[NFC][clang]=20Add=20ubsan-trap-merge?=
 =?UTF-8?q?.c=20test=20to=20show=20absence=20of=20nomerge=20(=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit 1b68b33ac0b3c2c8bd2ab89fec4f516f622cebdf.
---
 clang/test/CodeGen/ubsan-trap-merge.c | 105 --
 1 file changed, 105 deletions(-)
 delete mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
deleted file mode 100644
index b4de97b5e08f33..00
--- a/clang/test/CodeGen/ubsan-trap-merge.c
+++ /dev/null
@@ -1,105 +0,0 @@
-// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
-// The most important assertion is the attributes at the end of the file, which
-// shows that ubsan does not currently attach 'nomerge'.
-//
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm 
-fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 
-mllvm -ubsan-unique-traps %s -o - \
-// RUN: | FileCheck %s
-//
-// REQUIRES: x86-registered-target
-
-// CHECK-LABEL: define dso_local noundef i32 @f(
-// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
-// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
-// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
-// CHECK:   [[TRAP]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
-// CHECK-NEXT:unreachable, !nosanitize [[META2]]
-// CHECK:   [[CONT]]:
-// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META2]]
-// CHECK-NEXT:ret i32 [[TMP2]]
-//
-int f(int x) {
-  return x + 125;
-}
-
-// CHECK-LABEL: define dso_local noundef i32 @g(
-// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
-// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
-// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
-// CHECK:   [[TRAP]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize 
[[META2]]
-// CHECK-NEXT:unreachable, !nosanitize [[META2]]
-// CHECK:   [[CONT]]:
-// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META2]]
-// CHECK-NEXT:ret i32 [[TMP2]]
-//
-int g(int x) {
-  return x + 127;
-}
-
-// CHECK-LABEL: define dso_local noundef i32 @h(
-// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
-// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
-// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
-// CHECK:   [[TRAP]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize 
[[META2]]
-// CHECK-NEXT:unreachable, !nosanitize [[META2]]
-// CHECK:   [[CONT]]:
-// CHECK-NEXT:[[TMP2:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]]
-// CHECK-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, 
!nosanitize [[META2]]
-// CHECK-NEXT:br i1 [[TMP3]], label %[[TRAP1:.*]], label %[[CONT2:.*]], 
!nosanitize [[META2]]
-// CHECK:   [[TRAP1]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 4) #[[ATTR4]], !nosanitize 
[[META2]]
-// CHECK-NEXT:unreachable, !nosanitize [[META2]]
-// CHECK:   [[CONT2]]:
-// CHECK-NEXT:[[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, 
!nosanitize [[META2]]
-// CHECK-NEXT:[[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META2]]
-// CHECK-NEXT:[[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], 
i32 [[TMP4]])
-// CHECK-NEXT:ret i32 [[COND]]
-//
-int h(int x, int y) {
-  x += 127;
-  y += 129;
-  return x < y ? x : y;
-}
-
-// CHECK-LABEL: define dso_local noundef i32 @m(
-// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) 
loca

[clang] Revert "[NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge" (PR #117804)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From cffa7c3081a1d7b9cb64ac129109cb358d11a751 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 01/13] [ubsan] Change ubsan-unique-traps to use nomerge
 instead of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp|  6 ++--
 clang/test/CodeGen/bounds-checking.c|  4 +--
 clang/test/CodeGen/ubsan-trap-merge.c   | 24 +++
 llvm/test/CodeGen/X86/ubsan-trap-merge.ll   | 31 ++-
 llvm/test/CodeGen/X86/ubsan-trap-nomerge.ll | 33 ++---
 5 files changed, 47 insertions(+), 51 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
index b4de97b5e08f33..ef32605c73174a 100644
--- a/clang/test/CodeGen/ubsan-trap-merge.c
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -1,20 +1,20 @@
 // NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
 // The most important assertion is the attributes at the end of the file, which
-// shows that ubsan does not currently attach 'nomerge'.
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
 //
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm 
-fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 
-mllvm -ubsan-unique-traps %s -o - \
 // RUN: | FileCheck %s
 //
 // REQUIRES: x86-registered-target
 
-// CHECK-LABEL: define dso_local noundef i32 @f(
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
 // CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
 // CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
 // CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
 // CHECK:   [[TRAP]]:
-// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-

[clang] Reapply "[NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge" (#117804) (PR #117805)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond created 
https://github.com/llvm/llvm-project/pull/117805

This reverts commit c8bdb31ff66e8934060c60816c57925fdec42a2c.

It was reverted because I forgot to update the auto-generated assertions after 
adding the target triple.

Original commit message:

This test (copied from https://github.com/llvm/llvm-project/pull/83470) 
demonstrates that UBSan does not add the nomerge annotation. This is 
significant because it can result in them being merged by the backend, even 
when -ubsan-unique-traps is enabled.

N.B. https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. 
https://github.com/llvm/llvm-project/pull/101549 fixed that limitation ("It 
sets nomerge flag for the node if the instruction has nomerge arrtibute."); 
planned upcoming work (https://github.com/llvm/llvm-project/pull/117651) will 
add nomerge for ubsan.

>From b5628adc6f93c733058a3c2d90b78e1bf37c63be Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 22:29:04 +
Subject: [PATCH] Reapply "[NFC][clang] Add ubsan-trap-merge.c test to show
 absence of nomerge" (#117804)

This reverts commit c8bdb31ff66e8934060c60816c57925fdec42a2c.

It was reverted because I forgot to update the auto-generated assertions after 
adding the target triple.

Original commit message:

This test (copied from https://github.com/llvm/llvm-project/pull/83470) 
demonstrates that UBSan does not add the nomerge annotation. This is 
significant because it can result in them being merged by the backend, even 
when -ubsan-unique-traps is enabled.

N.B. https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. 
https://github.com/llvm/llvm-project/pull/101549 fixed that limitation ("It 
sets nomerge flag for the node if the instruction has nomerge arrtibute."); 
planned upcoming work (https://github.com/llvm/llvm-project/pull/117651) will 
add nomerge for ubsan.
---
 clang/test/CodeGen/ubsan-trap-merge.c | 105 ++
 1 file changed, 105 insertions(+)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..0f50d8c1ff47f2
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,105 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan does not currently attach 'nomerge'.
+//
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm 
-fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 
-mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+//
+// REQUIRES: x86-registered-target
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META2]]
+// CHECK-NEXT:unreachable, !nosanitize [[META2]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META2]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META2]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META2]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize 
[[META2]]
+// CHECK-NEXT:unreachable, !nosanitize [[META2]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META2]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int g(int x) {
+  return x + 127;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h(
+// CHECK-SAME: i32

[clang] [NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge (PR #117649)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117649

>From d85a7637f4386bc243f6f4198faf6f9cdbb49506 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:19:47 +
Subject: [PATCH 1/2] [NFC][clang] Add ubsan-trap-merge.c test to show absence
 of nomerge

This test demonstrates that UBSan does not add the nomerge annotation. This is 
significant because it results in them being merged by the backend.

N.B. https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. 
https://github.com/llvm/llvm-project/pull/101549 fixed that limitation ("It 
sets nomerge flag for the node if the instruction has nomerge arrtibute."); 
planned upcoming will add nomerge for ubsan.
---
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 1 file changed, 106 insertions(+)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..6c78fc4abf67c1
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan does not currently attach 'nomerge'.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local noundef i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local noundef i32 @g(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META5]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize 
[[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int g(int x) {
+  return x + 127;
+}
+
+// CHECK-LABEL: define dso_local noundef i32 @h(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META5]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize 
[[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META5]]
+// CHECK-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP3]], label %[[TRAP1:.*]], label %[[CONT2:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP1]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 4) #[[ATTR4]], !nosanitize 
[[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT2]]:
+// CHECK-NEXT:[[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:[[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:[[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], 
i32 [[TMP4]])
+// CHECK-NEXT:ret i32 [[COND]]
+//
+int 

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 1/6] [ubsan] Change ubsan-unique-traps to use nomerge instead
 of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SAME

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits


@@ -0,0 +1,185 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5

thurstond wrote:

Thanks, moved!

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits


@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \

thurstond wrote:

Done! I'd overlooked the clang driver distinction - thanks for your 
electrifying comment! 

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 1/8] [ubsan] Change ubsan-unique-traps to use nomerge instead
 of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SAME

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-26 Thread Thurston Dang via cfe-commits

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


[clang] 4a63f4d - Revert "[HLSL] set alwaysinline on HLSL functions (#106588)"

2024-09-17 Thread Thurston Dang via cfe-commits

Author: Thurston Dang
Date: 2024-09-17T21:06:36Z
New Revision: 4a63f4d301c0e044073e1b1f8f110015ec1778a1

URL: 
https://github.com/llvm/llvm-project/commit/4a63f4d301c0e044073e1b1f8f110015ec1778a1
DIFF: 
https://github.com/llvm/llvm-project/commit/4a63f4d301c0e044073e1b1f8f110015ec1778a1.diff

LOG: Revert "[HLSL] set alwaysinline on HLSL functions (#106588)"

This reverts commit a729e706de3fc6ebee49ede3c50afb47f2e29191.

Reason:bBuildbot failure 
(https://lab.llvm.org/buildbot/#/builders/25/builds/2541):
'Clang :: CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl' failed

Added: 


Modified: 
clang/lib/CodeGen/CGHLSLRuntime.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
clang/test/CodeGenHLSL/GlobalDestructors.hlsl
clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl
clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl

Removed: 
clang/test/CodeGenHLSL/inline-constructors.hlsl
clang/test/CodeGenHLSL/inline-functions.hlsl



diff  --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index bec0a29e34fcb5..b6e6555e63fca1 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -338,7 +338,6 @@ void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes(
 NumThreadsAttr->getZ());
 Fn->addFnAttr(NumThreadsKindStr, NumThreadsStr);
   }
-  Fn->addFnAttr(llvm::Attribute::NoInline);
 }
 
 static Value *buildVectorInput(IRBuilder<> &B, Function *F, llvm::Type *Ty) {

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 17b82b205063d4..ba2d6588900a11 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2473,14 +2473,11 @@ void 
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
 B.addAttribute(llvm::Attribute::StackProtectReq);
 
   if (!D) {
-// Non-entry HLSL functions must always be inlined.
-if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline))
-  B.addAttribute(llvm::Attribute::AlwaysInline);
 // If we don't have a declaration to control inlining, the function isn't
 // explicitly marked as alwaysinline for semantic reasons, and inlining is
 // disabled, mark the function as noinline.
-else if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
- CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining)
+if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
+CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining)
   B.addAttribute(llvm::Attribute::NoInline);
 
 F->addFnAttrs(B);
@@ -2507,13 +2504,9 @@ void 
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
   ShouldAddOptNone &= !D->hasAttr();
   ShouldAddOptNone &= !D->hasAttr();
 
-  // Non-entry HLSL functions must always be inlined.
-  if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline) &&
-  !D->hasAttr()) {
-B.addAttribute(llvm::Attribute::AlwaysInline);
-  } else if ((ShouldAddOptNone || D->hasAttr()) &&
- !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
-// Add optnone, but do so only if the function isn't always_inline.
+  // Add optnone, but do so only if the function isn't always_inline.
+  if ((ShouldAddOptNone || D->hasAttr()) &&
+  !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
 B.addAttribute(llvm::Attribute::OptimizeNone);
 
 // OptimizeNone implies noinline; we should not be inlining such functions.
@@ -2533,8 +2526,7 @@ void 
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
 B.addAttribute(llvm::Attribute::NoInline);
   } else if (D->hasAttr()) {
 B.addAttribute(llvm::Attribute::NoDuplicate);
-  } else if (D->hasAttr() &&
- !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
+  } else if (D->hasAttr() && 
!F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
 // Add noinline if the function isn't always_inline.
 B.addAttribute(llvm::Attribute::NoInline);
   } else if (D->hasAttr() &&

diff  --git a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl 
b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
index b39311ad67cd62..f954c9d2f029f2 100644
--- a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
+++ b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm 
-disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -O0 %s -o 
- | FileCheck %s --check-prefixes=CHECK,INLINE
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm 
-disable-llvm-passes %s -o - | FileCheck %s
 
 int i;
 
@@ -8,7 +7,7 @@ __attri

[clang] [HLSL] set alwaysinline on HLSL functions (PR #106588)

2024-09-17 Thread Thurston Dang via cfe-commits

thurstond wrote:

@nico Sorry, my bad. I didn't notice the test was also updated as a companion 
to this change (https://github.com/llvm/llvm-project/pull/109023). I'll revert 
the test as well.

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


[clang] da03d17 - Revert "[HLSL] update StructuredBuffer subscript test for alwaysinline (#109023)"

2024-09-17 Thread Thurston Dang via cfe-commits

Author: Thurston Dang
Date: 2024-09-17T22:49:59Z
New Revision: da03d17698f205fe8ebc54c32994c8ce2c51a81e

URL: 
https://github.com/llvm/llvm-project/commit/da03d17698f205fe8ebc54c32994c8ce2c51a81e
DIFF: 
https://github.com/llvm/llvm-project/commit/da03d17698f205fe8ebc54c32994c8ce2c51a81e.diff

LOG: Revert "[HLSL] update StructuredBuffer subscript test for alwaysinline 
(#109023)"

This reverts commit f4fe26ddfde0d5bb1c512e89a9cdd442a7518ee1.

Reason: 4a63f4d301c0e044073e1b1f8f110015ec1778a1 reverted "[HLSL] set 
alwaysinline on HLSL functions (#106588)" due to a buildbot failure; this test 
(which builds upon the reverted patch) also needs to be reverted.

Added: 


Modified: 
clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl

Removed: 




diff  --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl 
b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl
index 155749ec4f94a9..9bd885d94d7e75 100644
--- a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl
@@ -11,7 +11,6 @@ void main(unsigned GI : SV_GroupIndex) {
 // Even at -O0 the subscript operators get inlined. The -O0 IR is a bit messy
 // and confusing to follow so the match here is pretty weak.
 
-// CHECK: define void @main()
-// Verify inlining leaves only calls to "llvm." intrinsics
-// CHECK-NOT:   call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
+// CHECK: define internal void @"?main@@YAXI@Z"
+// CHECK-NOT: call
 // CHECK: ret void



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [HLSL] set alwaysinline on HLSL functions (PR #106588)

2024-09-17 Thread Thurston Dang via cfe-commits

thurstond wrote:

Oh, actually, I just realized the test update was the fix-forward. So the 
correct fix would be to reland both the change and the test update. Sorry!

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


[clang] 4a0bf83 - Reapply "[HLSL] update StructuredBuffer subscript test for alwaysinline (#109023)"

2024-09-17 Thread Thurston Dang via cfe-commits

Author: Thurston Dang
Date: 2024-09-17T22:54:04Z
New Revision: 4a0bf8377e1038d6cf9454c7c6740bd759729938

URL: 
https://github.com/llvm/llvm-project/commit/4a0bf8377e1038d6cf9454c7c6740bd759729938
DIFF: 
https://github.com/llvm/llvm-project/commit/4a0bf8377e1038d6cf9454c7c6740bd759729938.diff

LOG: Reapply "[HLSL] update StructuredBuffer subscript test for alwaysinline 
(#109023)"

This reverts commit da03d17698f205fe8ebc54c32994c8ce2c51a81e.

I mistakenly reverted this fix-forward.

Added: 


Modified: 
clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl

Removed: 




diff  --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl 
b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl
index 9bd885d94d7e75..155749ec4f94a9 100644
--- a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-subscript.hlsl
@@ -11,6 +11,7 @@ void main(unsigned GI : SV_GroupIndex) {
 // Even at -O0 the subscript operators get inlined. The -O0 IR is a bit messy
 // and confusing to follow so the match here is pretty weak.
 
-// CHECK: define internal void @"?main@@YAXI@Z"
-// CHECK-NOT: call
+// CHECK: define void @main()
+// Verify inlining leaves only calls to "llvm." intrinsics
+// CHECK-NOT:   call {{[^@]*}} @{{[^l][^l][^v][^m][^\.]}}
 // CHECK: ret void



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b89bb77 - Reapply "[HLSL] set alwaysinline on HLSL functions (#106588)"

2024-09-17 Thread Thurston Dang via cfe-commits

Author: Thurston Dang
Date: 2024-09-17T22:54:52Z
New Revision: b89bb7775d155fc787ab3170f3fa38449069ecb3

URL: 
https://github.com/llvm/llvm-project/commit/b89bb7775d155fc787ab3170f3fa38449069ecb3
DIFF: 
https://github.com/llvm/llvm-project/commit/b89bb7775d155fc787ab3170f3fa38449069ecb3.diff

LOG: Reapply "[HLSL] set alwaysinline on HLSL functions (#106588)"

This reverts commit 4a63f4d301c0e044073e1b1f8f110015ec1778a1.

It was reverted because of a buildbot breakage, but the fix-forward has
landed (https://github.com/llvm/llvm-project/pull/109023).

Added: 
clang/test/CodeGenHLSL/inline-constructors.hlsl
clang/test/CodeGenHLSL/inline-functions.hlsl

Modified: 
clang/lib/CodeGen/CGHLSLRuntime.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl
clang/test/CodeGenHLSL/GlobalDestructors.hlsl
clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl
clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl

Removed: 




diff  --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index b6e6555e63fca1..bec0a29e34fcb5 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -338,6 +338,7 @@ void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes(
 NumThreadsAttr->getZ());
 Fn->addFnAttr(NumThreadsKindStr, NumThreadsStr);
   }
+  Fn->addFnAttr(llvm::Attribute::NoInline);
 }
 
 static Value *buildVectorInput(IRBuilder<> &B, Function *F, llvm::Type *Ty) {

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index ba2d6588900a11..17b82b205063d4 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2473,11 +2473,14 @@ void 
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
 B.addAttribute(llvm::Attribute::StackProtectReq);
 
   if (!D) {
+// Non-entry HLSL functions must always be inlined.
+if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline))
+  B.addAttribute(llvm::Attribute::AlwaysInline);
 // If we don't have a declaration to control inlining, the function isn't
 // explicitly marked as alwaysinline for semantic reasons, and inlining is
 // disabled, mark the function as noinline.
-if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
-CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining)
+else if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) &&
+ CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining)
   B.addAttribute(llvm::Attribute::NoInline);
 
 F->addFnAttrs(B);
@@ -2504,9 +2507,13 @@ void 
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
   ShouldAddOptNone &= !D->hasAttr();
   ShouldAddOptNone &= !D->hasAttr();
 
-  // Add optnone, but do so only if the function isn't always_inline.
-  if ((ShouldAddOptNone || D->hasAttr()) &&
-  !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
+  // Non-entry HLSL functions must always be inlined.
+  if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline) &&
+  !D->hasAttr()) {
+B.addAttribute(llvm::Attribute::AlwaysInline);
+  } else if ((ShouldAddOptNone || D->hasAttr()) &&
+ !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
+// Add optnone, but do so only if the function isn't always_inline.
 B.addAttribute(llvm::Attribute::OptimizeNone);
 
 // OptimizeNone implies noinline; we should not be inlining such functions.
@@ -2526,7 +2533,8 @@ void 
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
 B.addAttribute(llvm::Attribute::NoInline);
   } else if (D->hasAttr()) {
 B.addAttribute(llvm::Attribute::NoDuplicate);
-  } else if (D->hasAttr() && 
!F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
+  } else if (D->hasAttr() &&
+ !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) {
 // Add noinline if the function isn't always_inline.
 B.addAttribute(llvm::Attribute::NoInline);
   } else if (D->hasAttr() &&

diff  --git a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl 
b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
index f954c9d2f029f2..b39311ad67cd62 100644
--- a/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
+++ b/clang/test/CodeGenHLSL/GlobalConstructorFunction.hlsl
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm 
-disable-llvm-passes %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm 
-disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -O0 %s -o 
- | FileCheck %s --check-prefixes=CHECK,INLINE
 
 int i;
 
@@ -7,7 +8,7 @@ __attribute__((constructor)) void c

[clang] [HLSL] set alwaysinline on HLSL functions (PR #106588)

2024-09-17 Thread Thurston Dang via cfe-commits

thurstond wrote:

I've reverted both of my reverts

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


[clang] [HLSL] set alwaysinline on HLSL functions (PR #106588)

2024-09-17 Thread Thurston Dang via cfe-commits

thurstond wrote:

> Sorry I didn't mention here that the fix was in. It looks like everything is 
> clean now?

Yes, both your changes are back in and I anticipate the buildbots will be green 
again. Sorry for the noise!

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


[clang] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-25 Thread Thurston Dang via cfe-commits

https://github.com/thurstond created 
https://github.com/llvm/llvm-project/pull/117651

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 has since fixed the nomerge 
limitation ("It sets nomerge flag for the node if the instruction has nomerge 
arrtibute."). This patch therefore takes advantage of nomerge instead of using 
the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH] [ubsan] Change ubsan-unique-traps to use nomerge instead of
 counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s

[clang] [NFC][clang] Add ubsan-trap-merge.c test to show absence of nomerge (PR #117649)

2024-11-25 Thread Thurston Dang via cfe-commits

https://github.com/thurstond created 
https://github.com/llvm/llvm-project/pull/117649

This test (copied from https://github.com/llvm/llvm-project/pull/83470) 
demonstrates that UBSan does not add the nomerge annotation. This is 
significant because it results in them being merged by the backend.

N.B. https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. 
https://github.com/llvm/llvm-project/pull/101549 fixed that limitation ("It 
sets nomerge flag for the node if the instruction has nomerge arrtibute."); 
planned upcoming work will add nomerge for ubsan.

>From d85a7637f4386bc243f6f4198faf6f9cdbb49506 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:19:47 +
Subject: [PATCH] [NFC][clang] Add ubsan-trap-merge.c test to show absence of
 nomerge

This test demonstrates that UBSan does not add the nomerge annotation. This is 
significant because it results in them being merged by the backend.

N.B. https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. 
https://github.com/llvm/llvm-project/pull/101549 fixed that limitation ("It 
sets nomerge flag for the node if the instruction has nomerge arrtibute."); 
planned upcoming will add nomerge for ubsan.
---
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 1 file changed, 106 insertions(+)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..6c78fc4abf67c1
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan does not currently attach 'nomerge'.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local noundef i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local noundef i32 @g(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META5]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize 
[[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int g(int x) {
+  return x + 127;
+}
+
+// CHECK-LABEL: define dso_local noundef i32 @h(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) 
local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META5]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 2) #[[ATTR4]], !nosanitize 
[[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META5]]
+// CHECK-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-25 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 1/3] [ubsan] Change ubsan-unique-traps to use nomerge instead
 of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SAME

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-25 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/117651

>From f24a87de48c42f310ee73ecf480ea2dcf631881f Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Tue, 26 Nov 2024 00:33:09 +
Subject: [PATCH 1/2] [ubsan] Change ubsan-unique-traps to use nomerge instead
 of counter

https://github.com/llvm/llvm-project/pull/65972 (continuation of 
https://reviews.llvm.org/D148654) had considered adding nomerge to ubsantrap, 
but did not proceed with that because of 
https://github.com/llvm/llvm-project/issues/53011. Instead, it added a counter 
(based on TrapBB->getParent()->size()) to each ubsantrap call. However, this 
counter is not guaranteed to be unique after inlining, as shown by 
https://github.com/llvm/llvm-project/pull/83470, which can result in ubsantraps 
being merged by the backend.

https://github.com/llvm/llvm-project/pull/101549 fixed has since fixed the 
nomerge limitation ("It sets nomerge flag for the node if the instruction has 
nomerge arrtibute."). This patch therefore takes advantage of nomerge instead 
of using the counter, guaranteeing that the ubsantraps are not merged.

This patch is equivalent to https://github.com/llvm/llvm-project/pull/83470 but 
also adds nomerge and updates the test that was precommitted in 
https://github.com/llvm/llvm-project/pull/117649.
---
 clang/lib/CodeGen/CGExpr.cpp  |   6 +-
 clang/test/CodeGen/bounds-checking.c  |   4 +-
 clang/test/CodeGen/ubsan-trap-merge.c | 106 ++
 3 files changed, 110 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/ubsan-trap-merge.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d3f470d401b3d4..f8c1e1cd7a4d68 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3921,16 +3921,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value 
*Checked,
 
 llvm::CallInst *TrapCall = Builder.CreateCall(
 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
-llvm::ConstantInt::get(CGM.Int8Ty,
-   ClSanitizeDebugDeoptimization
-   ? TrapBB->getParent()->size()
-   : static_cast(CheckHandlerID)));
+llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
 
 if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
   auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
 CGM.getCodeGenOpts().TrapFuncName);
   TrapCall->addFnAttr(A);
 }
+TrapCall->addFnAttr(llvm::Attribute::NoMerge);
 TrapCall->setDoesNotReturn();
 TrapCall->setDoesNotThrow();
 Builder.CreateUnreachable();
diff --git a/clang/test/CodeGen/bounds-checking.c 
b/clang/test/CodeGen/bounds-checking.c
index 8100e30d0650ad..f6c4880e70a150 100644
--- a/clang/test/CodeGen/bounds-checking.c
+++ b/clang/test/CodeGen/bounds-checking.c
@@ -74,11 +74,11 @@ char B2[10];
 // CHECK-LABEL: @f8
 void f8(int i, int k) {
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B[i] = '\0';
 
   // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5)
-  // NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
+  // NOOPTARRAY: call void @llvm.ubsantrap(i8 18)
   B2[k] = '\0';
 }
 
diff --git a/clang/test/CodeGen/ubsan-trap-merge.c 
b/clang/test/CodeGen/ubsan-trap-merge.c
new file mode 100644
index 00..e6aa7902262813
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-merge.c
@@ -0,0 +1,106 @@
+// NOTE: Assertions have mostly been autogenerated by 
utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// The most important assertion is the attributes at the end of the file, which
+// shows that ubsan attaches 'nomerge' to each ubsantrap intrinsic.
+//
+// RUN: %clang -fsanitize=signed-integer-overflow -S -emit-llvm 
-fsanitize-trap=all -O3 -mllvm -ubsan-unique-traps %s -o - \
+// RUN: | FileCheck %s
+
+#include 
+#include 
+
+// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f(
+// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:[[TMP0:%.*]] = tail call { i32, i1 } 
@llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META5:![0-9]+]]
+// CHECK-NEXT:[[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, 
!nosanitize [[META5]]
+// CHECK-NEXT:br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], 
!nosanitize [[META5]]
+// CHECK:   [[TRAP]]:
+// CHECK-NEXT:tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], 
!nosanitize [[META5]]
+// CHECK-NEXT:unreachable, !nosanitize [[META5]]
+// CHECK:   [[CONT]]:
+// CHECK-NEXT:[[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, 
!nosanitize [[META5]]
+// CHECK-NEXT:ret i32 [[TMP2]]
+//
+int f(int x) {
+  return x + 125;
+}
+
+// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g(
+// CHECK-SAME

[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-25 Thread Thurston Dang via cfe-commits

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


[clang] [llvm] [ubsan] Change ubsan-unique-traps to use nomerge instead of counter (PR #117651)

2024-11-25 Thread Thurston Dang via cfe-commits

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/121619

>From ca1fabc5ea75af0acdd1969c0ad505e04103e1c9 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Sat, 4 Jan 2025 02:53:00 +
Subject: [PATCH 1/9] [sanitizer] Parse weighted sanitizer args and
 -fno-sanitize-top-hot

This adds a function to parse weighted sanitizer flags (e.g.,
-fsanitize-blah=undefined=0.5,null=0.3) and adds the plumbing to
apply that to -fno-sanitize-top-hot from the frontend to backend.

-fno-sanitize-top-hot currently has no effect; future work will
use it to generalize ubsan-guard-checks (originaly introduced in 
5f9ed2ff8364ff3e4fac410472f421299dafa793).
---
 clang/include/clang/Basic/CodeGenOptions.h |  4 ++
 clang/include/clang/Basic/Sanitizers.h | 14 +
 clang/include/clang/Driver/Options.td  |  7 +++
 clang/include/clang/Driver/SanitizerArgs.h |  1 +
 clang/lib/Basic/Sanitizers.cpp | 38 
 clang/lib/Driver/SanitizerArgs.cpp | 69 +-
 clang/lib/Frontend/CompilerInvocation.cpp  |  5 ++
 7 files changed, 124 insertions(+), 14 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 8097c9ef772bc7..f69f52e49a2fe9 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -384,6 +384,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// the expense of debuggability).
   SanitizerSet SanitizeMergeHandlers;
 
+  /// Set of top hotness thresholds, specifying the fraction of code that is
+  /// excluded from sanitization (0 = skip none, 0.1 = skip hottest 10%, 1.0 = 
skip all).
+  SanitizerMaskWeights NoSanitizeTopHot = {0};
+
   /// List of backend command-line options for -fembed-bitcode.
   std::vector CmdArgs;
 
diff --git a/clang/include/clang/Basic/Sanitizers.h 
b/clang/include/clang/Basic/Sanitizers.h
index c890242269b334..fa6b557819a1a1 100644
--- a/clang/include/clang/Basic/Sanitizers.h
+++ b/clang/include/clang/Basic/Sanitizers.h
@@ -154,6 +154,8 @@ struct SanitizerKind {
 #include "clang/Basic/Sanitizers.def"
 }; // SanitizerKind
 
+typedef double SanitizerMaskWeights[SanitizerKind::SO_Count];
+
 struct SanitizerSet {
   /// Check if a certain (single) sanitizer is enabled.
   bool has(SanitizerMask K) const {
@@ -186,10 +188,22 @@ struct SanitizerSet {
 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
 
+/// Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= 
or
+/// -fno-sanitize= value list.
+/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
+/// The relevant weight(s) are updated in the passed array.
+/// Individual weights are never reset to zero unless explicitly set
+/// (e.g., 'null=0.0').
+SanitizerMask parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, 
SanitizerMaskWeights Weights);
+
 /// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
 void serializeSanitizerSet(SanitizerSet Set,
SmallVectorImpl &Values);
 
+/// Serialize a SanitizerMaskWeights into values for -fsanitize= or 
-fno-sanitize=.
+void serializeSanitizerMaskWeights(const SanitizerMaskWeights Weights,
+   SmallVectorImpl &Values);
+
 /// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
 /// this group enables.
 SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index d922709db17786..631a6099781e6c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2649,6 +2649,13 @@ def fsanitize_undefined_strip_path_components_EQ : 
Joined<["-"], "fsanitize-unde
   HelpText<"Strip (or keep only, if negative) a given number of path 
components "
"when emitting check metadata.">,
   MarshallingInfoInt, "0", 
"int">;
+def fno_sanitize_top_hot_EQ
+: CommaJoined<["-"], "fno-sanitize-top-hot=">,
+  Group,
+  HelpText<"Skip sanitization for the fraction of top hottest code "
+   "(0.0 [default] = do not skip any sanitization; "
+   "0.1 = skip the hottest 10% of code; "
+   "1.0 = skip all sanitization)">;
 
 } // end -f[no-]sanitize* flags
 
diff --git a/clang/include/clang/Driver/SanitizerArgs.h 
b/clang/include/clang/Driver/SanitizerArgs.h
index 3b275092bbbe86..854893269e8543 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -26,6 +26,7 @@ class SanitizerArgs {
   SanitizerSet RecoverableSanitizers;
   SanitizerSet TrapSanitizers;
   SanitizerSet MergeHandlers;
+  SanitizerMaskWeights TopHot = {0};
 
   std::vector UserIgnorelistFiles;
   std::vector SystemIgnorelistFiles;
diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sa

[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -154,6 +154,8 @@ struct SanitizerKind {
 #include "clang/Basic/Sanitizers.def"
 }; // SanitizerKind
 
+typedef double SanitizerMaskWeights[SanitizerKind::SO_Count];

thurstond wrote:

Done

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -2649,6 +2649,11 @@ def fsanitize_undefined_strip_path_components_EQ : 
Joined<["-"], "fsanitize-unde
   HelpText<"Strip (or keep only, if negative) a given number of path 
components "
"when emitting check metadata.">,
   MarshallingInfoInt, "0", 
"int">;
+def fno_sanitize_top_hot_EQ
+: CommaJoined<["-"], "fno-sanitize-top-hot=">,
+  Group,
+  HelpText<"Exclude sanitization for the top hottest fraction of code "

thurstond wrote:

Done

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -2649,6 +2649,11 @@ def fsanitize_undefined_strip_path_components_EQ : 
Joined<["-"], "fsanitize-unde
   HelpText<"Strip (or keep only, if negative) a given number of path 
components "
"when emitting check metadata.">,
   MarshallingInfoInt, "0", 
"int">;
+def fno_sanitize_top_hot_EQ
+: CommaJoined<["-"], "fno-sanitize-top-hot=">,
+  Group,
+  HelpText<"Exclude sanitization for the top hottest fraction of code "

thurstond wrote:

Done

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -26,6 +26,8 @@ class SanitizerArgs {
   SanitizerSet RecoverableSanitizers;
   SanitizerSet TrapSanitizers;
   SanitizerSet MergeHandlers;
+  SanitizerSet TopHot;
+  SanitizerMaskWeights TopHotWeights = {0};

thurstond wrote:

Renamed to Cutoff - is that ok instead of CutoffThreshold?

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -3602,6 +3602,7 @@ void CodeGenFunction::EmitCheck(
   llvm::Value *RecoverableCond = nullptr;
   llvm::Value *TrapCond = nullptr;
   bool NoMerge = false;
+  bool SanitizeGuardChecks = ClSanitizeGuardChecks;

thurstond wrote:

Noted for the next patch (this patch has been updated to be Driver changes 
only).

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -3615,9 +3616,12 @@ void CodeGenFunction::EmitCheck(
 

thurstond wrote:

Done

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -154,6 +154,8 @@ struct SanitizerKind {
 #include "clang/Basic/Sanitizers.def"
 }; // SanitizerKind
 
+typedef double SanitizerMaskWeights[SanitizerKind::SO_Count];

thurstond wrote:

Done

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/121619

>From ca1fabc5ea75af0acdd1969c0ad505e04103e1c9 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Sat, 4 Jan 2025 02:53:00 +
Subject: [PATCH 1/5] [sanitizer] Parse weighted sanitizer args and
 -fno-sanitize-top-hot

This adds a function to parse weighted sanitizer flags (e.g.,
-fsanitize-blah=undefined=0.5,null=0.3) and adds the plumbing to
apply that to -fno-sanitize-top-hot from the frontend to backend.

-fno-sanitize-top-hot currently has no effect; future work will
use it to generalize ubsan-guard-checks (originaly introduced in 
5f9ed2ff8364ff3e4fac410472f421299dafa793).
---
 clang/include/clang/Basic/CodeGenOptions.h |  4 ++
 clang/include/clang/Basic/Sanitizers.h | 14 +
 clang/include/clang/Driver/Options.td  |  7 +++
 clang/include/clang/Driver/SanitizerArgs.h |  1 +
 clang/lib/Basic/Sanitizers.cpp | 38 
 clang/lib/Driver/SanitizerArgs.cpp | 69 +-
 clang/lib/Frontend/CompilerInvocation.cpp  |  5 ++
 7 files changed, 124 insertions(+), 14 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 8097c9ef772bc7..f69f52e49a2fe9 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -384,6 +384,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// the expense of debuggability).
   SanitizerSet SanitizeMergeHandlers;
 
+  /// Set of top hotness thresholds, specifying the fraction of code that is
+  /// excluded from sanitization (0 = skip none, 0.1 = skip hottest 10%, 1.0 = 
skip all).
+  SanitizerMaskWeights NoSanitizeTopHot = {0};
+
   /// List of backend command-line options for -fembed-bitcode.
   std::vector CmdArgs;
 
diff --git a/clang/include/clang/Basic/Sanitizers.h 
b/clang/include/clang/Basic/Sanitizers.h
index c890242269b334..fa6b557819a1a1 100644
--- a/clang/include/clang/Basic/Sanitizers.h
+++ b/clang/include/clang/Basic/Sanitizers.h
@@ -154,6 +154,8 @@ struct SanitizerKind {
 #include "clang/Basic/Sanitizers.def"
 }; // SanitizerKind
 
+typedef double SanitizerMaskWeights[SanitizerKind::SO_Count];
+
 struct SanitizerSet {
   /// Check if a certain (single) sanitizer is enabled.
   bool has(SanitizerMask K) const {
@@ -186,10 +188,22 @@ struct SanitizerSet {
 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
 
+/// Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= 
or
+/// -fno-sanitize= value list.
+/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
+/// The relevant weight(s) are updated in the passed array.
+/// Individual weights are never reset to zero unless explicitly set
+/// (e.g., 'null=0.0').
+SanitizerMask parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, 
SanitizerMaskWeights Weights);
+
 /// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
 void serializeSanitizerSet(SanitizerSet Set,
SmallVectorImpl &Values);
 
+/// Serialize a SanitizerMaskWeights into values for -fsanitize= or 
-fno-sanitize=.
+void serializeSanitizerMaskWeights(const SanitizerMaskWeights Weights,
+   SmallVectorImpl &Values);
+
 /// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
 /// this group enables.
 SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index d922709db17786..631a6099781e6c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2649,6 +2649,13 @@ def fsanitize_undefined_strip_path_components_EQ : 
Joined<["-"], "fsanitize-unde
   HelpText<"Strip (or keep only, if negative) a given number of path 
components "
"when emitting check metadata.">,
   MarshallingInfoInt, "0", 
"int">;
+def fno_sanitize_top_hot_EQ
+: CommaJoined<["-"], "fno-sanitize-top-hot=">,
+  Group,
+  HelpText<"Skip sanitization for the fraction of top hottest code "
+   "(0.0 [default] = do not skip any sanitization; "
+   "0.1 = skip the hottest 10% of code; "
+   "1.0 = skip all sanitization)">;
 
 } // end -f[no-]sanitize* flags
 
diff --git a/clang/include/clang/Driver/SanitizerArgs.h 
b/clang/include/clang/Driver/SanitizerArgs.h
index 3b275092bbbe86..854893269e8543 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -26,6 +26,7 @@ class SanitizerArgs {
   SanitizerSet RecoverableSanitizers;
   SanitizerSet TrapSanitizers;
   SanitizerSet MergeHandlers;
+  SanitizerMaskWeights TopHot = {0};
 
   std::vector UserIgnorelistFiles;
   std::vector SystemIgnorelistFiles;
diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sa

[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/121619

>From ca1fabc5ea75af0acdd1969c0ad505e04103e1c9 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Sat, 4 Jan 2025 02:53:00 +
Subject: [PATCH 1/3] [sanitizer] Parse weighted sanitizer args and
 -fno-sanitize-top-hot

This adds a function to parse weighted sanitizer flags (e.g.,
-fsanitize-blah=undefined=0.5,null=0.3) and adds the plumbing to
apply that to -fno-sanitize-top-hot from the frontend to backend.

-fno-sanitize-top-hot currently has no effect; future work will
use it to generalize ubsan-guard-checks (originaly introduced in 
5f9ed2ff8364ff3e4fac410472f421299dafa793).
---
 clang/include/clang/Basic/CodeGenOptions.h |  4 ++
 clang/include/clang/Basic/Sanitizers.h | 14 +
 clang/include/clang/Driver/Options.td  |  7 +++
 clang/include/clang/Driver/SanitizerArgs.h |  1 +
 clang/lib/Basic/Sanitizers.cpp | 38 
 clang/lib/Driver/SanitizerArgs.cpp | 69 +-
 clang/lib/Frontend/CompilerInvocation.cpp  |  5 ++
 7 files changed, 124 insertions(+), 14 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 8097c9ef772bc7..f69f52e49a2fe9 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -384,6 +384,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// the expense of debuggability).
   SanitizerSet SanitizeMergeHandlers;
 
+  /// Set of top hotness thresholds, specifying the fraction of code that is
+  /// excluded from sanitization (0 = skip none, 0.1 = skip hottest 10%, 1.0 = 
skip all).
+  SanitizerMaskWeights NoSanitizeTopHot = {0};
+
   /// List of backend command-line options for -fembed-bitcode.
   std::vector CmdArgs;
 
diff --git a/clang/include/clang/Basic/Sanitizers.h 
b/clang/include/clang/Basic/Sanitizers.h
index c890242269b334..fa6b557819a1a1 100644
--- a/clang/include/clang/Basic/Sanitizers.h
+++ b/clang/include/clang/Basic/Sanitizers.h
@@ -154,6 +154,8 @@ struct SanitizerKind {
 #include "clang/Basic/Sanitizers.def"
 }; // SanitizerKind
 
+typedef double SanitizerMaskWeights[SanitizerKind::SO_Count];
+
 struct SanitizerSet {
   /// Check if a certain (single) sanitizer is enabled.
   bool has(SanitizerMask K) const {
@@ -186,10 +188,22 @@ struct SanitizerSet {
 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
 
+/// Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= 
or
+/// -fno-sanitize= value list.
+/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
+/// The relevant weight(s) are updated in the passed array.
+/// Individual weights are never reset to zero unless explicitly set
+/// (e.g., 'null=0.0').
+SanitizerMask parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, 
SanitizerMaskWeights Weights);
+
 /// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
 void serializeSanitizerSet(SanitizerSet Set,
SmallVectorImpl &Values);
 
+/// Serialize a SanitizerMaskWeights into values for -fsanitize= or 
-fno-sanitize=.
+void serializeSanitizerMaskWeights(const SanitizerMaskWeights Weights,
+   SmallVectorImpl &Values);
+
 /// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
 /// this group enables.
 SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index d922709db17786..631a6099781e6c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2649,6 +2649,13 @@ def fsanitize_undefined_strip_path_components_EQ : 
Joined<["-"], "fsanitize-unde
   HelpText<"Strip (or keep only, if negative) a given number of path 
components "
"when emitting check metadata.">,
   MarshallingInfoInt, "0", 
"int">;
+def fno_sanitize_top_hot_EQ
+: CommaJoined<["-"], "fno-sanitize-top-hot=">,
+  Group,
+  HelpText<"Skip sanitization for the fraction of top hottest code "
+   "(0.0 [default] = do not skip any sanitization; "
+   "0.1 = skip the hottest 10% of code; "
+   "1.0 = skip all sanitization)">;
 
 } // end -f[no-]sanitize* flags
 
diff --git a/clang/include/clang/Driver/SanitizerArgs.h 
b/clang/include/clang/Driver/SanitizerArgs.h
index 3b275092bbbe86..854893269e8543 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -26,6 +26,7 @@ class SanitizerArgs {
   SanitizerSet RecoverableSanitizers;
   SanitizerSet TrapSanitizers;
   SanitizerSet MergeHandlers;
+  SanitizerMaskWeights TopHot = {0};
 
   std::vector UserIgnorelistFiles;
   std::vector SystemIgnorelistFiles;
diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sa

[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits

https://github.com/thurstond updated 
https://github.com/llvm/llvm-project/pull/121619

>From ca1fabc5ea75af0acdd1969c0ad505e04103e1c9 Mon Sep 17 00:00:00 2001
From: Thurston Dang 
Date: Sat, 4 Jan 2025 02:53:00 +
Subject: [PATCH 1/4] [sanitizer] Parse weighted sanitizer args and
 -fno-sanitize-top-hot

This adds a function to parse weighted sanitizer flags (e.g.,
-fsanitize-blah=undefined=0.5,null=0.3) and adds the plumbing to
apply that to -fno-sanitize-top-hot from the frontend to backend.

-fno-sanitize-top-hot currently has no effect; future work will
use it to generalize ubsan-guard-checks (originaly introduced in 
5f9ed2ff8364ff3e4fac410472f421299dafa793).
---
 clang/include/clang/Basic/CodeGenOptions.h |  4 ++
 clang/include/clang/Basic/Sanitizers.h | 14 +
 clang/include/clang/Driver/Options.td  |  7 +++
 clang/include/clang/Driver/SanitizerArgs.h |  1 +
 clang/lib/Basic/Sanitizers.cpp | 38 
 clang/lib/Driver/SanitizerArgs.cpp | 69 +-
 clang/lib/Frontend/CompilerInvocation.cpp  |  5 ++
 7 files changed, 124 insertions(+), 14 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 8097c9ef772bc7..f69f52e49a2fe9 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -384,6 +384,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// the expense of debuggability).
   SanitizerSet SanitizeMergeHandlers;
 
+  /// Set of top hotness thresholds, specifying the fraction of code that is
+  /// excluded from sanitization (0 = skip none, 0.1 = skip hottest 10%, 1.0 = 
skip all).
+  SanitizerMaskWeights NoSanitizeTopHot = {0};
+
   /// List of backend command-line options for -fembed-bitcode.
   std::vector CmdArgs;
 
diff --git a/clang/include/clang/Basic/Sanitizers.h 
b/clang/include/clang/Basic/Sanitizers.h
index c890242269b334..fa6b557819a1a1 100644
--- a/clang/include/clang/Basic/Sanitizers.h
+++ b/clang/include/clang/Basic/Sanitizers.h
@@ -154,6 +154,8 @@ struct SanitizerKind {
 #include "clang/Basic/Sanitizers.def"
 }; // SanitizerKind
 
+typedef double SanitizerMaskWeights[SanitizerKind::SO_Count];
+
 struct SanitizerSet {
   /// Check if a certain (single) sanitizer is enabled.
   bool has(SanitizerMask K) const {
@@ -186,10 +188,22 @@ struct SanitizerSet {
 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
 
+/// Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= 
or
+/// -fno-sanitize= value list.
+/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
+/// The relevant weight(s) are updated in the passed array.
+/// Individual weights are never reset to zero unless explicitly set
+/// (e.g., 'null=0.0').
+SanitizerMask parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, 
SanitizerMaskWeights Weights);
+
 /// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
 void serializeSanitizerSet(SanitizerSet Set,
SmallVectorImpl &Values);
 
+/// Serialize a SanitizerMaskWeights into values for -fsanitize= or 
-fno-sanitize=.
+void serializeSanitizerMaskWeights(const SanitizerMaskWeights Weights,
+   SmallVectorImpl &Values);
+
 /// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
 /// this group enables.
 SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index d922709db17786..631a6099781e6c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2649,6 +2649,13 @@ def fsanitize_undefined_strip_path_components_EQ : 
Joined<["-"], "fsanitize-unde
   HelpText<"Strip (or keep only, if negative) a given number of path 
components "
"when emitting check metadata.">,
   MarshallingInfoInt, "0", 
"int">;
+def fno_sanitize_top_hot_EQ
+: CommaJoined<["-"], "fno-sanitize-top-hot=">,
+  Group,
+  HelpText<"Skip sanitization for the fraction of top hottest code "
+   "(0.0 [default] = do not skip any sanitization; "
+   "0.1 = skip the hottest 10% of code; "
+   "1.0 = skip all sanitization)">;
 
 } // end -f[no-]sanitize* flags
 
diff --git a/clang/include/clang/Driver/SanitizerArgs.h 
b/clang/include/clang/Driver/SanitizerArgs.h
index 3b275092bbbe86..854893269e8543 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -26,6 +26,7 @@ class SanitizerArgs {
   SanitizerSet RecoverableSanitizers;
   SanitizerSet TrapSanitizers;
   SanitizerSet MergeHandlers;
+  SanitizerMaskWeights TopHot = {0};
 
   std::vector UserIgnorelistFiles;
   std::vector SystemIgnorelistFiles;
diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sa

[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-06 Thread Thurston Dang via cfe-commits


@@ -3615,9 +3616,12 @@ void CodeGenFunction::EmitCheck(
 
 if (!CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Checked[i].second))
   NoMerge = true;
+
+if (!CGM.getCodeGenOpts().NoSanitizeTopHot.has(Checked[i].second))
+  SanitizeGuardChecks = true;
   }
 
-  if (ClSanitizeGuardChecks) {
+  if (SanitizeGuardChecks) {
 llvm::Value *Allow =
 
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check),
llvm::ConstantInt::get(CGM.Int8Ty, CheckHandler));

thurstond wrote:

Instead of passing CheckHandler, can I pass the sanitizer cutoff threshold 
instead?

Something like
```
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check),
   llvm::ConstantInt::get(CGM.Int8Ty, 
NoSanitizeTopHot[someIndex]));
```

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-07 Thread Thurston Dang via cfe-commits


@@ -46,26 +47,20 @@ bool clang::parseSanitizerWeightedValue(StringRef Value, 
bool AllowGroups,
 #include "clang/Basic/Sanitizers.def"
  .Default(SanitizerMask());
 
-  if (ParsedKind) {
-size_t equalsIndex = Value.find_first_of('=');
-if (equalsIndex != llvm::StringLiteral::npos) {
-  double arg;
-  if ((Value.size() > (equalsIndex + 1)) &&
-  !Value.substr(equalsIndex + 1).getAsDouble(arg)) {
-// AllowGroups is already taken into account for ParsedKind,
-// hence we unconditionally expandSanitizerGroups.
-SanitizerMask ExpandedKind = expandSanitizerGroups(ParsedKind);
-
-for (unsigned int i = 0; i < SanitizerKind::SO_Count; i++)
-  if (ExpandedKind & SanitizerMask::bitPosToMask(i))
-Cutoffs[i] = arg;
-
-return true;
-  }
-}
-  }
-
-  return false;
+  if (!ParsedKind)

thurstond wrote:

Thanks, the tests pass! Should the clamping be moved to 
`parseNoSanitizeHotArgs`? Hypothetically there could be some future flag, 
`-fsanitize-something-else=undefined=42,null=56` that could reuse 
`parseSanitizerWeightedValue` if clamping were not applied in 
`parseSanitizerWeightedValue`.

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-07 Thread Thurston Dang via cfe-commits


@@ -186,10 +188,24 @@ struct SanitizerSet {
 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
 
+/// Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= 
or
+/// -fno-sanitize= value list.
+/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
+/// The relevant weight(s) are updated in the passed array.
+/// Individual Cutoffs are never reset to zero unless explicitly set
+/// (e.g., 'null=0.0').
+SanitizerMask parseSanitizerWeightedValue(StringRef Value, bool AllowGroups,

thurstond wrote:

Done

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-07 Thread Thurston Dang via cfe-commits


@@ -1436,6 +1436,19 @@ static SmallVector 
serializeSanitizerKinds(SanitizerSet S) {
   return Values;
 }
 
+static void parseSanitizerWeightedKinds(
+StringRef FlagName, const std::vector &Sanitizers,
+DiagnosticsEngine &Diags, SanitizerSet &S, SanitizerMaskCutoffs *Cutoffs) {

thurstond wrote:

Done

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-07 Thread Thurston Dang via cfe-commits


@@ -154,6 +154,8 @@ struct SanitizerKind {
 #include "clang/Basic/Sanitizers.def"
 }; // SanitizerKind
 
+using SanitizerMaskCutoffs = std::array;

thurstond wrote:

Like this? 
https://github.com/llvm/llvm-project/pull/121619/commits/56ba349e7f085fca3bfd531ea219b1d9e8ef177c

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


[clang] [sanitizer] Parse weighted sanitizer args and -fno-sanitize-top-hot (PR #121619)

2025-01-07 Thread Thurston Dang via cfe-commits


@@ -1154,3 +1154,58 @@
 
 // RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,undefined  %s 
-### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-UBSAN
 // CHECK-REALTIME-UBSAN: error: invalid argument '-fsanitize=realtime' not 
allowed with '-fsanitize=undefined'
+
+
+// * Test -fno-sanitize-top-hot *
+
+// -fno-sanitize-top-hot=undefined=0.5
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined 
-fno-sanitize-top-hot=undefined=0.5 %s -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-TOP-HOT1
+// CHECK-TOP-HOT1: 
"-fno-sanitize-top-hot={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr)=0.5(0*),?){19}"}}
+
+// No-op: no sanitizers are specified
+// RUN: %clang --target=x86_64-linux-gnu -fno-sanitize-top-hot=undefined=0.5 
%s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TOP-HOT2
+// CHECK-TOP-HOT2-NOT: "-fsanitize"
+// CHECK-TOP-HOT2-NOT: "-fno-sanitize-top-hot"
+
+// Enable undefined, then cancel out integer using a cutoff of 0.0
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined 
-fno-sanitize-top-hot=undefined=0.5,integer=0.0 %s -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-TOP-HOT3
+// CHECK-TOP-HOT3: 
"-fno-sanitize-top-hot={{((unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr)=0.5(0*),?){15}"}}
+
+// Enable undefined, then cancel out integer using a cutoff of 0.0, then 
re-enable signed-integer-overflow
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined 
-fno-sanitize-top-hot=undefined=0.5,integer=0.0,signed-integer-overflow=0.7 %s 
-### 2>&1 | FileCheck %s --check-prefix=CHECK-TOP-HOT4
+// CHECK-TOP-HOT4: 
"-fno-sanitize-top-hot={{((signed-integer-overflow|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr)=(0.5|0.49|0.7|0.69)([0-9]*),?){16}"}}
+
+// Check that -fno-sanitize-top-hot=undefined=0.4 does not widen the set of 
-fsanitize=integer checks.
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=integer 
-fno-sanitize-top-hot=undefined=0.4 %s -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-TOP-HOT5
+// CHECK-TOP-HOT5: 
"-fno-sanitize-top-hot={{((integer-divide-by-zero|shift-base|shift-exponent|signed-integer-overflow)=(0.4|0.39)([0-9]*),?){4}"}}
+
+// No-op: it's allowed for the user to specify a cutoff of 0.0, though the 
argument is not passed along by the driver.
+// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined 
-fno-sanitize-top-hot=undefined=0.0 %s -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-TOP-HOT6
+// CHECK-TOP-HOT6: 
"-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr),?){19}"}}
+// CHECK-TOP-HOT6-NOT: unsupported argument
+// CHECK-TOP-HOT6-NOT: "-fno-sanitize-top-hot"
+
+// Invalid: bad sanitizer
+// RUN: not %clang --target=x86_64-linux-gnu -fno-sanitize-top-hot=pot=0.0 %s 
-### 2>&1 | FileCheck %s --check-prefix=CHECK-TOP-HOT7
+// CHECK-TOP-HOT7: unsupported argument 'pot=0.0' to option 
'-fno-sanitize-top-hot='
+
+// Invalid: bad cutoff
+// RUN: not %clang --target=x86_64-linux-gnu 
-fno-sanitize-top-hot=undefined=xyzzy %s -### 2>&1 | FileCheck %s 
--check-prefix=CHECK-TOP-HOT8
+// CHECK-TOP-HOT8: unsupported argument 'undefined=xyzzy' to option 
'-fno-sanitize-top-hot='
+
+// Invalid: -fno-sanitize-top without parameters
+// RUN: not %clang --target=x86_64-linux-gnu -fno-sanitize-top-hot %s -### 
2>&1 | FileCheck %s --check-prefix=CHECK-TOP-HOT9
+// CHECK-TOP-HOT9: unknown argument: '-fno-sanitize-top-hot'
+
+// Invalid: -fno-sanitize-top=undefined without cutoff
+// RUN: not %clang --target=x86_64-linux-gnu -fno-sanitize-top-hot=undefined 
%s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TOP-HOT10
+// CHECK-TOP-HOT10: unsupported argument 'undefined' to option 
'-fno-sanitize-top-hot='
+
+// Invalid: -fno-sanitize-top=undefined= without cutoff
+// RUN: not %clang --target=x86_64-linux-gnu -fno-sanitize-top-hot=undefined= 
%s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TOP-HOT11
+// CHECK-TOP-HOT11: unsupported argument 'undefined=' to option 
'-fno-sanitize-top-hot='
+
+// No-op: -fno-sanitize-top= without parameters is unusual but valid
+// RUN: %clang --target=x86_64-linux-gnu -fno-sanitize-top-hot= %s -### 2>&1 | 
FileCheck %s --check-prefix=CHECK-TOP-HOT12
+// CHECK-TOP-HOT12-NOT: unsupported argument

thurstond wrote:

Good idea! Done in d3fa04dbe6622878e7747f21ad036799e0af5e5a

`-Werror` helped reveal there was a bug (arguments weren't claimed; 

  1   2   3   >