llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-compiler-rt-sanitizer Author: Victor Chernyakin (localspook) <details> <summary>Changes</summary> Towards #<!-- -->43241. [N1169](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf) section 4.1.6.2.1 specifies that fixed-point division by zero is UB, but UBSan currently doesn't catch it: https://godbolt.org/z/xrc3oKcxd. This PR implements a new check to handle it, `fixed-point-divide-by-zero`. This check is part of a new group, `fixed-point`, which will hopefully be expanded in the future (division by zero isn't the only UB that can happen with fixed-point numbers). This PR adds a new type descriptor kind but no associated type info, because this specific check doesn't need it. Future checks (e.g. overflow) will probably need to define it though. --- Patch is 70.65 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/165181.diff 20 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+5) - (modified) clang/docs/UndefinedBehaviorSanitizer.rst (+4) - (modified) clang/include/clang/Basic/Features.def (+4) - (modified) clang/include/clang/Basic/Sanitizers.def (+3-1) - (modified) clang/lib/CodeGen/CGExpr.cpp (+6-2) - (modified) clang/lib/CodeGen/CGExprScalar.cpp (+12-1) - (modified) clang/test/CodeGen/allow-ubsan-check.c (+140-140) - (modified) clang/test/Driver/fsanitize-annotate-debug-info.c (+3-3) - (modified) clang/test/Driver/fsanitize-merge.c (+3-3) - (modified) clang/test/Driver/fsanitize-minimal-runtime.c (+4-4) - (modified) clang/test/Driver/fsanitize-recover.c (+1-1) - (modified) clang/test/Driver/fsanitize-skip-hot-cutoff.c (+4-4) - (modified) clang/test/Driver/fsanitize-trap.c (+3-3) - (modified) clang/test/Driver/fsanitize-undefined.c (+5-5) - (modified) clang/test/Driver/fsanitize.c (+2-2) - (modified) clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp (+16) - (modified) compiler-rt/lib/ubsan/ubsan_checks.inc (+2) - (modified) compiler-rt/lib/ubsan/ubsan_handlers.cpp (+2) - (modified) compiler-rt/lib/ubsan/ubsan_value.h (+4) - (added) compiler-rt/test/ubsan/TestCases/FixedPoint/divide-by-zero.cpp (+10) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 061ccd2492c49..f635b41949051 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -211,6 +211,11 @@ New Compiler Flags higher), accurate source locations are used; otherwise, a heuristic fallback is used with a note suggesting how to enable debug info for better accuracy. +- New option ``-fsanitize=fixed-point-divide-by-zero`` added to instrument + code involving fixed point numbers (``-ffixed-point``) with checks for + division by zero. Also added a new sanitizer group ``-fsanitize=fixed-point`` + that includes the new option. + Deprecated Compiler Flags ------------------------- diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst index bb0dc00609688..fc95d52f14d6b 100644 --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -119,6 +119,8 @@ Available checks are: - ``-fsanitize=enum``: Load of a value of an enumerated type which is not in the range of representable values for that enumerated type. + - ``-fsanitize=fixed-point-divide-by-zero``: Fixed point division by zero + (when compiling with ``-ffixed-point``). - ``-fsanitize=float-cast-overflow``: Conversion to, from, or between floating-point types which would overflow the destination. Because the range of representable values for all @@ -224,6 +226,8 @@ You can also use the following check groups: ``nullability-*`` group of checks. - ``-fsanitize=undefined-trap``: Deprecated alias of ``-fsanitize=undefined``. + - ``-fsanitize=fixed-point``: Checks for undefined behavior with fixed point + values. Enables ``-fsanitize=fixed-point-divide-by-zero``. - ``-fsanitize=implicit-integer-truncation``: Catches lossy integral conversions. Enables ``implicit-signed-integer-truncation`` and ``implicit-unsigned-integer-truncation``. diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 2f7741ff74f9b..c264263a41bf5 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -66,6 +66,10 @@ FEATURE(array_bounds_sanitizer, LangOpts.Sanitize.has(SanitizerKind::ArrayBounds)) FEATURE(enum_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Enum)) +FEATURE(fixed_point_divide_by_zero_sanitizer, + LangOpts.Sanitize.has(SanitizerKind::FixedPointDivideByZero)) +FEATURE(fixed_point_sanitizer, + LangOpts.Sanitize.hasOneOf(SanitizerKind::FixedPoint)) FEATURE(float_cast_overflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::FloatCastOverflow)) FEATURE(integer_divide_by_zero_sanitizer, diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index da85431625026..b77a838d71da1 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -94,6 +94,8 @@ SANITIZER("array-bounds", ArrayBounds) SANITIZER("bool", Bool) SANITIZER("builtin", Builtin) SANITIZER("enum", Enum) +SANITIZER("fixed-point-divide-by-zero", FixedPointDivideByZero) +SANITIZER_GROUP("fixed-point", FixedPoint, FixedPointDivideByZero) SANITIZER("float-cast-overflow", FloatCastOverflow) SANITIZER("float-divide-by-zero", FloatDivideByZero) SANITIZER("function", Function) @@ -149,7 +151,7 @@ SANITIZER("shadow-call-stack", ShadowCallStack) // ABI or address space layout implications, and only catch undefined behavior. SANITIZER_GROUP("undefined", Undefined, Alignment | Bool | Builtin | ArrayBounds | Enum | - FloatCastOverflow | + FixedPoint | FloatCastOverflow | IntegerDivideByZero | NonnullAttribute | Null | ObjectSize | PointerOverflow | Return | ReturnsNonnullAttribute | Shift | SignedIntegerOverflow | Unreachable | VLABound | Function) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 23802cdeb4811..0ee17d9611538 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -82,6 +82,8 @@ enum VariableTypeDescriptorKind : uint16_t { TK_Float = 0x0001, /// An _BitInt(N) type. TK_BitInt = 0x0002, + /// A fixed-point type. + TK_FixedPoint = 0x0003, /// Any other type. The value representation is unspecified. TK_Unknown = 0xffff }; @@ -3886,8 +3888,8 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) { /// /// followed by an array of i8 containing the type name with extra information /// for BitInt. TypeKind is TK_Integer(0) for an integer, TK_Float(1) for a -/// floating point value, TK_BitInt(2) for BitInt and TK_Unknown(0xFFFF) for -/// anything else. +/// floating point value, TK_BitInt(2) for BitInt, TK_FixedPoint(3) for a +/// fixed point value, and TK_Unknown(0xFFFF) for anything else. llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { // Only emit each type's descriptor once. if (llvm::Constant *C = CGM.getTypeDescriptorFromMap(T)) @@ -3919,6 +3921,8 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { } else if (T->isFloatingType()) { TypeKind = TK_Float; TypeInfo = getContext().getTypeSize(T); + } else if (T->isFixedPointType()) { + TypeKind = TK_FixedPoint; } // Format the type name as if for a diagnostic, including quotes and diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index d208b760396b6..166813c6d2474 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -4819,9 +4819,20 @@ Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) { Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema); break; case BO_DivAssign: - case BO_Div: + case BO_Div: { + SanitizerDebugLocation SanScope(&CGF, + {SanitizerKind::SO_FixedPointDivideByZero}, + SanitizerHandler::DivremOverflow); + if (CGF.SanOpts.has(SanitizerKind::FixedPointDivideByZero)) { + Value *Zero = llvm::Constant::getNullValue(RHS->getType()); + const std::pair<Value *, SanitizerKind::SanitizerOrdinal> Check = { + Builder.CreateICmpNE(RHS, Zero), + SanitizerKind::SO_FixedPointDivideByZero}; + EmitBinOpCheck(Check, op); + } Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema); break; + } case BO_ShlAssign: case BO_Shl: Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS); diff --git a/clang/test/CodeGen/allow-ubsan-check.c b/clang/test/CodeGen/allow-ubsan-check.c index da3bf3d4d72f5..31a8ec64da97f 100644 --- a/clang/test/CodeGen/allow-ubsan-check.c +++ b/clang/test/CodeGen/allow-ubsan-check.c @@ -7,30 +7,30 @@ // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -O1 -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null,local-bounds -mllvm -ubsan-guard-checks -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,null,local-bounds | FileCheck %s --check-prefixes=REC -// CHECK-LABEL: define dso_local noundef i32 @div( -// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META6:![0-9]+]] -// CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META6]] -// CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META6]] -// CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]] // // 27 == SO_IntegerDivideByZero -// CHECK-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), !nosanitize [[META6]] -// CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META6]] -// CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META6]] // // 41 == SO_SignedIntegerOverflow -// CHECK-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META6]] -// CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META6]] -// CHECK-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META6]] -// CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META6]] -// CHECK-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] +// CHECK-LABEL: define dso_local noundef i32 @div( +// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META5:![0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META5]] +// CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META5]] +// CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META5]] +// CHECK-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META5]] +// CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META5]] +// CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META5]] +// CHECK-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 43), !nosanitize [[META5]] +// CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META5]] +// CHECK-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META5]] +// CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META5]] +// CHECK-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]] // CHECK: [[HANDLER_DIVREM_OVERFLOW]]: -// CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META6]] -// CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META6]] -// CHECK-NEXT: tail call void @__ubsan_handle_divrem_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]], !nosanitize [[META6]] -// CHECK-NEXT: unreachable, !nosanitize [[META6]] +// CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META5]] +// CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META5]] +// CHECK-NEXT: tail call void @__ubsan_handle_divrem_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]], !nosanitize [[META5]] +// CHECK-NEXT: unreachable, !nosanitize [[META5]] // CHECK: [[CONT]]: // CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X]], [[Y]] // CHECK-NEXT: ret i32 [[DIV]] @@ -38,21 +38,21 @@ // TR-LABEL: define dso_local noundef i32 @div( // TR-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // TR-NEXT: [[ENTRY:.*:]] -// TR-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META6:![0-9]+]] -// TR-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META6]] -// TR-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META6]] -// TR-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]] -// TR-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), !nosanitize [[META6]] -// TR-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META6]] -// TR-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META6]] -// TR-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META6]] -// TR-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META6]] -// TR-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META6]] -// TR-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META6]] -// TR-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] +// TR-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META5:![0-9]+]] +// TR-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META5]] +// TR-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META5]] +// TR-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META5]] +// TR-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META5]] +// TR-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META5]] +// TR-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META5]] +// TR-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 43), !nosanitize [[META5]] +// TR-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META5]] +// TR-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META5]] +// TR-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META5]] +// TR-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[TRAP:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]] // TR: [[TRAP]]: -// TR-NEXT: tail call void @llvm.ubsantrap(i8 3) #[[ATTR7:[0-9]+]], !nosanitize [[META6]] -// TR-NEXT: unreachable, !nosanitize [[META6]] +// TR-NEXT: tail call void @llvm.ubsantrap(i8 3) #[[ATTR7:[0-9]+]], !nosanitize [[META5]] +// TR-NEXT: unreachable, !nosanitize [[META5]] // TR: [[CONT]]: // TR-NEXT: [[DIV:%.*]] = sdiv i32 [[X]], [[Y]] // TR-NEXT: ret i32 [[DIV]] @@ -60,23 +60,23 @@ // REC-LABEL: define dso_local noundef i32 @div( // REC-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // REC-NEXT: [[ENTRY:.*:]] -// REC-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META6:![0-9]+]] -// REC-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META6]] -// REC-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META6]] -// REC-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META6]] -// REC-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), !nosanitize [[META6]] -// REC-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META6]] -// REC-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META6]] -// REC-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META6]] -// REC-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META6]] -// REC-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META6]] -// REC-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META6]] -// REC-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META6]] +// REC-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META5:![0-9]+]] +// REC-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META5]] +// REC-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META5]] +// REC-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META5]] +// REC-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META5]] +// REC-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META5]] +// REC-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META5]] +// REC-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 43), !nosanitize [[META5]] +// REC-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META5]] +// REC-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META5]] +// REC-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META5]] +// REC-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], !prof [[PROF6:![0-9]+]], !nosanitize [[META5]] // REC: [[HANDLER_DIVREM_OVERFLOW]]: -// REC-NEXT: [[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META6]] -// REC-NEXT: [[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META6]] -// REC-NEXT: tail call void @__ubsan_handle_divrem_overflow(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]], !nosanitize [[META6]] -// REC-NEXT: br label %[[CONT]], !nosanitize [[META6]] +// REC-NEXT: [[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META5]] +// REC-NEXT: [[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META5]] +// REC-NEXT: tail call void @__ubsan_handle_divrem_overflow(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]], !nosanitize [[META5]] +// REC-NEXT: br label %[[CONT]], !nosanitize [[META5]] // REC: [[CONT]]: // REC-NEXT: [[DIV:%.*]] = sdiv i32 [[X]], [[Y]] // REC-NEXT: ret i32 [[DIV]] @@ -85,103 +85,103 @@ int div(int x, int y) { return x / y; } +// +// 29 == SO_Null // CHECK-LABEL: define dso_local i32 @null( // CHECK-SAME: ptr noundef readonly captures(address_is_null) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META6]] -// -// 29 == SO_Null -// CHECK-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META6]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META5]] +// CHECK-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 31), !nosanitize [[META5]] // CHECK-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] -// CHECK-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META6]] +// CHECK-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META5]] // CHECK: [[HANDLER_TYPE_MISMATCH]]: -// CHECK-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META6]] -// CHECK-NEXT: unreachable, !nosanitize [[META6]] +// CHECK-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META5]] +// CHECK-NEXT: unreachable, !nosanitize [[META5]] // CHECK: [[CONT]]: -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[INT_TBAA2:![0-9]+]] +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[INT_TBAA1:![0-9]+]] // CHECK-NEXT: ret i32 [[TMP2]] // // TR-LABEL: define dso_local i32 @null( // TR-SAME: ptr noundef readonly captures(address_is_null) [[X:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // TR-NEXT: [[ENTRY:.*:]] -// TR-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META6]] -// TR-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META6]] +// TR-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META5]] +// TR-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 31), !nosanitize [[META5]] // TR-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] -// TR-NEXT: br i1 [[DOTNOT1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META6]] +// TR-NEXT: br i1 [[DOTNOT1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF7:![0-9]+]], !nosanitize [[META5]] // TR: [[TRAP]]: -// TR-NEXT: tail call void @llvm.ubsantrap(i8 22) #[[ATTR7]], !nosanitize [[META6]] -// TR-NEXT: unreachable, !nosanitize [[META6]] +// TR-NEXT: tail call void @llvm.ubsantrap(i8 22) #[[ATTR7]], !nosanitize [[META5]] +// TR-NEXT: unreachable, !nosanitize [[META5]] // TR: [[CONT]]: -// TR-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[INT_TBAA2:![0-9]+]] +// TR-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[INT_TBAA1:![0-9]+]] // 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]] { // REC-NEXT: [[ENTRY:.*:]] -// REC-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META6]] -// REC-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META6]] +// REC-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META5]] +// REC-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.all... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/165181 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
