llvm-project
5301245b - [X86] Don't drop a redundant 32-bit `and` whose users were selected as def32 (#223750)

Commit
32 days ago
[X86] Don't drop a redundant 32-bit `and` whose users were selected as def32 (#223750) Fixes #222714 Nothing was wrong with the IR or the DAG combines here; the `and %idx, 1` survived all the way into instruction selection. Isel selects users before operands, so the `zext` of the (narrowed, i32) `and` had already been turned into a `SUBREG_TO_REG` through the `def32` pattern, which assumes the i32 producer zeroes the upper 32 bits. When isel then reached the `and`, `shrinkAndImmediate` noticed via known bits that the mask was redundant and replaced the `and` with its operand — a `truncate` of a 64-bit `cmov`. That truncate is just a subregister copy, so the already-emitted `SUBREG_TO_REG` ended up reading the whole 64-bit register, and the upper bits went straight into the scaled address. The `_BitInt(98)` is a red herring; the same thing happens with plain `i64`. The `def32` predicate now lives in `X86DAGToDAGISel::isDef32` (the PatLeaf calls it), and `shrinkAndImmediate` only drops a 32-bit `and` when its operand satisfies that predicate. Otherwise it returns false and the `and` is selected as a normal 32-bit instruction, which zeroes the upper half as the users expect.
Parents
Loading