[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `sanitizer-x86_64-linux-android` running on `sanitizer-buildbot-android` while building `clang` at step 2 "annotate". Full details are available at: https://lab.llvm.org/buildbot/#/builders/186/builds/8072 Here is the relevant piece of the build log for the reference ``` Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure) ... PASS: SanitizerCommon-asan-arm-Android :: wcrtomb.c (1112 of 1572) PASS: SanitizerCommon-asan-arm-Android :: wcslen_test.c (1113 of 1572) PASS: SanitizerCommon-asan-arm-Android :: wctomb.c (1114 of 1572) PASS: SanitizerCommon-asan-arm-Android :: symbolize_pc_demangle.cpp (1115 of 1572) PASS: SanitizerCommon-asan-arm-Android :: compress_stack_depot.cpp (1116 of 1572) PASS: UBSan-AddressSanitizer-arm :: TestCases/ImplicitConversion/integer-sign-change-summary.cpp (1117 of 1572) PASS: SanitizerCommon-asan-arm-Android :: hard_rss_limit_mb_test.cpp (1118 of 1572) PASS: SanitizerCommon-asan-arm-Android :: max_allocation_size.cpp (1119 of 1572) PASS: SanitizerCommon-asan-arm-Android :: symbolize_stack.cpp (1120 of 1572) PASS: UBSan-AddressSanitizer-arm :: TestCases/Float/cast-overflow.cpp (1121 of 1572) FAIL: UBSan-AddressSanitizer-arm :: TestCases/ImplicitConversion/bitfield-conversion.c (1122 of 1572) TEST 'UBSan-AddressSanitizer-arm :: TestCases/ImplicitConversion/bitfield-conversion.c' FAILED Exit Code: 1 Command Output (stderr): -- /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/sanitizer_common/android_commands/android_compile.py /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/bin/clang -fsanitize=address --target=armv7-linux-androideabi24 --sysroot=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --gcc-toolchain=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -B/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta -fuse-ld=lld -x c -fsanitize=implicit-bitfield-conversion -O0 /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/ubsan/TestCases/ImplicitConversion/bitfield-conversion.c -o /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_arm/test/ubsan/AddressSanitizer-arm/TestCases/ImplicitConversion/Output/bitfield-conversion.c.tmp && /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_arm/test/ubsan/AddressSanitizer-arm/TestCases/ImplicitConversion/Output/bitfield-conversion.c.tmp 2>&1 | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/ubsan/TestCases/ImplicitConversion/bitfield-conversion.c --check-prefixes=CHECK # RUN: at line 1 + /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/sanitizer_common/android_commands/android_compile.py /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/bin/clang -fsanitize=address --target=armv7-linux-androideabi24 --sysroot=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --gcc-toolchain=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -B/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta -fuse-ld=lld -x c -fsanitize=implicit-bitfield-conversion -O0 /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/ubsan/TestCases/ImplicitConversion/bitfield-conversion.c -o /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_arm/test/ubsan/AddressSanitizer-arm/TestCases/ImplicitConversion/Output/bitfield-conversion.c.tmp + /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_arm/test/ubsan/AddressSanitizer-arm/TestCases/ImplicitConversion/Output/bitfield-conversion.c.tmp + FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/ubsan/TestCases/ImplicitConversion/bitfield-conversion.c --check-prefixes=CHECK /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/sanitizer_common/androi
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw closed https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
dtcxzyw wrote: > willreturn means we eliminate the call The ubsan handler cannot be eliminated because `inaccessiblemem: readwrite` indicates that it has externally observable side effects. BTW, I just worry that some risky instructions (e.g., divided by zero) may be moved before the handler. https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw updated
https://github.com/llvm/llvm-project/pull/130990
>From 48f8e2591c317f90eff6f1d0a4ecdf27e19a1b01 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng
Date: Thu, 13 Mar 2025 00:39:09 +0800
Subject: [PATCH 1/5] [Clang][CodeGen][UBSan] Add pre-commit tests. NFC.
---
clang/test/CodeGen/ubsan-attr.cpp | 84 +++
1 file changed, 84 insertions(+)
create mode 100644 clang/test/CodeGen/ubsan-attr.cpp
diff --git a/clang/test/CodeGen/ubsan-attr.cpp
b/clang/test/CodeGen/ubsan-attr.cpp
new file mode 100644
index 0..e0a8570154939
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-attr.cpp
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
UTC_ARGS: --check-attributes --check-globals all --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o -
-fsanitize-recover=signed-integer-overflow | FileCheck %s
--check-prefixes=RECOVER
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o - | FileCheck %s
--check-prefixes=ABORT
+
+// RECOVER: Function Attrs: mustprogress nounwind
+// RECOVER-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// RECOVER-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// RECOVER-NEXT: [[ENTRY:.*]]:
+// RECOVER-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// RECOVER-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// RECOVER-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// RECOVER-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// RECOVER-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// RECOVER-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// RECOVER: [[HANDLER_ADD_OVERFLOW]]:
+// RECOVER-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:tail call void @__ubsan_handle_add_overflow(ptr nonnull
@[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize [[META8]]
+// RECOVER-NEXT:[[DOTPRE:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2]]
+// RECOVER-NEXT:[[DOTPRE3:%.*]] = sext i16 [[DOTPRE]] to i32
+// RECOVER-NEXT:br label %[[CONT]], !nosanitize [[META8]]
+// RECOVER: [[CONT]]:
+// RECOVER-NEXT:[[CONV1_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE3]],
%[[HANDLER_ADD_OVERFLOW]] ], [ [[CONV]], %[[ENTRY]] ]
+// RECOVER-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// RECOVER-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// RECOVER-NEXT:ret i32 [[CONV1_PRE_PHI]]
+//
+// ABORT: Function Attrs: mustprogress nounwind
+// ABORT-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// ABORT-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// ABORT-NEXT: [[ENTRY:.*:]]
+// ABORT-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// ABORT-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// ABORT-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// ABORT-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// ABORT-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// ABORT-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// ABORT: [[HANDLER_ADD_OVERFLOW]]:
+// ABORT-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:tail call void @__ubsan_handle_add_overflow_abort(ptr
nonnull @[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize
[[META8]]
+// ABORT-NEXT:unreachable, !nosanitize [[META8]]
+// ABORT: [[CONT]]:
+// ABORT-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// ABORT-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// ABORT-NEXT:ret i32 [[CONV]]
+//
+int test(int &a, short &c) {
+ a += c;
+ return c;
+}
+//.
+// RECOVER: attributes #[[ATTR0]] = { mustprogress nounwind
"min-legal-vector-width"="0" "no-trapping-math"="true"
"stack-protector-buffer-size"="8" "tar
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
efriedma-quic wrote:
> The ubsan handler cannot be eliminated because inaccessiblemem: readwrite
> indicates that it has externally observable side effects.
That is not how things work. For example:
```
$ echo "declare void @g() define void @f() nounwind { call void @g()
memory(argmem: read, inaccessiblemem: readwrite) willreturn unreachable }" |
opt -O3 -S
; ModuleID = ''
source_filename = ""
; Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind
willreturn memory(none)
define void @f() local_unnamed_addr #0 {
unreachable
}
attributes #0 = { mustprogress nofree norecurse noreturn nosync nounwind
willreturn memory(none) }
```
https://github.com/llvm/llvm-project/pull/130990
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/efriedma-quic approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
dtcxzyw wrote:
> > The ubsan handler cannot be eliminated because inaccessiblemem: readwrite
> > indicates that it has externally observable side effects.
>
> That is not how things work. For example:
>
> ```
> $ echo "declare void @g() define void @f() nounwind { call void @g()
> memory(argmem: read, inaccessiblemem: readwrite) willreturn unreachable }" |
> opt -O3 -S
> ; ModuleID = ''
> source_filename = ""
>
> ; Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind
> willreturn memory(none)
> define void @f() local_unnamed_addr #0 {
> unreachable
> }
>
> attributes #0 = { mustprogress nofree norecurse noreturn nosync nounwind
> willreturn memory(none) }
> ```
Fixed. Now it sets `mustprogress`.
https://github.com/llvm/llvm-project/pull/130990
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw updated
https://github.com/llvm/llvm-project/pull/130990
>From 48f8e2591c317f90eff6f1d0a4ecdf27e19a1b01 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng
Date: Thu, 13 Mar 2025 00:39:09 +0800
Subject: [PATCH 1/4] [Clang][CodeGen][UBSan] Add pre-commit tests. NFC.
---
clang/test/CodeGen/ubsan-attr.cpp | 84 +++
1 file changed, 84 insertions(+)
create mode 100644 clang/test/CodeGen/ubsan-attr.cpp
diff --git a/clang/test/CodeGen/ubsan-attr.cpp
b/clang/test/CodeGen/ubsan-attr.cpp
new file mode 100644
index 0..e0a8570154939
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-attr.cpp
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
UTC_ARGS: --check-attributes --check-globals all --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o -
-fsanitize-recover=signed-integer-overflow | FileCheck %s
--check-prefixes=RECOVER
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o - | FileCheck %s
--check-prefixes=ABORT
+
+// RECOVER: Function Attrs: mustprogress nounwind
+// RECOVER-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// RECOVER-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// RECOVER-NEXT: [[ENTRY:.*]]:
+// RECOVER-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// RECOVER-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// RECOVER-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// RECOVER-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// RECOVER-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// RECOVER-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// RECOVER: [[HANDLER_ADD_OVERFLOW]]:
+// RECOVER-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:tail call void @__ubsan_handle_add_overflow(ptr nonnull
@[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize [[META8]]
+// RECOVER-NEXT:[[DOTPRE:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2]]
+// RECOVER-NEXT:[[DOTPRE3:%.*]] = sext i16 [[DOTPRE]] to i32
+// RECOVER-NEXT:br label %[[CONT]], !nosanitize [[META8]]
+// RECOVER: [[CONT]]:
+// RECOVER-NEXT:[[CONV1_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE3]],
%[[HANDLER_ADD_OVERFLOW]] ], [ [[CONV]], %[[ENTRY]] ]
+// RECOVER-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// RECOVER-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// RECOVER-NEXT:ret i32 [[CONV1_PRE_PHI]]
+//
+// ABORT: Function Attrs: mustprogress nounwind
+// ABORT-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// ABORT-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// ABORT-NEXT: [[ENTRY:.*:]]
+// ABORT-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// ABORT-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// ABORT-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// ABORT-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// ABORT-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// ABORT-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// ABORT: [[HANDLER_ADD_OVERFLOW]]:
+// ABORT-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:tail call void @__ubsan_handle_add_overflow_abort(ptr
nonnull @[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize
[[META8]]
+// ABORT-NEXT:unreachable, !nosanitize [[META8]]
+// ABORT: [[CONT]]:
+// ABORT-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// ABORT-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// ABORT-NEXT:ret i32 [[CONV]]
+//
+int test(int &a, short &c) {
+ a += c;
+ return c;
+}
+//.
+// RECOVER: attributes #[[ATTR0]] = { mustprogress nounwind
"min-legal-vector-width"="0" "no-trapping-math"="true"
"stack-protector-buffer-size"="8" "tar
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw updated
https://github.com/llvm/llvm-project/pull/130990
>From 48f8e2591c317f90eff6f1d0a4ecdf27e19a1b01 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng
Date: Thu, 13 Mar 2025 00:39:09 +0800
Subject: [PATCH 1/3] [Clang][CodeGen][UBSan] Add pre-commit tests. NFC.
---
clang/test/CodeGen/ubsan-attr.cpp | 84 +++
1 file changed, 84 insertions(+)
create mode 100644 clang/test/CodeGen/ubsan-attr.cpp
diff --git a/clang/test/CodeGen/ubsan-attr.cpp
b/clang/test/CodeGen/ubsan-attr.cpp
new file mode 100644
index 0..e0a8570154939
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-attr.cpp
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
UTC_ARGS: --check-attributes --check-globals all --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o -
-fsanitize-recover=signed-integer-overflow | FileCheck %s
--check-prefixes=RECOVER
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o - | FileCheck %s
--check-prefixes=ABORT
+
+// RECOVER: Function Attrs: mustprogress nounwind
+// RECOVER-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// RECOVER-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// RECOVER-NEXT: [[ENTRY:.*]]:
+// RECOVER-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// RECOVER-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// RECOVER-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// RECOVER-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// RECOVER-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// RECOVER-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// RECOVER: [[HANDLER_ADD_OVERFLOW]]:
+// RECOVER-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:tail call void @__ubsan_handle_add_overflow(ptr nonnull
@[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize [[META8]]
+// RECOVER-NEXT:[[DOTPRE:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2]]
+// RECOVER-NEXT:[[DOTPRE3:%.*]] = sext i16 [[DOTPRE]] to i32
+// RECOVER-NEXT:br label %[[CONT]], !nosanitize [[META8]]
+// RECOVER: [[CONT]]:
+// RECOVER-NEXT:[[CONV1_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE3]],
%[[HANDLER_ADD_OVERFLOW]] ], [ [[CONV]], %[[ENTRY]] ]
+// RECOVER-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// RECOVER-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// RECOVER-NEXT:ret i32 [[CONV1_PRE_PHI]]
+//
+// ABORT: Function Attrs: mustprogress nounwind
+// ABORT-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// ABORT-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// ABORT-NEXT: [[ENTRY:.*:]]
+// ABORT-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// ABORT-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// ABORT-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// ABORT-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// ABORT-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// ABORT-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// ABORT: [[HANDLER_ADD_OVERFLOW]]:
+// ABORT-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:tail call void @__ubsan_handle_add_overflow_abort(ptr
nonnull @[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize
[[META8]]
+// ABORT-NEXT:unreachable, !nosanitize [[META8]]
+// ABORT: [[CONT]]:
+// ABORT-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// ABORT-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// ABORT-NEXT:ret i32 [[CONV]]
+//
+int test(int &a, short &c) {
+ a += c;
+ return c;
+}
+//.
+// RECOVER: attributes #[[ATTR0]] = { mustprogress nounwind
"min-legal-vector-width"="0" "no-trapping-math"="true"
"stack-protector-buffer-size"="8" "tar
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
llvmbot wrote:
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-clang
Author: Yingwei Zheng (dtcxzyw)
Changes
This patch adds `memory(argmem: read, inaccessiblemem: readwrite) willreturn`
to **recoverable** ubsan handlers in order to unblock some memory/loop
optimizations. It provides an average of 3% performance improvement on
llvm-test-suite (except for 49 test failures due to ubsan diagnostics).
Closes https://github.com/llvm/llvm-project/issues/130093.
---
Patch is 88.19 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/130990.diff
4 Files Affected:
- (modified) clang/lib/CodeGen/CGExpr.cpp (+11)
- (modified) clang/test/CodeGen/allow-ubsan-check.c (+14-14)
- (modified) clang/test/CodeGen/attr-counted-by.c (+116-116)
- (added) clang/test/CodeGen/ubsan-attr.cpp (+81)
``diff
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 5943ff9294e1a..6db043d884c3d 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3617,6 +3617,17 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
.addAttribute(llvm::Attribute::NoUnwind);
}
B.addUWTableAttr(llvm::UWTableKind::Default);
+ // Add more precise attributes to recoverable ubsan handlers for better
+ // optimizations.
+ if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && MayReturn) {
+// __ubsan_handle_dynamic_type_cache_miss reads the vtable, which is also
+// accessible by the current module.
+if (CheckHandler != SanitizerHandler::DynamicTypeCacheMiss)
+ B.addMemoryAttr(llvm::MemoryEffects::argMemOnly(llvm::ModRefInfo::Ref) |
+ llvm::MemoryEffects::inaccessibleMemOnly());
+// If the handler does not return, we must hit a undefined behavior.
+B.addAttribute(llvm::Attribute::WillReturn);
+ }
llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(
FnType, FnName,
diff --git a/clang/test/CodeGen/allow-ubsan-check.c
b/clang/test/CodeGen/allow-ubsan-check.c
index c116604288546..59d03e123a1a6 100644
--- a/clang/test/CodeGen/allow-ubsan-check.c
+++ b/clang/test/CodeGen/allow-ubsan-check.c
@@ -29,7 +29,7 @@
// CHECK: [[HANDLER_DIVREM_OVERFLOW]]:
// CHECK-NEXT:[[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]]
// CHECK-NEXT:[[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]]
-// CHECK-NEXT:tail call void @__ubsan_handle_divrem_overflow_abort(ptr
nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]],
!nosanitize [[META2]]
+// CHECK-NEXT:tail call void @__ubsan_handle_divrem_overflow_abort(ptr
nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR8:[0-9]+]],
!nosanitize [[META2]]
// CHECK-NEXT:unreachable, !nosanitize [[META2]]
// CHECK: [[CONT]]:
// CHECK-NEXT:[[DIV:%.*]] = sdiv i32 [[X]], [[Y]]
@@ -75,7 +75,7 @@
// REC: [[HANDLER_DIVREM_OVERFLOW]]:
// REC-NEXT:[[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]]
// REC-NEXT:[[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]]
-// REC-NEXT:tail call void @__ubsan_handle_divrem_overflow(ptr nonnull
@[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]], !nosanitize
[[META2]]
+// REC-NEXT:tail call void @__ubsan_handle_divrem_overflow(ptr nonnull
@[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR8:[0-9]+]], !nosanitize
[[META2]]
// REC-NEXT:br label %[[CONT]], !nosanitize [[META2]]
// REC: [[CONT]]:
// REC-NEXT:[[DIV:%.*]] = sdiv i32 [[X]], [[Y]]
@@ -86,7 +86,7 @@ int div(int x, int y) {
}
// CHECK-LABEL: define dso_local i32 @null(
-// CHECK-SAME: ptr noundef readonly captures(address_is_null) [[X:%.*]])
local_unnamed_addr #[[ATTR0]] {
+// CHECK-SAME: ptr noundef readonly captures(address_is_null) [[X:%.*]])
local_unnamed_addr #[[ATTR3:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT:[[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META2]]
//
@@ -95,7 +95,7 @@ int div(int x, int y) {
// CHECK-NEXT:[[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]]
// CHECK-NEXT:br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]],
label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]]
// CHECK: [[HANDLER_TYPE_MISMATCH]]:
-// CHECK-NEXT:tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr
nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META2]]
+// CHECK-NEXT:tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr
nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META2]]
// CHECK-NEXT:unreachable, !nosanitize [[META2]]
// CHECK: [[CONT]]:
// CHECK-NEXT:[[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa
[[TBAA5:![0-9]+]]
@@ -116,14 +116,14 @@ int div(int x, int y) {
// TR-NEXT:ret i32 [[TMP2]]
//
// REC-LABEL: define dso_local i32 @null(
-// REC-SAME: ptr noundef readonly captures(address_is_null) [[X:%.*]])
local_unnamed_addr #[[ATTR0]] {
+// R
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw ready_for_review https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw edited https://github.com/llvm/llvm-project/pull/130990 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw updated
https://github.com/llvm/llvm-project/pull/130990
>From ea0d82d48d7a28467dc4e945314b57bc2b63085c Mon Sep 17 00:00:00 2001
From: Yingwei Zheng
Date: Thu, 13 Mar 2025 00:39:09 +0800
Subject: [PATCH 1/3] [Clang][CodeGen][UBSan] Add pre-commit tests. NFC.
---
clang/test/CodeGen/ubsan-attr.cpp | 84 +++
1 file changed, 84 insertions(+)
create mode 100644 clang/test/CodeGen/ubsan-attr.cpp
diff --git a/clang/test/CodeGen/ubsan-attr.cpp
b/clang/test/CodeGen/ubsan-attr.cpp
new file mode 100644
index 0..e0a8570154939
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-attr.cpp
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
UTC_ARGS: --check-attributes --check-globals all --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o -
-fsanitize-recover=signed-integer-overflow | FileCheck %s
--check-prefixes=RECOVER
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o - | FileCheck %s
--check-prefixes=ABORT
+
+// RECOVER: Function Attrs: mustprogress nounwind
+// RECOVER-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// RECOVER-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// RECOVER-NEXT: [[ENTRY:.*]]:
+// RECOVER-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// RECOVER-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// RECOVER-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// RECOVER-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// RECOVER-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// RECOVER-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// RECOVER: [[HANDLER_ADD_OVERFLOW]]:
+// RECOVER-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:tail call void @__ubsan_handle_add_overflow(ptr nonnull
@[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize [[META8]]
+// RECOVER-NEXT:[[DOTPRE:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2]]
+// RECOVER-NEXT:[[DOTPRE3:%.*]] = sext i16 [[DOTPRE]] to i32
+// RECOVER-NEXT:br label %[[CONT]], !nosanitize [[META8]]
+// RECOVER: [[CONT]]:
+// RECOVER-NEXT:[[CONV1_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE3]],
%[[HANDLER_ADD_OVERFLOW]] ], [ [[CONV]], %[[ENTRY]] ]
+// RECOVER-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// RECOVER-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// RECOVER-NEXT:ret i32 [[CONV1_PRE_PHI]]
+//
+// ABORT: Function Attrs: mustprogress nounwind
+// ABORT-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// ABORT-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// ABORT-NEXT: [[ENTRY:.*:]]
+// ABORT-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// ABORT-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// ABORT-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// ABORT-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// ABORT-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// ABORT-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// ABORT: [[HANDLER_ADD_OVERFLOW]]:
+// ABORT-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:tail call void @__ubsan_handle_add_overflow_abort(ptr
nonnull @[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize
[[META8]]
+// ABORT-NEXT:unreachable, !nosanitize [[META8]]
+// ABORT: [[CONT]]:
+// ABORT-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// ABORT-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// ABORT-NEXT:ret i32 [[CONV]]
+//
+int test(int &a, short &c) {
+ a += c;
+ return c;
+}
+//.
+// RECOVER: attributes #[[ATTR0]] = { mustprogress nounwind
"min-legal-vector-width"="0" "no-trapping-math"="true"
"stack-protector-buffer-size"="8" "tar
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff 57a90883ca541a90a7a4a22d715832ec0ceb0599
f5297c7e45452b39e1ceec6ff3ab50fd6792f393 --extensions cpp,c --
clang/test/CodeGen/ubsan-attr.cpp clang/lib/CodeGen/CGExpr.cpp
clang/test/CodeGen/allow-ubsan-check.c clang/test/CodeGen/attr-counted-by.c
``
View the diff from clang-format here.
``diff
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 845b176fa6..b04bec6bc2 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3617,9 +3617,11 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
.addAttribute(llvm::Attribute::NoUnwind);
}
B.addUWTableAttr(llvm::UWTableKind::Default);
- // Add more precise attributes to recoverable ubsan handlers for better
optimizations.
+ // Add more precise attributes to recoverable ubsan handlers for better
+ // optimizations.
if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && MayReturn) {
-B.addMemoryAttr(llvm::MemoryEffects::argMemOnly(llvm::ModRefInfo::Ref) |
llvm::MemoryEffects::inaccessibleMemOnly());
+B.addMemoryAttr(llvm::MemoryEffects::argMemOnly(llvm::ModRefInfo::Ref) |
+llvm::MemoryEffects::inaccessibleMemOnly());
// If the handler does not return, we must hit a undefined behavior.
B.addAttribute(llvm::Attribute::WillReturn);
}
``
https://github.com/llvm/llvm-project/pull/130990
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][CodeGen][UBSan] Add more precise attributes to recoverable ubsan handlers (PR #130990)
https://github.com/dtcxzyw created
https://github.com/llvm/llvm-project/pull/130990
Closes https://github.com/llvm/llvm-project/issues/130093.
>From ea0d82d48d7a28467dc4e945314b57bc2b63085c Mon Sep 17 00:00:00 2001
From: Yingwei Zheng
Date: Thu, 13 Mar 2025 00:39:09 +0800
Subject: [PATCH 1/2] [Clang][CodeGen][UBSan] Add pre-commit tests. NFC.
---
clang/test/CodeGen/ubsan-attr.cpp | 84 +++
1 file changed, 84 insertions(+)
create mode 100644 clang/test/CodeGen/ubsan-attr.cpp
diff --git a/clang/test/CodeGen/ubsan-attr.cpp
b/clang/test/CodeGen/ubsan-attr.cpp
new file mode 100644
index 0..e0a8570154939
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-attr.cpp
@@ -0,0 +1,84 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
UTC_ARGS: --check-attributes --check-globals all --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o -
-fsanitize-recover=signed-integer-overflow | FileCheck %s
--check-prefixes=RECOVER
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm
-fsanitize=signed-integer-overflow -O3 %s -o - | FileCheck %s
--check-prefixes=ABORT
+
+// RECOVER: Function Attrs: mustprogress nounwind
+// RECOVER-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// RECOVER-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// RECOVER-NEXT: [[ENTRY:.*]]:
+// RECOVER-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// RECOVER-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// RECOVER-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// RECOVER-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// RECOVER-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// RECOVER-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// RECOVER: [[HANDLER_ADD_OVERFLOW]]:
+// RECOVER-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// RECOVER-NEXT:tail call void @__ubsan_handle_add_overflow(ptr nonnull
@[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize [[META8]]
+// RECOVER-NEXT:[[DOTPRE:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2]]
+// RECOVER-NEXT:[[DOTPRE3:%.*]] = sext i16 [[DOTPRE]] to i32
+// RECOVER-NEXT:br label %[[CONT]], !nosanitize [[META8]]
+// RECOVER: [[CONT]]:
+// RECOVER-NEXT:[[CONV1_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE3]],
%[[HANDLER_ADD_OVERFLOW]] ], [ [[CONV]], %[[ENTRY]] ]
+// RECOVER-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// RECOVER-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// RECOVER-NEXT:ret i32 [[CONV1_PRE_PHI]]
+//
+// ABORT: Function Attrs: mustprogress nounwind
+// ABORT-LABEL: define dso_local noundef range(i32 -32768, 32768) i32
@_Z4testRiRs(
+// ABORT-SAME: ptr noundef nonnull align 4 captures(none) dereferenceable(4)
[[A:%.*]], ptr noundef nonnull readonly align 2 captures(none)
dereferenceable(2) [[C:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// ABORT-NEXT: [[ENTRY:.*:]]
+// ABORT-NEXT:[[TMP0:%.*]] = load i16, ptr [[C]], align 2, !tbaa
[[TBAA2:![0-9]+]]
+// ABORT-NEXT:[[CONV:%.*]] = sext i16 [[TMP0]] to i32
+// ABORT-NEXT:[[TMP1:%.*]] = load i32, ptr [[A]], align 4, !tbaa
[[TBAA6:![0-9]+]]
+// ABORT-NEXT:[[TMP2:%.*]] = tail call { i32, i1 }
@llvm.sadd.with.overflow.i32(i32 [[TMP1]], i32 [[CONV]]), !nosanitize
[[META8:![0-9]+]]
+// ABORT-NEXT:[[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1,
!nosanitize [[META8]]
+// ABORT-NEXT:br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW:.*]], label
%[[CONT:.*]], !prof [[PROF9:![0-9]+]], !nosanitize [[META8]]
+// ABORT: [[HANDLER_ADD_OVERFLOW]]:
+// ABORT-NEXT:[[TMP4:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:[[TMP5:%.*]] = zext i32 [[CONV]] to i64, !nosanitize
[[META8]]
+// ABORT-NEXT:tail call void @__ubsan_handle_add_overflow_abort(ptr
nonnull @[[GLOB1]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR3:[0-9]+]], !nosanitize
[[META8]]
+// ABORT-NEXT:unreachable, !nosanitize [[META8]]
+// ABORT: [[CONT]]:
+// ABORT-NEXT:[[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0,
!nosanitize [[META8]]
+// ABORT-NEXT:store i32 [[TMP6]], ptr [[A]], align 4, !tbaa [[TBAA6]]
+// ABORT-NEXT:ret i32 [[CONV]]
+//
+int test(int &a, short &c) {
+ a += c;
+ return c;
+}
+//.
+// RECOVER: attributes #[[ATTR0]] = { mustprogress nounwind
"min-legal-vector-width"="0" "no-
