All notable changes to LLTFI are recorded here. Format follows Keep a Changelog.
This release upgrades LLTFI from LLVM 15 to LLVM 20. Every change is
backward-compatible with LLFI. The full migration narrative, task breakdown,
and effort accounting are in migration.md.
- LLVM version requirement raised from 15 to 20. LLVM 15 is no longer
supported. Install LLVM 20 via the LLVM apt repository or build from source
(see
README.md). - Legacy pass manager (
opt -load,-enable-new-pm=0) removed. All passes — includingInstructionDuplication— now use the new pass manager exclusively. Any external scripts callingoptdirectly must be updated to use-load-pass-pluginand--passes=<PassName>. InstructionDuplicationpass renamed toInstructionDuplicationPassin the plugin registry to match the new PM convention.
InstructionDuplicationmigrated to the new pass manager (PassInfoMixin); exposed as"InstructionDuplicationPass"inSEDPasses.so.- Two new tests in
test_instruction_duplication.py:real_model_structural— appliesInstructionDuplicationPassto a real onnx-mlirmodel.lland verifiescompareFloatValuescalls are inserted.real_model_end_to_end— runs the baseline and duplicated models throughlliand asserts outputs are identical (SKIP whenmodel.llabsent).
lint.sh— unified C++ and Python lint runner;--fixauto-formats in-place..clang-tidy— project-level tidy config with intentionally disabled checks documented..clang-format— project-level format config (LLVM style, 2-space indent).setup.cfg—flake8andflake8-bugbearconfiguration for Python linting.
architecture.md— new developer reference covering pass pipeline, selector class hierarchy, hardware/software/ML fault modes, the runtime library, and the interface between compile-time and runtime layers.docs/input_yaml_guide.md— prose guide to writinginput.yamlfiles, covering all keys,CustomTensorOperatorML targeting, and complete examples.docs/tutorial_first_experiment.md— end-to-end walkthrough of thefactorialexperiment including output file interpretation and outcome classification (masked / SDC / crash / hang).docs/adding_a_test.md— step-by-step guide for adding a regression test, covering program registration, test case structure, custom Python scripts, and the SKIP convention.CODING_GUIDELINES.md— expanded with sections onoverride, variable initialisation, container emptiness (.empty()over.size() == 0), andcast<>vs.dyn_cast<>.CONTRIBUTING.md— addedAdding a Test Casesection pointing todocs/adding_a_test.md.docs/tutorial_ml_experiment.md— new end-to-end walkthrough of an ML/ONNX fault injection experiment covering the full ONNX → LLVM IR compilation pipeline,CustomTensorOperatorlayer targeting, multi-fault injection options, per-layer profiling output, andCompareLayerOutputs.py.
| File | Change |
|---|---|
llvm_passes/core/FaultInjectionPass.cpp |
3 sites: new AllocaInst/StoreInst/LoadInst constructors updated to LLVM 17+ API |
llvm_passes/core/InstTracePass.cpp |
6 sites: same; getFirstNonPHIOrDbgOrLifetime() now returns BasicBlock::iterator |
llvm_passes/core/Utils.cpp |
M.getGlobalList().push_back() → new GlobalVariable(M, ...) (removed in LLVM 17) |
All selector .cpp files |
getNumArgOperands() → arg_size() (removed in LLVM 15); #include "llvm/Support/CFG.h" → "llvm/IR/CFG.h" |
llvm_passes/instruction_duplication/InstructionDuplication.cpp |
getNextNonDebugInstruction() return type updated to BasicBlock::iterator |
| Category | Details |
|---|---|
| Bug fixes | Double-free in Controller.cpp destructor; file stream leak in LLFIDotGraphPass.cpp; unchecked fopen null in GenLLFIIndexPass.cpp; uninitialized isChainDuplication field |
| Null safety | getCalledFunction() null checks in ProfilingPass.cpp, InstructionDuplication.cpp, CustomTensorOperatorInstSelector.cpp |
| LLVM idioms | dyn_cast<> after isa<> → cast<> (asserting) across Utils.cpp, ProfilingPass.cpp; NULL → nullptr throughout |
| Override safety | virtual on override methods → override keyword across all selector classes; virtual ~Base() = default added to abstract base classes |
| Style | .empty() over .size() == 0; const auto& in range-for; strncpy/strncat over unbounded strcpy/strcat; cl::opt<T>::getValue() to avoid slicing |
| Dead code | Removed unreachable return false after exhaustive if/else in InstructionDuplication.cpp:runOnMainGraph() |
| Copies | for (auto insVector : arithInst) → for (const auto& insVector : ...) to avoid copying inner vectors |
except:→except Exception:throughoutbin/,tools/,test_suite/SCRIPTS/- Bare
open()→with open(...) as f:in multiple scripts subprocess(..., shell=True)removed; replaced with list-form callsyaml.load()→yaml.safe_load()everywhereexit()→sys.exit()in scripts%-formatstrings → f-strings in new code
docker/Dockerfile— LLVM source checkout updated from a pinned LLVM 15 commit hash (9778ec057cf4) to thellvmorg-20.1.0tag;pyyaml===5.4.1corrected topyyaml==5.4.1(non-standard triple-equals syntax).
README.md— restructured to eliminate overlap witharchitecture.md; addeddocs/section listing all user guides; added pointer toarchitecture.mdfor internal design.caveats.txt— LLVM version references updated 15 → 20; duplicate item number fixed.llvm_passes/instruction_duplication/README.md—opt -always-inline(legacy PM) →opt --passes=always-inline(new PM).llvm_passes/instruction_duplication/shared_lib/build.shandcompile_shrd_lib.sh— hardcodedclang/clang++→LLVM_GXX_BIN_DIRpattern, fixing builds on Ubuntu where apt installsclang-20only.architecture.md— corrected several inaccuracies found during code review:preFuncreturn type (boolnotint) and parameter types (unsignedthroughout);injectFuncregister parameter types;doProfilingparameter type (intnotunsigned);printInstTracersignature (second param ischar *opcode, notunsigned; last param isint, notlong);lltfiMLLayerparameter types (int64_t); removed non-existentrandomanddata_corruptionfi_typeentries; corrected claim that
- H-2 — Human review of IRBuilder insertion-point correctness in
FaultInjectionPass.cppandInstTracePass.cpp. TheAllocaInstcalls were migrated toBasicBlock*insertAtEnd form andBasicBlock::iteratorform respectively; both compile and all 21 tests pass, but a developer familiar with the pass semantics should verify the insertion points are logically correct before merging to main. - H-3 — onnx-mlir real-model validation. Requires installing onnx-mlir and
running
sample_programs/ml_sample_programs/vision_models/mnist/compile.shto producemodel.ll. The two newtest_instruction_duplication.pytests will then run instead of skipping. Not a blocker — all other tests pass.
The master branch represents LLTFI as it existed targeting LLVM 15, with
the following improvements over the original LLFI fork:
- ML fault injection support (TensorFlow, PyTorch via ONNX-MLIR)
CustomTensorOperatorinstruction selector for layer-level ML targetingInstructionDuplicationpass (SEDPasses.so) for soft-error detection- Batch fault injection scripts (
batchInstrument.py,batchProfile.py,batchInjectfault.py) - Trace analysis tools (
tracediff.py,traceontograph.py,traceunion.py,tracetodot.py) - Makefile generation tool (
GenerateMakefile) - Initial
CODING_GUIDELINES.mdandCONTRIBUTING.md - Migration plan document (
migration.md) for the LLVM 15 → 20 upgrade