diff --git a/llvm/include/llvm/Analysis/LazyValueInfo.h b/llvm/include/llvm/Analysis/LazyValueInfo.h index f013a4a75d3d6a..ead9f5f0225cd0 100644 --- a/llvm/include/llvm/Analysis/LazyValueInfo.h +++ b/llvm/include/llvm/Analysis/LazyValueInfo.h @@ -151,6 +151,17 @@ class LazyValueAnalysis : public AnalysisInfoMixin { friend struct AnalysisInfoMixin; }; +/// Printer pass for the LazyValueAnalysis results. +class LazyValueInfoPrinterPass + : public PassInfoMixin { + raw_ostream &OS; + +public: + explicit LazyValueInfoPrinterPass(raw_ostream &OS) : OS(OS) {} + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + /// Wrapper around LazyValueInfo. class LazyValueInfoWrapperPass : public FunctionPass { LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete; diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 5cb207c8036d40..868824285301a0 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -2087,6 +2087,15 @@ void LazyValueInfoAnnotatedWriter::emitInstructionAnnot( } +PreservedAnalyses LazyValueInfoPrinterPass::run(Function &F, + FunctionAnalysisManager &AM) { + OS << "LVI for function '" << F.getName() << "':\n"; + auto &LVI = AM.getResult(F); + auto &DTree = AM.getResult(F); + LVI.printLVI(F, DTree, OS); + return PreservedAnalyses::all(); +} + namespace { // Printer class for LazyValueInfo results. class LazyValueInfoPrinter : public FunctionPass { diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 2067fc473b522d..199a8e4622e35a 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -400,6 +400,7 @@ FUNCTION_PASS("print", FunctionPropertiesPrinterPass(dbgs())) FUNCTION_PASS("print", InlineCostAnnotationPrinterPass(dbgs())) FUNCTION_PASS("print", InlineSizeEstimatorAnalysisPrinterPass(dbgs())) +FUNCTION_PASS("print", LazyValueInfoPrinterPass(dbgs())) FUNCTION_PASS("print", LoopPrinterPass(dbgs())) FUNCTION_PASS("print", MemorySSAWalkerPrinterPass(dbgs())) FUNCTION_PASS("print", PhiValuesPrinterPass(dbgs())) diff --git a/llvm/test/Analysis/LazyValueAnalysis/print.ll b/llvm/test/Analysis/LazyValueAnalysis/print.ll new file mode 100644 index 00000000000000..6b4938a5fd9e07 --- /dev/null +++ b/llvm/test/Analysis/LazyValueAnalysis/print.ll @@ -0,0 +1,49 @@ +; RUN: opt %s -disable-output -passes="jump-threading,print" 2>&1 | FileCheck %s + +; first to populate the values. + +define i32 @constraint(i32 %a) { +; CHECK-LABEL: LVI for function 'constraint': +chklt64: +; CHECK-LABEL: chklt64: +; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined +; CHECK-NEXT: ; LatticeVal for: ' %cmp = icmp slt i32 %a, 64' in BB: '%chklt64' is: overdefined +; CHECK-NEXT: ; LatticeVal for: ' %cmp = icmp slt i32 %a, 64' in BB: '%chkgt0' is: constantrange<-1, 0> +; CHECK-NEXT: ; LatticeVal for: ' %cmp = icmp slt i32 %a, 64' in BB: '%notinbounds' is: overdefined +; CHECK-NEXT: %cmp = icmp slt i32 %a, 64 +; CHECK-NEXT: ; LatticeVal for: ' br i1 %cmp, label %chkgt0, label %notinbounds' in BB: '%chklt64' is: overdefined +; CHECK-NEXT: ; LatticeVal for: ' br i1 %cmp, label %chkgt0, label %notinbounds' in BB: '%chkgt0' is: overdefined +; CHECK-NEXT: ; LatticeVal for: ' br i1 %cmp, label %chkgt0, label %notinbounds' in BB: '%notinbounds' is: overdefined +; CHECK-NEXT: br i1 %cmp, label %chkgt0, label %notinbounds + %cmp = icmp slt i32 %a, 64 + br i1 %cmp, label %chkgt0, label %notinbounds + +chkgt0: +; CHECK-LABEL: chkgt0: +; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: constantrange<-2147483648, 64> +; CHECK-NEXT: ; LatticeVal for: ' %cmp1 = icmp sgt i32 %a, 0' in BB: '%chkgt0' is: overdefined +; CHECK-NEXT: ; LatticeVal for: ' %cmp1 = icmp sgt i32 %a, 0' in BB: '%inbounds' is: constantrange<-1, 0> +; CHECK-NEXT: %cmp1 = icmp sgt i32 %a, 0 +; CHECK-NEXT: ; LatticeVal for: ' br i1 %cmp1, label %inbounds, label %notinbounds' in BB: '%chkgt0' is: overdefined +; CHECK-NEXT: ; LatticeVal for: ' br i1 %cmp1, label %inbounds, label %notinbounds' in BB: '%inbounds' is: overdefined +; CHECK-NEXT: br i1 %cmp1, label %inbounds, label %notinbounds + %cmp1 = icmp sgt i32 %a, 0 + br i1 %cmp1, label %inbounds, label %notinbounds + +inbounds: +; CHECK-LABEL: inbounds: +; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: constantrange<1, 64> +; CHECK-NEXT: ; LatticeVal for: ' ret i32 %a' in BB: '%inbounds' is: overdefined +; CHECK-NEXT: ret i32 %a + ret i32 %a + +notinbounds: +; CHECK-LABEL: notinbounds: +; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: constantrange<64, 1> +; CHECK-NEXT: ; LatticeVal for: ' %sum = add i32 %a, 64' in BB: '%notinbounds' is: constantrange<128, 65> +; CHECK-NEXT: %sum = add i32 %a, 64 +; CHECK-NEXT: ; LatticeVal for: ' ret i32 %sum' in BB: '%notinbounds' is: overdefined +; CHECK-NEXT: ret i32 %sum + %sum = add i32 %a, 64 + ret i32 %sum +}