-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][CodeGen] Guard ubsan checks with llvm.allow.ubsan.check
#87436
[clang][CodeGen] Guard ubsan checks with llvm.allow.ubsan.check
#87436
Conversation
Created using spr 1.3.4
Created using spr 1.3.4 [skip ci]
Created using spr 1.3.4
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Vitaly Buka (vitalybuka) ChangesIntrinsic inserted into CodeGenFunction::EmitCheck, which CFI is not the goal, and fixing inconsistencies with CFI is outside of the cope of the patch. RFC: https://discourse.llvm.org/t/rfc-add-llvm-experimental-hot-intrinsic-or-llvm-hot/77641 Full diff: https://github.com/llvm/llvm-project/pull/87436.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 54432353e7420d..b7c134f7044754 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -56,7 +56,13 @@ using namespace CodeGen;
// Experiment to make sanitizers easier to debug
static llvm::cl::opt<bool> ClSanitizeDebugDeoptimization(
"ubsan-unique-traps", llvm::cl::Optional,
- llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"));
+ llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check."));
+
+// TODO: Introduce frontend options to enabled per sanitizers, similar to
+// `fsanitize-trap`.
+static llvm::cl::opt<bool> ClSanitizeGuardChecks(
+ "ubsan-guard-checks", llvm::cl::Optional,
+ llvm::cl::desc("Guard UBSAN checks with `llvm.allow.ubsan.check()`."));
//===--------------------------------------------------------------------===//
// Miscellaneous Helper Methods
@@ -3521,6 +3527,17 @@ void CodeGenFunction::EmitCheck(
: FatalCond;
Cond = Cond ? Builder.CreateAnd(Cond, Check) : Check;
}
+
+ if (ClSanitizeGuardChecks) {
+ llvm::Value *Allow =
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check),
+ llvm::ConstantInt::get(CGM.Int8Ty, CheckHandler));
+
+ for (llvm::Value **Cond : {&FatalCond, &RecoverableCond, &TrapCond}) {
+ if (*Cond)
+ *Cond = Builder.CreateOr(*Cond, Builder.CreateNot(Allow));
+ }
+ }
if (TrapCond)
EmitTrapCheck(TrapCond, CheckHandler);
diff --git a/clang/test/CodeGen/allow-ubsan-check.c b/clang/test/CodeGen/allow-ubsan-check.c
index bc425230c8ec75..5232d240854666 100644
--- a/clang/test/CodeGen/allow-ubsan-check.c
+++ b/clang/test/CodeGen/allow-ubsan-check.c
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null -fsanitize-trap=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s --check-prefixes=TRAP
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s --check-prefixes=RECOVER
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null -mllvm -ubsan-guard-checks | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null -mllvm -ubsan-guard-checks -fsanitize-trap=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s --check-prefixes=TRAP
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null -mllvm -ubsan-guard-checks -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,null | FileCheck %s --check-prefixes=RECOVER
// CHECK-LABEL: define dso_local i32 @div(
@@ -18,11 +18,14 @@
// CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP1]], -1, !nosanitize [[META2]]
// CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP3]], [[TMP4]], !nosanitize [[META2]]
// CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP2]], [[OR]], !nosanitize [[META2]]
-// CHECK-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_DIVREM_OVERFLOW:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]], !nosanitize [[META2]]
+// CHECK-NEXT: br i1 [[TMP8]], label [[CONT:%.*]], label [[HANDLER_DIVREM_OVERFLOW:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
// CHECK: handler.divrem_overflow:
-// CHECK-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
-// CHECK-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
-// CHECK-NEXT: call void @__ubsan_handle_divrem_overflow_abort(ptr @[[GLOB1:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP9:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
+// CHECK-NEXT: call void @__ubsan_handle_divrem_overflow_abort(ptr @[[GLOB1:[0-9]+]], i64 [[TMP9]], i64 [[TMP10]]) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: cont:
// CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
@@ -42,9 +45,12 @@
// TRAP-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP1]], -1, !nosanitize [[META2]]
// TRAP-NEXT: [[OR:%.*]] = or i1 [[TMP3]], [[TMP4]], !nosanitize [[META2]]
// TRAP-NEXT: [[TMP5:%.*]] = and i1 [[TMP2]], [[OR]], !nosanitize [[META2]]
-// TRAP-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP6:%.*]] = call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]], !nosanitize [[META2]]
+// TRAP-NEXT: br i1 [[TMP8]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
// TRAP: trap:
-// TRAP-NEXT: call void @llvm.ubsantrap(i8 3) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
+// TRAP-NEXT: call void @llvm.ubsantrap(i8 3) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: cont:
// TRAP-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
@@ -64,11 +70,14 @@
// RECOVER-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP1]], -1, !nosanitize [[META2]]
// RECOVER-NEXT: [[OR:%.*]] = or i1 [[TMP3]], [[TMP4]], !nosanitize [[META2]]
// RECOVER-NEXT: [[TMP5:%.*]] = and i1 [[TMP2]], [[OR]], !nosanitize [[META2]]
-// RECOVER-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_DIVREM_OVERFLOW:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP6:%.*]] = call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]], !nosanitize [[META2]]
+// RECOVER-NEXT: br i1 [[TMP8]], label [[CONT:%.*]], label [[HANDLER_DIVREM_OVERFLOW:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]]
// RECOVER: handler.divrem_overflow:
-// RECOVER-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
-// RECOVER-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
-// RECOVER-NEXT: call void @__ubsan_handle_divrem_overflow(ptr @[[GLOB1:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP9:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP10:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
+// RECOVER-NEXT: call void @__ubsan_handle_divrem_overflow(ptr @[[GLOB1:[0-9]+]], i64 [[TMP9]], i64 [[TMP10]]) #[[ATTR4:[0-9]+]], !nosanitize [[META2]]
// RECOVER-NEXT: br label [[CONT]], !nosanitize [[META2]]
// RECOVER: cont:
// RECOVER-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP0]], [[TMP1]]
@@ -85,14 +94,17 @@ int div(int x, int y) {
// CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
// CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TMP0]], null, !nosanitize [[META2]]
-// CHECK-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 22), !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true, !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP1]], [[TMP3]], !nosanitize [[META2]]
+// CHECK-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
// CHECK: handler.type_mismatch:
-// CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]]
-// CHECK-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB2:[0-9]+]], i64 [[TMP2]]) #[[ATTR3]], !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]]
+// CHECK-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr @[[GLOB2:[0-9]+]], i64 [[TMP5]]) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: cont:
-// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
-// CHECK-NEXT: ret i32 [[TMP3]]
+// CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP0]], align 4
+// CHECK-NEXT: ret i32 [[TMP6]]
//
// TRAP-LABEL: define dso_local i32 @null(
// TRAP-SAME: ptr noundef [[X:%.*]]) #[[ATTR0]] {
@@ -101,13 +113,16 @@ int div(int x, int y) {
// TRAP-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8
// TRAP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
// TRAP-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TMP0]], null, !nosanitize [[META2]]
-// TRAP-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 22), !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true, !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP4:%.*]] = or i1 [[TMP1]], [[TMP3]], !nosanitize [[META2]]
+// TRAP-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
// TRAP: trap:
-// TRAP-NEXT: call void @llvm.ubsantrap(i8 22) #[[ATTR3]], !nosanitize [[META2]]
+// TRAP-NEXT: call void @llvm.ubsantrap(i8 22) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: cont:
-// TRAP-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP0]], align 4
-// TRAP-NEXT: ret i32 [[TMP2]]
+// TRAP-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4
+// TRAP-NEXT: ret i32 [[TMP5]]
//
// RECOVER-LABEL: define dso_local i32 @null(
// RECOVER-SAME: ptr noundef [[X:%.*]]) #[[ATTR0]] {
@@ -116,14 +131,17 @@ int div(int x, int y) {
// RECOVER-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8
// RECOVER-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X_ADDR]], align 8
// RECOVER-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TMP0]], null, !nosanitize [[META2]]
-// RECOVER-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 22), !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true, !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP4:%.*]] = or i1 [[TMP1]], [[TMP3]], !nosanitize [[META2]]
+// RECOVER-NEXT: br i1 [[TMP4]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
// RECOVER: handler.type_mismatch:
-// RECOVER-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]]
-// RECOVER-NEXT: call void @__ubsan_handle_type_mismatch_v1(ptr @[[GLOB2:[0-9]+]], i64 [[TMP2]]) #[[ATTR3]], !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize [[META2]]
+// RECOVER-NEXT: call void @__ubsan_handle_type_mismatch_v1(ptr @[[GLOB2:[0-9]+]], i64 [[TMP5]]) #[[ATTR4]], !nosanitize [[META2]]
// RECOVER-NEXT: br label [[CONT]], !nosanitize [[META2]]
// RECOVER: cont:
-// RECOVER-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
-// RECOVER-NEXT: ret i32 [[TMP3]]
+// RECOVER-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP0]], align 4
+// RECOVER-NEXT: ret i32 [[TMP6]]
//
int null(int* x) {
return *x;
@@ -142,11 +160,14 @@ int null(int* x) {
// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// CHECK-NEXT: [[TMP5:%.*]] = xor i1 [[TMP4]], true, !nosanitize [[META2]]
-// CHECK-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_ADD_OVERFLOW:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.allow.ubsan.check(i8 0), !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]], !nosanitize [[META2]]
+// CHECK-NEXT: br i1 [[TMP8]], label [[CONT:%.*]], label [[HANDLER_ADD_OVERFLOW:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
// CHECK: handler.add_overflow:
-// CHECK-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
-// CHECK-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
-// CHECK-NEXT: call void @__ubsan_handle_add_overflow_abort(ptr @[[GLOB3:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3]], !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP9:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
+// CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
+// CHECK-NEXT: call void @__ubsan_handle_add_overflow_abort(ptr @[[GLOB3:[0-9]+]], i64 [[TMP9]], i64 [[TMP10]]) #[[ATTR4]], !nosanitize [[META2]]
// CHECK-NEXT: unreachable, !nosanitize [[META2]]
// CHECK: cont:
// CHECK-NEXT: ret i32 [[TMP3]]
@@ -164,9 +185,12 @@ int null(int* x) {
// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
// TRAP-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// TRAP-NEXT: [[TMP5:%.*]] = xor i1 [[TMP4]], true, !nosanitize [[META2]]
-// TRAP-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP6:%.*]] = call i1 @llvm.allow.ubsan.check(i8 0), !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]]
+// TRAP-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]], !nosanitize [[META2]]
+// TRAP-NEXT: br i1 [[TMP8]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize [[META2]]
// TRAP: trap:
-// TRAP-NEXT: call void @llvm.ubsantrap(i8 0) #[[ATTR3]], !nosanitize [[META2]]
+// TRAP-NEXT: call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]]
// TRAP-NEXT: unreachable, !nosanitize [[META2]]
// TRAP: cont:
// TRAP-NEXT: ret i32 [[TMP3]]
@@ -184,11 +208,14 @@ int null(int* x) {
// RECOVER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]]
// RECOVER-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]]
// RECOVER-NEXT: [[TMP5:%.*]] = xor i1 [[TMP4]], true, !nosanitize [[META2]]
-// RECOVER-NEXT: br i1 [[TMP5]], label [[CONT:%.*]], label [[HANDLER_ADD_OVERFLOW:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP6:%.*]] = call i1 @llvm.allow.ubsan.check(i8 0), !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP8:%.*]] = or i1 [[TMP5]], [[TMP7]], !nosanitize [[META2]]
+// RECOVER-NEXT: br i1 [[TMP8]], label [[CONT:%.*]], label [[HANDLER_ADD_OVERFLOW:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
// RECOVER: handler.add_overflow:
-// RECOVER-NEXT: [[TMP6:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
-// RECOVER-NEXT: [[TMP7:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
-// RECOVER-NEXT: call void @__ubsan_handle_add_overflow(ptr @[[GLOB3:[0-9]+]], i64 [[TMP6]], i64 [[TMP7]]) #[[ATTR3]], !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP9:%.*]] = zext i32 [[TMP0]] to i64, !nosanitize [[META2]]
+// RECOVER-NEXT: [[TMP10:%.*]] = zext i32 [[TMP1]] to i64, !nosanitize [[META2]]
+// RECOVER-NEXT: call void @__ubsan_handle_add_overflow(ptr @[[GLOB3:[0-9]+]], i64 [[TMP9]], i64 [[TMP10]]) #[[ATTR4]], !nosanitize [[META2]]
// RECOVER-NEXT: br label [[CONT]], !nosanitize [[META2]]
// RECOVER: cont:
// RECOVER-NEXT: ret i32 [[TMP3]]
|
Created using spr 1.3.4 [skip ci]
I will land, and address followup comments, if any. |
Intrinsic inserted into CodeGenFunction::EmitCheck, which
is not mostly used by CFI.
CFI is not the goal, and fixing inconsistencies with CFI is outside of the cope of the patch.
RFC: https://discourse.llvm.org/t/rfc-add-llvm-experimental-hot-intrinsic-or-llvm-hot/77641