https://github.com/jdoerfert updated https://github.com/llvm/llvm-project/pull/195408
>From fbbd98d9d7c10a40ce23db795aabbe1d084764d2 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert <[email protected]> Date: Fri, 1 May 2026 21:21:25 -0700 Subject: [PATCH] [Instrumentor] Add unreachable support; unreachable stack trace printing Allow to instrument unreachable and provide a use case for stack trace printing. --- .../Instrumentor/InstrumentorUnreachable.cpp | 20 ++++++++++++++++++ clang/test/Instrumentor/UnreachableRT.cpp | 21 +++++++++++++++++++ clang/test/Instrumentor/UnreachableRT.json | 15 +++++++++++++ clang/test/Instrumentor/lit.local.cfg | 6 +++++- .../llvm/Transforms/IPO/Instrumentor.h | 21 +++++++++++++++++++ llvm/lib/Transforms/IPO/Instrumentor.cpp | 12 +++++++++++ .../Instrumentor/default_config.json | 5 +++++ 7 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 clang/test/Instrumentor/InstrumentorUnreachable.cpp create mode 100644 clang/test/Instrumentor/UnreachableRT.cpp create mode 100644 clang/test/Instrumentor/UnreachableRT.json diff --git a/clang/test/Instrumentor/InstrumentorUnreachable.cpp b/clang/test/Instrumentor/InstrumentorUnreachable.cpp new file mode 100644 index 0000000000000..0caf07a1e9496 --- /dev/null +++ b/clang/test/Instrumentor/InstrumentorUnreachable.cpp @@ -0,0 +1,20 @@ +// NOTE: Assertions have been autogenerated by utils/update_test_checks.py +// RUN: %clangxx -O0 -I%llvm_bin_dir/include/ -I%llvm_src_dir/include/ %S/UnreachableRT.cpp -o %t.UnreachableRT.o -c +// RUN: %clangxx -O0 -L%llvm_bin_dir/lib -lLLVMSupport -lLLVMDemangle -mllvm -enable-instrumentor -mllvm -instrumentor-read-config-file=%S/UnreachableRT.json %t.UnreachableRT.o -o %t %s +// RUN: %t 2>&1 | FileCheck %s --check-prefix=FIRST +// RUN: %t arg 2>&1 | FileCheck %s --check-prefix=SECOND + +static int foobar() { + __builtin_unreachable(); +} + + +int main(int argc, char **argv) { + if (argc > 1) + foobar(); + else + __builtin_unreachable(); +} + +// FIRST: Hit unreachable #1 +// SECOND: Hit unreachable #2 diff --git a/clang/test/Instrumentor/UnreachableRT.cpp b/clang/test/Instrumentor/UnreachableRT.cpp new file mode 100644 index 0000000000000..a608060128e57 --- /dev/null +++ b/clang/test/Instrumentor/UnreachableRT.cpp @@ -0,0 +1,21 @@ +//===---- Instrumentor/UnreachableRT.c - An example Instrumentor use -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" + +extern "C" { +void __unreachable_pre_unreachable(int64_t ID) { + llvm::errs() << "Hit unreachable #" << ID << "\n"; + llvm::sys::PrintStackTrace(llvm::errs()); + std::exit(0); +} +} diff --git a/clang/test/Instrumentor/UnreachableRT.json b/clang/test/Instrumentor/UnreachableRT.json new file mode 100644 index 0000000000000..9f4b1b76ef4b4 --- /dev/null +++ b/clang/test/Instrumentor/UnreachableRT.json @@ -0,0 +1,15 @@ +{ + "configuration": { + "runtime_prefix": "__unreachable_", + "runtime_prefix.description": "The runtime API prefix.", + "demangle_function_names": true, + "demangle_function_names.description": "Demangle functions names passed to the runtime." + }, + "instruction_pre": { + "unreachable": { + "enabled": true, + "id": true, + "id.description": "A unique ID associated with the given instrumentor call" + } + } +} diff --git a/clang/test/Instrumentor/lit.local.cfg b/clang/test/Instrumentor/lit.local.cfg index afb6cf1a99e25..ae3b82b9dc78e 100644 --- a/clang/test/Instrumentor/lit.local.cfg +++ b/clang/test/Instrumentor/lit.local.cfg @@ -1,2 +1,6 @@ + config.suffixes.add(".cpp") -config.excludes = ["StackUsageRT.cpp"] +config.excludes = ["StackUsageRT.cpp", "UnreachableRT.cpp"] + +config.substitutions.append(("%llvm_bin_dir", config.llvm_obj_root)) +config.substitutions.append(("%llvm_src_dir", config.llvm_src_root)) diff --git a/llvm/include/llvm/Transforms/IPO/Instrumentor.h b/llvm/include/llvm/Transforms/IPO/Instrumentor.h index 701498bb830b9..796104944f7a1 100644 --- a/llvm/include/llvm/Transforms/IPO/Instrumentor.h +++ b/llvm/include/llvm/Transforms/IPO/Instrumentor.h @@ -649,6 +649,27 @@ struct AllocaIO final : public InstructionIO<Instruction::Alloca> { } }; +struct UnreachableIO final : public InstructionIO<Instruction::Unreachable> { + UnreachableIO() : InstructionIO<Instruction::Unreachable>(/*IsPRE*/ true) {} + + enum ConfigKind { + PassId, + NumConfig, + }; + + using ConfigTy = BaseConfigTy<ConfigKind>; + ConfigTy Config; + + void init(InstrumentationConfig &IConf, LLVMContext &Ctx, + ConfigTy *UserConfig = nullptr); + + static void populate(InstrumentationConfig &IConf, LLVMContext &Ctx, + ConfigTy *UserConfig = nullptr) { + auto *PreIO = IConf.allocate<UnreachableIO>(); + PreIO->init(IConf, Ctx, UserConfig); + } +}; + /// The instrumentation opportunity for store instructions. struct StoreIO : public InstructionIO<Instruction::Store> { virtual ~StoreIO() {}; diff --git a/llvm/lib/Transforms/IPO/Instrumentor.cpp b/llvm/lib/Transforms/IPO/Instrumentor.cpp index 3ba1a2b00a5f8..e42befada5ab2 100644 --- a/llvm/lib/Transforms/IPO/Instrumentor.cpp +++ b/llvm/lib/Transforms/IPO/Instrumentor.cpp @@ -353,6 +353,7 @@ BaseConfigurationOption::createStringOption(InstrumentationConfig &IConf, void InstrumentationConfig::populate(InstrumentorIRBuilderTy &IIRB) { /// List of all instrumentation opportunities. FunctionIO::populate(*this, IIRB.Ctx); + UnreachableIO::populate(*this, IIRB.Ctx); AllocaIO::populate(*this, IIRB.Ctx); LoadIO::populate(*this, IIRB); StoreIO::populate(*this, IIRB); @@ -747,6 +748,17 @@ Value *FunctionIO::isMainFunction(Value &V, Type &Ty, ///} +/// UnreachableIO +///{ +void UnreachableIO::init(InstrumentationConfig &IConf, LLVMContext &Ctx, + ConfigTy *UserConfig) { + if (UserConfig) + Config = *UserConfig; + addCommonArgs(IConf, Ctx, Config.has(PassId)); + IConf.addChoice(*this, Ctx); +} +///} + /// AllocaIO ///{ void AllocaIO::init(InstrumentationConfig &IConf, LLVMContext &Ctx, diff --git a/llvm/test/Instrumentation/Instrumentor/default_config.json b/llvm/test/Instrumentation/Instrumentor/default_config.json index 336dc20cfd5e0..01dd8f8a8f720 100644 --- a/llvm/test/Instrumentation/Instrumentor/default_config.json +++ b/llvm/test/Instrumentation/Instrumentor/default_config.json @@ -49,6 +49,11 @@ } }, "instruction_pre": { + "unreachable": { + "enabled": true, + "id": true, + "id.description": "A unique ID associated with the given instrumentor call" + }, "load": { "enabled": true, "pointer": true, _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
