Created
September 21, 2025 03:48
-
-
Save raymondtay/093bde5d001445d9dd38413b7d2c0341 to your computer and use it in GitHub Desktop.
Driver program for the ValueTracking pass
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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