[llvm] [Instrumentor] Fix large int comparisons in filter expressions (PR #227585)
Ethan Luis McDonough via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 00:09:05 PDT 2026
https://github.com/EthanLuisMcDonough created https://github.com/llvm/llvm-project/pull/227585
Fixes #226941
>From 84bde73aed2c0b274fb51ca5edbba1f5c37fa002 Mon Sep 17 00:00:00 2001
From: Ethan Luis McDonough <emcdonou at qti.qualcomm.com>
Date: Wed, 30 Sep 2026 00:02:17 -0700
Subject: [PATCH] Fix large int comparisons in filter
---
llvm/lib/Transforms/IPO/InstrumentorUtils.cpp | 33 ++++++++--------
.../Instrumentor/i128_filter.ll | 38 +++++++++++++++++++
.../Instrumentor/i128_fiter_config.json | 9 +++++
3 files changed, 63 insertions(+), 17 deletions(-)
create mode 100644 llvm/test/Instrumentation/Instrumentor/i128_filter.ll
create mode 100644 llvm/test/Instrumentation/Instrumentor/i128_fiter_config.json
diff --git a/llvm/lib/Transforms/IPO/InstrumentorUtils.cpp b/llvm/lib/Transforms/IPO/InstrumentorUtils.cpp
index 79a7ccce939f6..7f419204c7da3 100644
--- a/llvm/lib/Transforms/IPO/InstrumentorUtils.cpp
+++ b/llvm/lib/Transforms/IPO/InstrumentorUtils.cpp
@@ -26,7 +26,7 @@ enum PropertyType { INT, STRING, POINTER, UNKNOWN };
/// (startswith), and logical operators (&&, ||).
class FilterEvaluator {
StringRef Expr;
- DenseMap<StringRef, int64_t> &IntPropertyValues;
+ DenseMap<StringRef, APInt> &IntPropertyValues;
DenseMap<StringRef, StringRef> &StringPropertyValues;
DenseMap<StringRef, Value *> &PointerPropertyValues;
DenseMap<StringRef, PropertyType> &DynamicProperties;
@@ -34,8 +34,7 @@ class FilterEvaluator {
size_t Pos = 0;
public:
- FilterEvaluator(StringRef Expr,
- DenseMap<StringRef, int64_t> &IntPropertyValues,
+ FilterEvaluator(StringRef Expr, DenseMap<StringRef, APInt> &IntPropertyValues,
DenseMap<StringRef, StringRef> &StringPropertyValues,
DenseMap<StringRef, Value *> &PointerPropertyValues,
DenseMap<StringRef, PropertyType> &DynamicProperties,
@@ -188,7 +187,7 @@ class FilterEvaluator {
auto FlagNameIt = FlagNameVals.find(FieldName);
if (FlagNameIt == FlagNameVals.end())
return createStringError("Invalid flag '" + FieldName + "'");
- return ((static_cast<int32_t>(FlagValIt->second) &
+ return ((static_cast<int32_t>(FlagValIt->second.getZExtValue()) &
FlagNameIt->second) == FlagNameIt->second) ^
LogicalNot;
}
@@ -243,7 +242,7 @@ class FilterEvaluator {
// Check if this is an integer property.
auto IntIt = IntPropertyValues.find(PropName);
if (IntIt != IntPropertyValues.end()) {
- int64_t LHS = IntIt->second;
+ auto LHS = IntIt->second;
// Parse operator.
enum OpKind { EQ, NE, LT, GT, LE, GE } Op;
@@ -290,10 +289,12 @@ class FilterEvaluator {
}
size_t DigitStart = Pos;
+ uint8_t DigitRadix = 10;
// Parse binary literals.
if (Pos + 1 < Expr.size() && Expr[Pos] == '0' && Expr[Pos + 1] == 'b') {
- Pos += 2;
+ DigitStart = (Pos += 2);
+ DigitRadix = 2;
while (Pos < Expr.size() && (Expr[Pos] == '0' || Expr[Pos] == '1'))
++Pos;
} else {
@@ -306,13 +307,11 @@ class FilterEvaluator {
return createStringError("expected integer value at position " +
std::to_string(Pos));
- StringRef ValueStr = Expr.slice(Start, Pos);
- int64_t RHS = 0;
- if (ValueStr.getAsInteger(0, RHS))
- return createStringError("invalid integer value '" + ValueStr + "'");
+ StringRef ValueStr = Expr.slice(DigitStart, Pos);
+ APInt RHS(LHS.getBitWidth(), ValueStr, DigitRadix);
if (Negative)
- RHS = -RHS;
+ RHS.negate();
// Evaluate comparison.
switch (Op) {
@@ -321,13 +320,13 @@ class FilterEvaluator {
case NE:
return LHS != RHS;
case LT:
- return LHS < RHS;
+ return LHS.slt(RHS);
case GT:
- return LHS > RHS;
+ return LHS.sgt(RHS);
case LE:
- return LHS <= RHS;
+ return LHS.sle(RHS);
case GE:
- return LHS >= RHS;
+ return LHS.sge(RHS);
}
return true;
}
@@ -450,7 +449,7 @@ bool llvm::instrumentor::evaluateFilter(Value &V, bool &Changed,
return true;
// Collect constant property values for filter evaluation.
- DenseMap<StringRef, int64_t> IntPropertyValues;
+ DenseMap<StringRef, APInt> IntPropertyValues;
DenseMap<StringRef, StringRef> StringPropertyValues;
DenseMap<StringRef, Value *> PointerPropertyValues;
DenseMap<StringRef, PropertyType> DynamicProperties;
@@ -470,7 +469,7 @@ bool llvm::instrumentor::evaluateFilter(Value &V, bool &Changed,
if (auto *CI = dyn_cast<ConstantInt>(ArgValue)) {
// Check for constant integer values.
- IntPropertyValues[Arg.Name] = CI->getSExtValue();
+ IntPropertyValues[Arg.Name] = CI->getValue();
} else if ((Arg.Flags & IRTArg::STRING) && isa<Constant>(ArgValue)) {
// Check for constant string values (marked with STRING flag).
if (auto *GV = dyn_cast<GlobalVariable>(ArgValue))
diff --git a/llvm/test/Instrumentation/Instrumentor/i128_filter.ll b/llvm/test/Instrumentation/Instrumentor/i128_filter.ll
new file mode 100644
index 0000000000000..abe62c72bf14a
--- /dev/null
+++ b/llvm/test/Instrumentation/Instrumentor/i128_filter.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=instrumentor -instrumentor-read-config-files=%S/i128_filter_config.json -S 2>&1 | FileCheck %s
+
+define i1 @compare_wide_skip(i128 %value) {
+; CHECK-LABEL: define i1 @compare_wide_skip(
+; CHECK-SAME: i128 [[VALUE:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP_SKIP:%.*]] = icmp eq i128 [[VALUE]], 18446744073709551616
+; CHECK-NEXT: ret i1 [[CMP_SKIP]]
+;
+entry:
+ %cmp.skip = icmp eq i128 %value, 18446744073709551616
+ ret i1 %cmp.skip
+}
+
+define i1 @compare_wide_inst(i128 %value) {
+; CHECK-LABEL: define i1 @compare_wide_inst(
+; CHECK-SAME: i128 [[VALUE:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP_INST:%.*]] = icmp eq i128 [[VALUE]], 5
+; CHECK-NEXT: ret i1 [[CMP_INST]]
+;
+entry:
+ %cmp.inst = icmp eq i128 %value, 5
+ ret i1 %cmp.inst
+}
+
+define i1 @compare_wide_inst_neg(i128 %value) {
+; CHECK-LABEL: define i1 @compare_wide_inst_neg(
+; CHECK-SAME: i128 [[VALUE:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP_INST:%.*]] = icmp eq i128 [[VALUE]], -25
+; CHECK-NEXT: ret i1 [[CMP_INST]]
+;
+entry:
+ %cmp.inst = icmp eq i128 %value, -25
+ ret i1 %cmp.inst
+}
diff --git a/llvm/test/Instrumentation/Instrumentor/i128_fiter_config.json b/llvm/test/Instrumentation/Instrumentor/i128_fiter_config.json
new file mode 100644
index 0000000000000..942c4b68c5df1
--- /dev/null
+++ b/llvm/test/Instrumentation/Instrumentor/i128_fiter_config.json
@@ -0,0 +1,9 @@
+{
+ "instruction_pre": {
+ "compare": {
+ "enabled": true,
+ "filter":"right==0b101||right==-25",
+ "right":true
+ }
+ }
+}
More information about the llvm-commits
mailing list