@@ -1641,11 +1641,20 @@ Reduction MachineOperatorReducer::ReduceWordNAnd(Node* node) {
1641
1641
namespace {
1642
1642
1643
1643
// Represents an operation of the form `(source & mask) == masked_value`.
1644
+ // where each bit set in masked_value also has to be set in mask.
1644
1645
struct BitfieldCheck {
1645
- Node* source;
1646
- uint32_t mask;
1647
- uint32_t masked_value;
1648
- bool truncate_from_64_bit;
1646
+ Node* const source;
1647
+ uint32_t const mask;
1648
+ uint32_t const masked_value;
1649
+ bool const truncate_from_64_bit;
1650
+ BitfieldCheck (Node* source, uint32_t mask, uint32_t masked_value,
1651
+ bool truncate_from_64_bit)
1652
+ : source(source),
1653
+ mask (mask),
1654
+ masked_value(masked_value),
1655
+ truncate_from_64_bit(truncate_from_64_bit) {
1656
+ CHECK_EQ (masked_value & ~mask, 0 );
1657
+ }
1649
1658
1650
1659
static base::Optional<BitfieldCheck> Detect (Node* node) {
1651
1660
// There are two patterns to check for here:
@@ -1660,14 +1669,16 @@ struct BitfieldCheck {
1660
1669
if (eq.left ().IsWord32And ()) {
1661
1670
Uint32BinopMatcher mand (eq.left ().node ());
1662
1671
if (mand.right ().HasValue () && eq.right ().HasValue ()) {
1663
- BitfieldCheck result{mand.left ().node (), mand.right ().Value (),
1664
- eq.right ().Value (), false };
1672
+ uint32_t mask = mand.right ().Value ();
1673
+ uint32_t masked_value = eq.right ().Value ();
1674
+ if ((masked_value & ~mask) != 0 ) return {};
1665
1675
if (mand.left ().IsTruncateInt64ToInt32 ()) {
1666
- result.truncate_from_64_bit = true ;
1667
- result.source =
1668
- NodeProperties::GetValueInput (mand.left ().node (), 0 );
1676
+ return BitfieldCheck (
1677
+ NodeProperties::GetValueInput (mand.left ().node (), 0 ), mask,
1678
+ masked_value, true );
1679
+ } else {
1680
+ return BitfieldCheck (mand.left ().node (), mask, masked_value, false );
1669
1681
}
1670
- return result;
1671
1682
}
1672
1683
}
1673
1684
} else {
0 commit comments