JIT: Fold null checks for const strings (#49930)
authorEgor Bogatov <egorbo@gmail.com>
Mon, 22 Mar 2021 07:06:55 +0000 (10:06 +0300)
committerGitHub <noreply@github.com>
Mon, 22 Mar 2021 07:06:55 +0000 (10:06 +0300)
src/coreclr/jit/valuenum.cpp
src/coreclr/jit/valuenumfuncs.h

index bae645e..b530c06 100644 (file)
@@ -8138,12 +8138,22 @@ void Compiler::fgValueNumberTree(GenTree* tree)
             if (tree->gtFlags & GTF_IND_INVARIANT)
             {
                 assert(!isVolatile); // We don't expect both volatile and invariant
-                tree->gtVNPair =
-                    ValueNumPair(vnStore->VNForMapSelect(VNK_Liberal, TYP_REF, ValueNumStore::VNForROH(),
-                                                         addrNvnp.GetLiberal()),
-                                 vnStore->VNForMapSelect(VNK_Conservative, TYP_REF, ValueNumStore::VNForROH(),
-                                                         addrNvnp.GetConservative()));
-                tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp);
+
+                // Is it a string literal? (it's always non-null)
+                if (addr->IsCnsIntOrI() && addr->IsIconHandle(GTF_ICON_STR_HDL))
+                {
+                    tree->gtVNPair = vnStore->VNPairForFunc(tree->TypeGet(), VNF_StrCns, addrNvnp);
+                    assert(addrXvnp.BothEqual() && (addrXvnp.GetLiberal() == ValueNumStore::VNForEmptyExcSet()));
+                }
+                else
+                {
+                    tree->gtVNPair =
+                        ValueNumPair(vnStore->VNForMapSelect(VNK_Liberal, TYP_REF, ValueNumStore::VNForROH(),
+                                                             addrNvnp.GetLiberal()),
+                                     vnStore->VNForMapSelect(VNK_Conservative, TYP_REF, ValueNumStore::VNForROH(),
+                                                             addrNvnp.GetConservative()));
+                    tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp);
+                }
             }
             else if (isVolatile)
             {
@@ -9598,7 +9608,7 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc)
             break;
 
         case CORINFO_HELP_STRCNS:
-            vnf = VNF_StrCns;
+            vnf = VNF_LazyStrCns;
             break;
 
         case CORINFO_HELP_CHKCASTCLASS:
index 1d3906d..9297115 100644 (file)
@@ -143,7 +143,8 @@ ValueNumFuncDef(JitReadyToRunNewArr, 3, false, true, false)
 ValueNumFuncDef(Box, 3, false, false, false)
 ValueNumFuncDef(BoxNullable, 3, false, false, false)
 
-ValueNumFuncDef(StrCns, 2, false, true, false)
+ValueNumFuncDef(LazyStrCns, 2, false, true, false)  // lazy-initialized string literal (helper)
+ValueNumFuncDef(StrCns, 1, false, true, false)      // indirect for a string literal
 ValueNumFuncDef(Unbox, 2, false, true, false)
 
 ValueNumFuncDef(LT_UN, 2, false, false, false)      // unsigned or unordered comparisons