Optimize u>=1 to u!=0 and u<1 to u==0 (dotnet/coreclr#25458)
authorEgor Bogatov <egorbo@gmail.com>
Wed, 16 Oct 2019 21:58:53 +0000 (00:58 +0300)
committerSergey Andreenko <seandree@microsoft.com>
Wed, 16 Oct 2019 21:58:53 +0000 (14:58 -0700)
* Optimize u >= 1 to u != 0 and u < 1 to u == 0 (u - unsigned)

* undo some changes

* make clang-format happy

* Address feedback

* Update morph.cpp

Commit migrated from https://github.com/dotnet/coreclr/commit/580024875e08a1569b847086ac54f3b549fff334

src/coreclr/src/jit/morph.cpp

index 3612bd263532714032d5e84ee06e8760fd6ca1be..91134e4f0f130bbad03d7e4b25b006adbb8b2ef5 100644 (file)
@@ -12364,69 +12364,62 @@ DONE_MORPHING_CHILDREN:
         case GT_GE:
         case GT_GT:
 
-            if ((tree->gtFlags & GTF_UNSIGNED) == 0)
+            if (op2->gtOper == GT_CNS_INT)
             {
-                if (op2->gtOper == GT_CNS_INT)
+                cns2 = op2;
+                /* Check for "expr relop 1" */
+                if (cns2->IsIntegralConst(1))
                 {
-                    cns2 = op2;
-                    /* Check for "expr relop 1" */
-                    if (cns2->IsIntegralConst(1))
+                    /* Check for "expr >= 1" */
+                    if (oper == GT_GE)
                     {
-                        /* Check for "expr >= 1" */
-                        if (oper == GT_GE)
-                        {
-                            /* Change to "expr > 0" */
-                            oper = GT_GT;
-                            goto SET_OPER;
-                        }
-                        /* Check for "expr < 1" */
-                        else if (oper == GT_LT)
-                        {
-                            /* Change to "expr <= 0" */
-                            oper = GT_LE;
-                            goto SET_OPER;
-                        }
+                        /* Change to "expr != 0" for unsigned and "expr > 0" for signed */
+                        oper = (tree->IsUnsigned()) ? GT_NE : GT_GT;
+                        goto SET_OPER;
                     }
-                    /* Check for "expr relop -1" */
-                    else if (cns2->IsIntegralConst(-1) && ((oper == GT_LE) || (oper == GT_GT)))
+                    /* Check for "expr 1" */
+                    else if (oper == GT_LT)
                     {
-                        /* Check for "expr <= -1" */
-                        if (oper == GT_LE)
-                        {
-                            /* Change to "expr < 0" */
-                            oper = GT_LT;
-                            goto SET_OPER;
-                        }
-                        /* Check for "expr > -1" */
-                        else if (oper == GT_GT)
-                        {
-                            /* Change to "expr >= 0" */
-                            oper = GT_GE;
-
-                        SET_OPER:
-                            // IF we get here we should be changing 'oper'
-                            assert(tree->OperGet() != oper);
+                        /* Change to "expr == 0" for unsigned and "expr <= 0" for signed */
+                        oper = (tree->IsUnsigned()) ? GT_EQ : GT_LE;
+                        goto SET_OPER;
+                    }
+                }
+                /* Check for "expr relop -1" */
+                else if (!tree->IsUnsigned() && cns2->IsIntegralConst(-1))
+                {
+                    /* Check for "expr <= -1" */
+                    if (oper == GT_LE)
+                    {
+                        /* Change to "expr < 0" */
+                        oper = GT_LT;
+                        goto SET_OPER;
+                    }
+                    /* Check for "expr > -1" */
+                    else if (oper == GT_GT)
+                    {
+                        /* Change to "expr >= 0" */
+                        oper = GT_GE;
 
-                            // Keep the old ValueNumber for 'tree' as the new expr
-                            // will still compute the same value as before
-                            tree->SetOper(oper, GenTree::PRESERVE_VN);
-                            cns2->gtIntCon.gtIconVal = 0;
+                    SET_OPER:
+                        // IF we get here we should be changing 'oper'
+                        assert(tree->OperGet() != oper);
 
-                            // vnStore is null before the ValueNumber phase has run
-                            if (vnStore != nullptr)
-                            {
-                                // Update the ValueNumber for 'cns2', as we just changed it to 0
-                                fgValueNumberTreeConst(cns2);
-                            }
+                        // Keep the old ValueNumber for 'tree' as the new expr
+                        // will still compute the same value as before
+                        tree->SetOper(oper, GenTree::PRESERVE_VN);
+                        cns2->gtIntCon.gtIconVal = 0;
 
-                            op2 = tree->AsOp()->gtOp2 = gtFoldExpr(op2);
+                        // vnStore is null before the ValueNumber phase has run
+                        if (vnStore != nullptr)
+                        {
+                            // Update the ValueNumber for 'cns2', as we just changed it to 0
+                            fgValueNumberTreeConst(cns2);
                         }
+                        op2 = tree->AsOp()->gtOp2 = gtFoldExpr(op2);
                     }
                 }
-            }
-            else // we have an unsigned comparison
-            {
-                if (op2->IsIntegralConst(0))
+                else if (tree->IsUnsigned() && op2->IsIntegralConst(0))
                 {
                     if ((oper == GT_GT) || (oper == GT_LE))
                     {