Skip to content

Instantly share code, notes, and snippets.

@raymondtay
Created September 21, 2025 03:48
Show Gist options
  • Save raymondtay/093bde5d001445d9dd38413b7d2c0341 to your computer and use it in GitHub Desktop.
Save raymondtay/093bde5d001445d9dd38413b7d2c0341 to your computer and use it in GitHub Desktop.
Driver program for the ValueTracking pass
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/DemandedBits.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Config/llvm-config.h" // LLVM_VERSION_MAJOR
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct VTPrinterPass : public PassInfoMixin<VTPrinterPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
const DataLayout &DL = F.getParent()->getDataLayout();
// Analyses commonly leveraged by ValueTracking
TargetLibraryInfo &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
AssumptionCache &AC = FAM.getResult<AssumptionAnalysis>(F);
// Build a SimplifyQuery "context bag"
SimplifyQuery Q(DL);
Q.TLI = &TLI;
Q.DT = &DT;
Q.AC = &AC;
// Q.AA can be set if you also fetch AAManager, but it's optional here.
errs() << "=== VTPrinter (LLVM " << LLVM_VERSION_STRING
<< ") on function: " << F.getName() << " ===\n";
for (Instruction &I : instructions(F)) {
Q.CxtI = &I; // context instruction helps dominance-aware facts
errs() << I << "\n";
// Integer facts
if (I.getType()->isIntegerTy()) {
unsigned BW = I.getType()->getIntegerBitWidth();
// LLVM 20 style: returns KnownBits
KnownBits KB = computeKnownBits(&I, DL, 0, &AC, &I, &DT);
bool NonZero = isKnownNonZero(&I, Q);
unsigned NSB = ComputeNumSignBits(&I, DL, 0, &AC, &I, &DT);
bool IsPow2 = isKnownToBeAPowerOfTwo(&I, DL, false, 0, &AC, &I, &DT);
SmallString<64> ZStr, OStr;
KB.Zero.toString(ZStr, /*Radix=*/16, /*Signed=*/false);
KB.One.toString(OStr, /*Radix=*/16, /*Signed=*/false);
errs() << " KnownZero: 0x" << ZStr << "\n";
errs() << " KnownOne : 0x" << OStr << "\n";
errs() << " KnownNonZero: " << (NonZero ? "yes" : "no") << "\n";
errs() << " NumSignBits: " << NSB << "\n";
errs() << " IsPowerOfTwo: " << (IsPow2 ? "yes" : "no") << "\n";
// Demanded bits (low 8)
if (BW >= 8) {
APInt Demanded(BW, 0xFF);
KnownBits Known(BW);
Known = computeKnownBits(&I, DL);
APInt DemandedOnes = Known.One & Demanded;
APInt DemandedZeros = Known.Zero & Demanded;
errs() << " Ones in demanded bits: " << DemandedOnes << "\n";
errs() << " Zeros in demanded bits: " << DemandedZeros << "\n";
}
}
// Floating-point facts
if (I.getType()->isFloatingPointTy()) {
KnownFPClass FC = computeKnownFPClass(&I, DL, llvm::fcSubnormal, 0,
&TLI, &AC, &I, &DT);
errs() << " FP Known: " << (FC.isKnownNeverNaN() ? "!NaN " : "")
<< (FC.isKnownNeverNegZero() ? "!-0 " : "")
<< (FC.isKnownNeverInfinity() ? "!Inf " : "") << "\n";
}
// Poison/undef guard (name differs pre-20 vs 20)
#if LLVM_VERSION_MAJOR >= 20
bool NotPoisonOrUndef =
isGuaranteedNotToBeUndefOrPoison(&I, &AC, &I, &DT);
#else
bool NotPoisonOrUndef = isGuaranteedNotToBeUndefOrPoison(&I, Q);
#endif
errs() << " NotUndefOrPoison: " << (NotPoisonOrUndef ? "yes" : "no")
<< "\n";
}
return PreservedAnalyses::all();
}
};
} // namespace
// New PM plugin entry point (tested on LLVM 20)
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
return {LLVM_PLUGIN_API_VERSION, "VTPrinter", LLVM_VERSION_STRING,
[](PassBuilder &PB) {
PB.registerPipelineParsingCallback(
[](StringRef Name, FunctionPassManager &FPM,
ArrayRef<PassBuilder::PipelineElement>) {
if (Name == "vt-printer") {
FPM.addPass(VTPrinterPass());
return true;
}
return false;
});
}};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment