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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits