JIT: A small CQ improvement for Equals/StartsWith unrolling (#76439)
authorEgor Bogatov <egorbo@gmail.com>
Sun, 2 Oct 2022 16:34:38 +0000 (18:34 +0200)
committerGitHub <noreply@github.com>
Sun, 2 Oct 2022 16:34:38 +0000 (18:34 +0200)
src/coreclr/jit/assertionprop.cpp
src/coreclr/jit/compiler.h
src/coreclr/jit/gentree.h

index aca2574..2176ac1 100644 (file)
@@ -175,6 +175,17 @@ bool IntegralRange::Contains(int64_t value) const
             }
             break;
 
+        case GT_CNS_INT:
+            if (node->IsIntegralConst(0) || node->IsIntegralConst(1))
+            {
+                return {SymbolicIntegerValue::Zero, SymbolicIntegerValue::One};
+            }
+            break;
+
+        case GT_QMARK:
+            return Union(ForNode(node->AsQmark()->ThenNode(), compiler),
+                         ForNode(node->AsQmark()->ElseNode(), compiler));
+
         case GT_CAST:
             return ForCastOutput(node->AsCast());
 
@@ -430,6 +441,12 @@ bool IntegralRange::Contains(int64_t value) const
     return {lowerBound, upperBound};
 }
 
+/* static */ IntegralRange IntegralRange::Union(IntegralRange range1, IntegralRange range2)
+{
+    return IntegralRange(min(range1.GetLowerBound(), range2.GetLowerBound()),
+                         max(range1.GetUpperBound(), range2.GetUpperBound()));
+}
+
 #ifdef DEBUG
 /* static */ void IntegralRange::Print(IntegralRange range)
 {
index 6850cd9..51b8764 100644 (file)
@@ -1268,6 +1268,7 @@ public:
     static IntegralRange ForNode(GenTree* node, Compiler* compiler);
     static IntegralRange ForCastInput(GenTreeCast* cast);
     static IntegralRange ForCastOutput(GenTreeCast* cast);
+    static IntegralRange Union(IntegralRange range1, IntegralRange range2);
 
 #ifdef DEBUG
     static void Print(IntegralRange range);
index 25f4084..0b0c2a3 100644 (file)
@@ -5707,6 +5707,16 @@ struct GenTreeQmark : public GenTreeOp
         assert((colon != nullptr) && colon->OperIs(GT_COLON));
     }
 
+    GenTree* ThenNode()
+    {
+        return gtOp2->AsColon()->ThenNode();
+    }
+
+    GenTree* ElseNode()
+    {
+        return gtOp2->AsColon()->ElseNode();
+    }
+
 #if DEBUGGABLE_GENTREE
     GenTreeQmark() : GenTreeOp()
     {