[llvm] [Instrumentor] Fix large int comparisons in filter expressions (PR #227585)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 00:09:49 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Ethan Luis McDonough (EthanLuisMcDonough)

<details>
<summary>Changes</summary>

Fixes #<!-- -->226941

---
Full diff: https://github.com/llvm/llvm-project/pull/227585.diff


3 Files Affected:

- (modified) llvm/lib/Transforms/IPO/InstrumentorUtils.cpp (+16-17) 
- (added) llvm/test/Instrumentation/Instrumentor/i128_filter.ll (+38) 
- (added) llvm/test/Instrumentation/Instrumentor/i128_fiter_config.json (+9) 


``````````diff
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
+        }
+    }
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/227585


More information about the llvm-commits mailing list