Skip to content

Commit

Permalink
Do not remove certain casts with contained operands (#74602)
Browse files Browse the repository at this point in the history
On ARM64, we turn the "EQ(CAST<byte>(x), 0)" into "TEST_EQ(x, 0xFF)",
to avoid materializing the cast.

However, this breaks recognition of the "cb[n]z" idiom. If "x" ends
up in a register, that's ok - we're essentially exchanging relop for a
cast. If, however, it was contained, it is better to leave it alone:

```
-            ldr     w0, [fp,#0x18]
-            tst     w0, #255
-            bne     G_M25131_IG10
-                                               ;; size=12 bbWeight=1    PerfScore 3.50
+            ldrb    w0, [fp,#0x18]
+            cbnz    w0, G_M25131_IG10
+                                               ;; size=8 bbWeight=1    PerfScore 3.00
```
  • Loading branch information
SingleAccretion committed Sep 23, 2022
1 parent 1a9f573 commit 66295dd
Showing 1 changed file with 3 additions and 4 deletions.
7 changes: 3 additions & 4 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2789,14 +2789,13 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp)
// doing so would produce incorrect results (e.g. RSZ, RSH).
//
// The below list of handled opers is conservative but enough to handle the most common
// situations. In particular this include CALL, sometimes the JIT unnecessarily widens
// the result of bool returning calls.
// situations.
//
bool removeCast =
#ifdef TARGET_ARM64
(op2Value == 0) && cmp->OperIs(GT_EQ, GT_NE, GT_GT) &&
(op2Value == 0) && cmp->OperIs(GT_EQ, GT_NE, GT_GT) && !castOp->isContained() &&
#endif
(castOp->OperIs(GT_CALL, GT_LCL_VAR) || castOp->OperIs(GT_OR, GT_XOR, GT_AND)
(castOp->OperIs(GT_LCL_VAR, GT_CALL, GT_OR, GT_XOR, GT_AND)
#ifdef TARGET_XARCH
|| IsContainableMemoryOp(castOp)
#endif
Expand Down

0 comments on commit 66295dd

Please sign in to comment.