[llvm-branch-commits] [NFCI] [ValueTracking] Add pass to print ConstantRanges (PR #140144)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu May 15 14:38:47 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Florian Mayer (fmayer)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/140144.diff
6 Files Affected:
- (modified) llvm/include/llvm/Analysis/ValueTracking.h (+15-1)
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+17)
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1)
- (modified) llvm/lib/Passes/PassRegistry.def (+1)
- (added) llvm/test/Analysis/ValueTracking/print-constant-range.ll (+234)
- (modified) llvm/utils/UpdateTestChecks/common.py (+1)
``````````diff
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 61dbb07e7128e..341c20931761a 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -19,9 +19,10 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/FMF.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/PassManager.h"
#include <cassert>
#include <cstdint>
@@ -1001,6 +1002,19 @@ std::optional<bool> isImpliedByDomCondition(CmpPredicate Pred, const Value *LHS,
void findValuesAffectedByCondition(Value *Cond, bool IsAssume,
function_ref<void(Value *)> InsertAffected);
+/// Printer pass for \p computeConstantRange results.
+class ConstantRangePrinterPass
+ : public PassInfoMixin<ConstantRangePrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit ConstantRangePrinterPass(raw_ostream &OS) : OS(OS) {}
+
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+ static bool isRequired() { return true; }
+};
+
} // end namespace llvm
#endif // LLVM_ANALYSIS_VALUETRACKING_H
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3d403531cea2f..3ebbf887b3e6c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -49,6 +49,7 @@
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -10451,3 +10452,19 @@ void llvm::findValuesAffectedByCondition(
}
}
}
+
+PreservedAnalyses ConstantRangePrinterPass::run(Function &F,
+ FunctionAnalysisManager &AM) {
+ // For compatibility with opt's -analyze feature under legacy pass manager
+ // which was not ported to NPM. This keeps tests using
+ // update_analyze_test_checks.py working.
+ OS << "Printing analysis 'ConstantRange' for function '" << F.getName()
+ << "':\n";
+ for (const Instruction &I : instructions(F)) {
+ if (!I.getType()->isIntOrIntVectorTy())
+ continue;
+ auto CR = computeConstantRange(&I, false);
+ OS << I << ": " << CR << "\n";
+ }
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 7740f622ede7c..060c1b535befd 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -78,6 +78,7 @@
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
#include "llvm/Analysis/UniformityAnalysis.h"
+#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
#include "llvm/CodeGen/AtomicExpand.h"
#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index ea792280ed975..8cbc6a1156c51 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -462,6 +462,7 @@ FUNCTION_PASS("print<phi-values>", PhiValuesPrinterPass(errs()))
FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(errs()))
FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(errs()))
FUNCTION_PASS("print<scalar-evolution>", ScalarEvolutionPrinterPass(errs()))
+FUNCTION_PASS("print<constant-range>", ConstantRangePrinterPass(errs()))
FUNCTION_PASS("print<stack-safety-local>", StackSafetyPrinterPass(errs()))
FUNCTION_PASS("print<uniformity>", UniformityInfoPrinterPass(errs()))
FUNCTION_PASS("reassociate", ReassociatePass())
diff --git a/llvm/test/Analysis/ValueTracking/print-constant-range.ll b/llvm/test/Analysis/ValueTracking/print-constant-range.ll
new file mode 100644
index 0000000000000..ad444551e9adc
--- /dev/null
+++ b/llvm/test/Analysis/ValueTracking/print-constant-range.ll
@@ -0,0 +1,234 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -disable-output '-passes=print<constant-range>' < %s -S 2>&1 | FileCheck %s
+
+define i1 @shl_C_X_ugt(i8 %x) {
+; CHECK-LABEL: 'shl_C_X_ugt'
+; CHECK-NEXT: %shl = shl i8 7, %x: [1,-31)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -32: full-set
+;
+ %shl = shl i8 7, %x
+ %r = icmp ugt i8 %shl, 224
+ ret i1 %r
+}
+
+define i1 @shl_C_X_ugt2(i8 %x) {
+; CHECK-LABEL: 'shl_C_X_ugt2'
+; CHECK-NEXT: %shl = shl i8 5, %x: [1,-63)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -64: full-set
+;
+ %shl = shl i8 5, %x
+ %r = icmp ugt i8 %shl, 192
+ ret i1 %r
+}
+
+define i1 @shl_C_X_ugt_fail(i8 %x) {
+; CHECK-LABEL: 'shl_C_X_ugt_fail'
+; CHECK-NEXT: %shl = shl i8 1, %x: [1,-127)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, 127: full-set
+;
+ %shl = shl i8 1, %x
+ %r = icmp ugt i8 %shl, 127
+ ret i1 %r
+}
+
+define i1 @shl_C_X_ugt_fail2(i8 %x) {
+; CHECK-LABEL: 'shl_C_X_ugt_fail2'
+; CHECK-NEXT: %shl = shl i8 3, %x: [1,-63)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -66: full-set
+;
+ %shl = shl i8 3, %x
+ %r = icmp ugt i8 %shl, 190
+ ret i1 %r
+}
+
+define i1 @shl_C_X_ugt_fail3(i8 %x) {
+; CHECK-LABEL: 'shl_C_X_ugt_fail3'
+; CHECK-NEXT: %shl = shl i8 -1, %x: [1,0)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -2: full-set
+;
+ %shl = shl i8 -1, %x
+ %r = icmp ugt i8 %shl, 254
+ ret i1 %r
+}
+
+define i1 @shl_C_X_ugt_todo(i8 %x) {
+; CHECK-LABEL: 'shl_C_X_ugt_todo'
+; CHECK-NEXT: %shl = shl i8 -127, %x: [1,-63)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -116: full-set
+;
+ %shl = shl i8 129, %x
+ %r = icmp ugt i8 %shl, 140
+ ret i1 %r
+}
+
+define i1 @shl_X_C_ugt(i8 %x) {
+; CHECK-LABEL: 'shl_X_C_ugt'
+; CHECK-NEXT: %shl = shl i8 %x, 6: [0,-63)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -64: full-set
+;
+ %shl = shl i8 %x, 6
+ %r = icmp ugt i8 %shl, 192
+ ret i1 %r
+}
+
+define i1 @shl_X_C_ugt_fail(i8 %x) {
+; CHECK-LABEL: 'shl_X_C_ugt_fail'
+; CHECK-NEXT: %shl = shl i8 %x, 6: [0,-63)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -65: full-set
+;
+ %shl = shl i8 %x, 6
+ %r = icmp ugt i8 %shl, 191
+ ret i1 %r
+}
+
+define i1 @shl_X_C_ugt_fail2(i8 %x) {
+; CHECK-LABEL: 'shl_X_C_ugt_fail2'
+; CHECK-NEXT: %shl = shl i8 %x, 5: [0,-31)
+; CHECK-NEXT: %r = icmp ugt i8 %shl, -64: full-set
+;
+ %shl = shl i8 %x, 5
+ %r = icmp ugt i8 %shl, 192
+ ret i1 %r
+}
+
+define i1 @and_ugt(i8 %xx) {
+; CHECK-LABEL: 'and_ugt'
+; CHECK-NEXT: %x = mul i8 %xx, %xx: full-set
+; CHECK-NEXT: %negx = sub i8 0, %x: full-set
+; CHECK-NEXT: %x_p2 = and i8 %negx, %x: [0,-127)
+; CHECK-NEXT: %r = icmp ugt i8 %x_p2, -128: full-set
+;
+ %x = mul i8 %xx, %xx ; thwart complexity-based canonicalization
+ %negx = sub i8 0, %x
+ %x_p2 = and i8 %negx, %x
+ %r = icmp ugt i8 %x_p2, 128
+ ret i1 %r
+}
+
+define i1 @and_ugt2(i8 %xx) {
+; CHECK-LABEL: 'and_ugt2'
+; CHECK-NEXT: %x = mul i8 %xx, %xx: full-set
+; CHECK-NEXT: %negx = sub i8 0, %x: full-set
+; CHECK-NEXT: %x_p2 = and i8 %x, %negx: [0,-127)
+; CHECK-NEXT: %r = icmp ugt i8 %x_p2, -128: full-set
+;
+ %x = mul i8 %xx, %xx ; thwart complexity-based canonicalization
+ %negx = sub i8 0, %x
+ %x_p2 = and i8 %x, %negx
+ %r = icmp ugt i8 %x_p2, 128
+ ret i1 %r
+}
+
+define i1 @and_ugt_fail(i8 %xx) {
+; CHECK-LABEL: 'and_ugt_fail'
+; CHECK-NEXT: %x = mul i8 %xx, %xx: full-set
+; CHECK-NEXT: %negx = sub i8 0, %x: full-set
+; CHECK-NEXT: %x_p2 = and i8 %x, %negx: [0,-127)
+; CHECK-NEXT: %r = icmp ugt i8 %x_p2, 127: full-set
+;
+ %x = mul i8 %xx, %xx ; thwart complexity-based canonicalization
+ %negx = sub i8 0, %x
+ %x_p2 = and i8 %x, %negx
+ %r = icmp ugt i8 %x_p2, 127
+ ret i1 %r
+}
+
+define i1 @urem_okay(i8 %x) {
+; CHECK-LABEL: 'urem_okay'
+; CHECK-NEXT: %val = urem i8 34, %x: [0,35)
+; CHECK-NEXT: %r = icmp ule i8 %val, 35: full-set
+;
+ %val = urem i8 34, %x
+ %r = icmp ule i8 %val, 35
+ ret i1 %r
+}
+
+define i1 @urem_fail(i8 %x) {
+; CHECK-LABEL: 'urem_fail'
+; CHECK-NEXT: %val = urem i8 34, %x: [0,35)
+; CHECK-NEXT: %r = icmp ule i8 %val, 33: full-set
+;
+ %val = urem i8 34, %x
+ %r = icmp ule i8 %val, 33
+ ret i1 %r
+}
+
+define i1 @srem_posC_okay0(i8 %x) {
+; CHECK-LABEL: 'srem_posC_okay0'
+; CHECK-NEXT: %val = srem i8 34, %x: [0,35)
+; CHECK-NEXT: %r = icmp sle i8 %val, 34: full-set
+;
+ %val = srem i8 34, %x
+ %r = icmp sle i8 %val, 34
+ ret i1 %r
+}
+
+define i1 @srem_posC_okay1(i8 %x) {
+; CHECK-LABEL: 'srem_posC_okay1'
+; CHECK-NEXT: %val = srem i8 34, %x: [0,35)
+; CHECK-NEXT: %r = icmp sge i8 %val, -3: full-set
+;
+ %val = srem i8 34, %x
+ %r = icmp sge i8 %val, -3
+ ret i1 %r
+}
+
+define i1 @srem_negC_okay0(i8 %x) {
+; CHECK-LABEL: 'srem_negC_okay0'
+; CHECK-NEXT: %val = srem i8 -34, %x: [-34,1)
+; CHECK-NEXT: %r = icmp sle i8 %val, 0: full-set
+;
+ %val = srem i8 -34, %x
+ %r = icmp sle i8 %val, 0
+ ret i1 %r
+}
+
+define i1 @srem_negC_okay1(i8 %x) {
+; CHECK-LABEL: 'srem_negC_okay1'
+; CHECK-NEXT: %val = srem i8 -34, %x: [-34,1)
+; CHECK-NEXT: %r = icmp sge i8 %val, -34: full-set
+;
+ %val = srem i8 -34, %x
+ %r = icmp sge i8 %val, -34
+ ret i1 %r
+}
+
+define i1 @srem_posC_fail0(i8 %x) {
+; CHECK-LABEL: 'srem_posC_fail0'
+; CHECK-NEXT: %val = srem i8 34, %x: [0,35)
+; CHECK-NEXT: %r = icmp sle i8 %val, 32: full-set
+;
+ %val = srem i8 34, %x
+ %r = icmp sle i8 %val, 32
+ ret i1 %r
+}
+
+define i1 @srem_posC_fail1(i8 %x) {
+; CHECK-LABEL: 'srem_posC_fail1'
+; CHECK-NEXT: %val = srem i8 34, %x: [0,35)
+; CHECK-NEXT: %r = icmp sge i8 %val, 1: full-set
+;
+ %val = srem i8 34, %x
+ %r = icmp sge i8 %val, 1
+ ret i1 %r
+}
+
+define i1 @srem_negC_fail0(i8 %x) {
+; CHECK-LABEL: 'srem_negC_fail0'
+; CHECK-NEXT: %val = srem i8 -34, %x: [-34,1)
+; CHECK-NEXT: %r = icmp sle i8 %val, -1: full-set
+;
+ %val = srem i8 -34, %x
+ %r = icmp sle i8 %val, -1
+ ret i1 %r
+}
+
+define i1 @srem_negC_fail1(i8 %x) {
+; CHECK-LABEL: 'srem_negC_fail1'
+; CHECK-NEXT: %val = srem i8 -34, %x: [-34,1)
+; CHECK-NEXT: %r = icmp sge i8 %val, -33: full-set
+;
+ %val = srem i8 -34, %x
+ %r = icmp sge i8 %val, -33
+ ret i1 %r
+}
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index d150612dd368e..5d57536b010b6 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -38,6 +38,7 @@
"Dependence Analysis",
"Loop Access Analysis",
"Scalar Evolution Analysis",
+ "ConstantRange",
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/140144
More information about the llvm-branch-commits
mailing list