FX diff shows a 34 byte improvement without any regressions. In the original code this transform was unnecessarily blocked by an uncontainable GT_AND bit mask:
mov rax, 0x80000000
and rax, qword ptr [rsp+08H]
mov rdx, 0x80000000
cmp rax, rdx
sete al
now generates
mov rax, 0x8000000000000000
and rax, qword ptr [rsp+08H]
setne al
Commit migrated from https://github.com/dotnet/coreclr/commit/
e74c08ecdde10a84af4fa555efbd925f2cc08547
}
}
}
+ else if (op1->OperGet() == GT_AND && ((cmp->OperGet() == GT_EQ) || (cmp->OperGet() == GT_NE)))
+ {
+ GenTree* andOp1 = op1->gtGetOp1();
+ GenTree* andOp2 = op1->gtGetOp2();
+
+ if (op2Value != 0)
+ {
+ //
+ // If we don't have a 0 compare we can get one by transforming ((x AND mask) EQ|NE mask)
+ // into ((x AND mask) NE|EQ 0) when mask is a single bit.
+ //
+
+ if (isPow2(static_cast<size_t>(op2Value)) && andOp2->IsIntegralConst(op2Value))
+ {
+ op2Value = 0;
+ op2->SetIconValue(0);
+ cmp->SetOperRaw(GenTree::ReverseRelop(cmp->OperGet()));
+ }
+ }
+ }
}
#endif // _TARGET_XARCH_
ssize_t andOp2CnsVal = andOp2->AsIntConCommon()->IconValue();
ssize_t relOp2CnsVal = op2->AsIntConCommon()->IconValue();
- if ((relOp2CnsVal == andOp2CnsVal) && isPow2(andOp2CnsVal))
- {
- // We have a single bit test, so now we can change the
- // tree into the alternative form,
- // so that we can generate a test instruction.
-
- // Reverse the equality comparison
- tree->SetOperRaw((tree->gtOper == GT_EQ) ? GT_NE : GT_EQ);
-
- // Change the relOp2CnsVal to zero
- relOp2CnsVal = 0;
- op2->AsIntConCommon()->SetIconValue(0);
- }
-
// Now do we have a equality compare with zero?
//
if (relOp2CnsVal == 0)