https://github.com/melver updated https://github.com/llvm/llvm-project/pull/172030
>From 6368450bba995b8c936f419f46d274c9cce84282 Mon Sep 17 00:00:00 2001 From: Marco Elver <[email protected]> Date: Fri, 12 Dec 2025 16:57:20 +0100 Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.8-beta.1 [skip ci] --- llvm/include/llvm/IR/Intrinsics.td | 14 ++++ .../Instrumentation/LowerAllowCheckPass.h | 2 + .../Instrumentation/LowerAllowCheckPass.cpp | 28 ++++++-- .../lower-builtin-allow-check-pipeline.ll | 0 .../lower-builtin-allow-check-remarks.ll | 0 .../lower-builtin-allow-check.ll | 0 .../LowerAllowCheck/sanitize-check.ll | 70 +++++++++++++++++++ 7 files changed, 108 insertions(+), 6 deletions(-) rename llvm/test/Transforms/{ => LowerAllowCheck}/lower-builtin-allow-check-pipeline.ll (100%) rename llvm/test/Transforms/{ => LowerAllowCheck}/lower-builtin-allow-check-remarks.ll (100%) rename llvm/test/Transforms/{ => LowerAllowCheck}/lower-builtin-allow-check.ll (100%) create mode 100644 llvm/test/Transforms/LowerAllowCheck/sanitize-check.ll diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 35a4158a56da9..c8e16178b7a02 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1884,6 +1884,20 @@ def int_allow_runtime_check : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_metadata [IntrInaccessibleMemOnly, NoUndef<RetIndex>]>, ClangBuiltin<"__builtin_allow_runtime_check">; +// Return true if the specific sanitizer is enabled for the function. +def int_allow_sanitize_address + : DefaultAttrsIntrinsic<[llvm_i1_ty], [], + [IntrInaccessibleMemOnly, NoUndef<RetIndex>]>; +def int_allow_sanitize_thread + : DefaultAttrsIntrinsic<[llvm_i1_ty], [], + [IntrInaccessibleMemOnly, NoUndef<RetIndex>]>; +def int_allow_sanitize_memory + : DefaultAttrsIntrinsic<[llvm_i1_ty], [], + [IntrInaccessibleMemOnly, NoUndef<RetIndex>]>; +def int_allow_sanitize_hwaddress + : DefaultAttrsIntrinsic<[llvm_i1_ty], [], + [IntrInaccessibleMemOnly, NoUndef<RetIndex>]>; + // Support for dynamic deoptimization (or de-specialization) def int_experimental_deoptimize : Intrinsic<[llvm_any_ty], [llvm_vararg_ty], [Throws]>; diff --git a/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h b/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h index 37bc728779836..7b5e4a21c057c 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h +++ b/llvm/include/llvm/Transforms/Instrumentation/LowerAllowCheckPass.h @@ -34,6 +34,8 @@ class LowerAllowCheckPass : public PassInfoMixin<LowerAllowCheckPass> { : Opts(std::move(Opts)) {}; LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + static bool isRequired() { return true; } + LLVM_ABI static bool IsRequested(); LLVM_ABI void printPipeline(raw_ostream &OS, diff --git a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp index 2486e77ab0137..d4c23ffe9a723 100644 --- a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp +++ b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp @@ -76,6 +76,7 @@ static bool lowerAllowChecks(Function &F, const BlockFrequencyInfo &BFI, const ProfileSummaryInfo *PSI, OptimizationRemarkEmitter &ORE, const LowerAllowCheckPass::Options &Opts) { + // List of intrinsics and the constant value they should be lowered to. SmallVector<std::pair<IntrinsicInst *, bool>, 16> ReplaceWithValue; std::unique_ptr<RandomNumberGenerator> Rng; @@ -123,26 +124,41 @@ static bool lowerAllowChecks(Function &F, const BlockFrequencyInfo &BFI, switch (ID) { case Intrinsic::allow_ubsan_check: case Intrinsic::allow_runtime_check: { - ++NumChecksTotal; - bool ToRemove = ShouldRemove(II); ReplaceWithValue.push_back({ II, - ToRemove, + !ToRemove, }); - if (ToRemove) - ++NumChecksRemoved; emitRemark(II, ORE, ToRemove); break; } + case Intrinsic::allow_sanitize_address: + ReplaceWithValue.push_back( + {II, F.hasFnAttribute(Attribute::SanitizeAddress)}); + break; + case Intrinsic::allow_sanitize_thread: + ReplaceWithValue.push_back( + {II, F.hasFnAttribute(Attribute::SanitizeThread)}); + break; + case Intrinsic::allow_sanitize_memory: + ReplaceWithValue.push_back( + {II, F.hasFnAttribute(Attribute::SanitizeMemory)}); + break; + case Intrinsic::allow_sanitize_hwaddress: + ReplaceWithValue.push_back( + {II, F.hasFnAttribute(Attribute::SanitizeHWAddress)}); + break; default: break; } } for (auto [I, V] : ReplaceWithValue) { - I->replaceAllUsesWith(ConstantInt::getBool(I->getType(), !V)); + ++NumChecksTotal; + if (!V) // If the final value is false, the check is considered removed + ++NumChecksRemoved; + I->replaceAllUsesWith(ConstantInt::getBool(I->getType(), V)); I->eraseFromParent(); } diff --git a/llvm/test/Transforms/lower-builtin-allow-check-pipeline.ll b/llvm/test/Transforms/LowerAllowCheck/lower-builtin-allow-check-pipeline.ll similarity index 100% rename from llvm/test/Transforms/lower-builtin-allow-check-pipeline.ll rename to llvm/test/Transforms/LowerAllowCheck/lower-builtin-allow-check-pipeline.ll diff --git a/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll b/llvm/test/Transforms/LowerAllowCheck/lower-builtin-allow-check-remarks.ll similarity index 100% rename from llvm/test/Transforms/lower-builtin-allow-check-remarks.ll rename to llvm/test/Transforms/LowerAllowCheck/lower-builtin-allow-check-remarks.ll diff --git a/llvm/test/Transforms/lower-builtin-allow-check.ll b/llvm/test/Transforms/LowerAllowCheck/lower-builtin-allow-check.ll similarity index 100% rename from llvm/test/Transforms/lower-builtin-allow-check.ll rename to llvm/test/Transforms/LowerAllowCheck/lower-builtin-allow-check.ll diff --git a/llvm/test/Transforms/LowerAllowCheck/sanitize-check.ll b/llvm/test/Transforms/LowerAllowCheck/sanitize-check.ll new file mode 100644 index 0000000000000..eb3c6073aabe5 --- /dev/null +++ b/llvm/test/Transforms/LowerAllowCheck/sanitize-check.ll @@ -0,0 +1,70 @@ +; RUN: opt < %s -passes=lower-allow-check -S | FileCheck %s +; RUN: opt < %s -passes=lower-allow-check -lower-allow-check-random-rate=0 -S | FileCheck %s + +declare i1 @llvm.allow.sanitize.address() +declare i1 @llvm.allow.sanitize.thread() +declare i1 @llvm.allow.sanitize.memory() +declare i1 @llvm.allow.sanitize.hwaddress() + +define i1 @test_address() sanitize_address { +; CHECK-LABEL: @test_address( +; CHECK-NEXT: ret i1 true + %1 = call i1 @llvm.allow.sanitize.address() + ret i1 %1 +} + +define i1 @test_no_sanitize_address() { +; CHECK-LABEL: @test_no_sanitize_address( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.allow.sanitize.address() + ret i1 %1 +} + +define i1 @test_address_but_no_thread() sanitize_address { +; CHECK-LABEL: @test_address_but_no_thread( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.allow.sanitize.thread() + ret i1 %1 +} + +define i1 @test_thread() sanitize_thread { +; CHECK-LABEL: @test_thread( +; CHECK-NEXT: ret i1 true + %1 = call i1 @llvm.allow.sanitize.thread() + ret i1 %1 +} + +define i1 @test_no_sanitize_thread() { +; CHECK-LABEL: @test_no_sanitize_thread( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.allow.sanitize.thread() + ret i1 %1 +} + +define i1 @test_memory() sanitize_memory { +; CHECK-LABEL: @test_memory( +; CHECK-NEXT: ret i1 true + %1 = call i1 @llvm.allow.sanitize.memory() + ret i1 %1 +} + +define i1 @test_no_sanitize_memory() { +; CHECK-LABEL: @test_no_sanitize_memory( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.allow.sanitize.memory() + ret i1 %1 +} + +define i1 @test_hwaddress() sanitize_hwaddress { +; CHECK-LABEL: @test_hwaddress( +; CHECK-NEXT: ret i1 true + %1 = call i1 @llvm.allow.sanitize.hwaddress() + ret i1 %1 +} + +define i1 @test_no_sanitize_hwaddress() { +; CHECK-LABEL: @test_no_sanitize_hwaddress( +; CHECK-NEXT: ret i1 false + %1 = call i1 @llvm.allow.sanitize.hwaddress() + ret i1 %1 +} >From d4f149dbb21fd7f5e706560b1aa3b8f0b9fa5ae9 Mon Sep 17 00:00:00 2001 From: Marco Elver <[email protected]> Date: Fri, 12 Dec 2025 17:18:15 +0100 Subject: [PATCH 2/4] tweak test Created using spr 1.3.8-beta.1 --- clang/test/CodeGen/builtin-allow-sanitize-check-lower.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeGen/builtin-allow-sanitize-check-lower.c b/clang/test/CodeGen/builtin-allow-sanitize-check-lower.c index 05a0295799f55..5e52f77f55573 100644 --- a/clang/test/CodeGen/builtin-allow-sanitize-check-lower.c +++ b/clang/test/CodeGen/builtin-allow-sanitize-check-lower.c @@ -9,9 +9,9 @@ _Bool check() { return __builtin_allow_sanitize_check("address"); } -// CHECK-LABEL: @test +// CHECK-LABEL: @test_sanitize // CHECK: ret i1 true -_Bool test() { +_Bool test_sanitize() { return check(); } >From f4c6cfded128616e2c8d119e19174bbed1298781 Mon Sep 17 00:00:00 2001 From: Marco Elver <[email protected]> Date: Wed, 17 Dec 2025 20:47:40 +0100 Subject: [PATCH 3/4] fixes Created using spr 1.3.8-beta.1 --- clang/lib/CodeGen/CGBuiltin.cpp | 37 ++++++++++--------- .../test/Sema/builtin-allow-sanitize-check.c | 6 +-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 98d80620b44a5..9de085379882c 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3551,25 +3551,28 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, } case Builtin::BI__builtin_allow_sanitize_check: { Intrinsic::ID IntrID = Intrinsic::not_intrinsic; - StringRef SanitizerName = + StringRef Name = cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())->getString(); - if (SanitizerName == "address" || SanitizerName == "kernel-address") { - if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress)) - IntrID = Intrinsic::allow_sanitize_address; - } else if (SanitizerName == "thread") { - if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Thread)) - IntrID = Intrinsic::allow_sanitize_thread; - } else if (SanitizerName == "memory" || SanitizerName == "kernel-memory") { - if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Memory | - SanitizerKind::KernelMemory)) - IntrID = Intrinsic::allow_sanitize_memory; - } else if (SanitizerName == "hwaddress" || - SanitizerName == "kernel-hwaddress") { - if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress)) - IntrID = Intrinsic::allow_sanitize_hwaddress; + // We deliberately allow the use of kernel- and non-kernel names + // interchangably, even when one or the other is enabled. This is consistent + // with the no_sanitize-attribute, which allows either kernel- or non-kernel + // name to disable instrumentation (see CodeGenFunction::StartFunction). + if (getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | + SanitizerKind::KernelAddress) && + (Name == "address" || Name == "kernel-address")) { + IntrID = Intrinsic::allow_sanitize_address; + } else if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && + Name == "thread") { + IntrID = Intrinsic::allow_sanitize_thread; + } else if (getLangOpts().Sanitize.hasOneOf(SanitizerKind::Memory | + SanitizerKind::KernelMemory) && + (Name == "memory" || Name == "kernel-memory")) { + IntrID = Intrinsic::allow_sanitize_memory; + } else if (getLangOpts().Sanitize.hasOneOf( + SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress) && + (Name == "hwaddress" || Name == "kernel-hwaddress")) { + IntrID = Intrinsic::allow_sanitize_hwaddress; } if (IntrID != Intrinsic::not_intrinsic) { diff --git a/clang/test/Sema/builtin-allow-sanitize-check.c b/clang/test/Sema/builtin-allow-sanitize-check.c index 94deb16dd89f9..6e0e21a869461 100644 --- a/clang/test/Sema/builtin-allow-sanitize-check.c +++ b/clang/test/Sema/builtin-allow-sanitize-check.c @@ -1,15 +1,15 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s void test_builtin_allow_sanitize_check() { - // Test with non-string literal argument + // Test with non-string literal argument. char str[] = "address"; (void)__builtin_allow_sanitize_check(str); // expected-error {{expression is not a string literal}} (void)__builtin_allow_sanitize_check(123); // expected-error {{expression is not a string literal}} - // Test with unsupported sanitizer name + // Test with unsupported sanitizer name. (void)__builtin_allow_sanitize_check("unsupported"); // expected-error {{invalid argument 'unsupported' to __builtin_allow_sanitize_check}} - // Test with supported sanitizer names + // Test with supported sanitizer names. (void)__builtin_allow_sanitize_check("address"); (void)__builtin_allow_sanitize_check("thread"); (void)__builtin_allow_sanitize_check("memory"); >From 14461fb01021f5a9689d55c1e848b8eb85ad78b2 Mon Sep 17 00:00:00 2001 From: Marco Elver <[email protected]> Date: Thu, 18 Dec 2025 12:05:13 +0100 Subject: [PATCH 4/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20introduced=20through=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.8-beta.1 [skip ci] --- llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp index d4c23ffe9a723..7a950036d9b6b 100644 --- a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp +++ b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp @@ -156,7 +156,7 @@ static bool lowerAllowChecks(Function &F, const BlockFrequencyInfo &BFI, for (auto [I, V] : ReplaceWithValue) { ++NumChecksTotal; - if (!V) // If the final value is false, the check is considered removed + if (!V) // If the final value is false, the check is considered removed. ++NumChecksRemoved; I->replaceAllUsesWith(ConstantInt::getBool(I->getType(), V)); I->eraseFromParent(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
