[llvm] [ISEL] Fix x86-64 instruction selection bug leaking upper 32 bits (PR #205600)

Ammar Askar via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 25 09:17:08 PDT 2026


================
@@ -1680,15 +1680,15 @@ def : Pat<(or (and GR64:$dst, -256),
               (i64 (zextloadi8 addr:$src))),
           (INSERT_SUBREG (i64 (COPY $dst)), (MOV8rm  i8mem:$src), sub_8bit)>;
 
-def : Pat<(or (and GR32:$dst, -256),
+def : Pat<(or (and def32:$dst, -256),
----------------
ammaraskar wrote:

Sorry, I'm not the best at understanding the ISEL phase yet, I tried adding the following to `def32` as a quick test (before even adding the filter for sub_8bit/sub_16bit):

```diff
@@ -850,6 +850,7 @@ def def32 : PatLeaf<(i32 GR32:$src), [{
          N->getOpcode() != ISD::AssertZext &&
          N->getOpcode() != ISD::AssertAlign &&
          N->getOpcode() != ISD::FREEZE &&
+         N->getOpcode() != TargetOpcode::INSERT_SUBREG &&
          !((N->getOpcode() == X86ISD::BSF || N->getOpcode() == X86ISD::BSR) &&
            (!N->getOperand(0).isUndef() && !isa<ConstantSDNode>(N->getOperand(0))));
 }]>;
```

but it seems to not work as I expect. Looking at the output of `-debug-only=isel` from my [minimal reproducer in the bug](https://github.com/llvm/llvm-project/issues/205291#issuecomment-4791736516), it seems like the `zext` gets selected before we select the `INSERT_SUBREG`. Is that the fix you were thinking of or did I just implement it incorrectly?

```
ISEL: Starting selection on root node: t14: i64 = zero_extend t13
ISEL: Starting pattern match
  Initial Opcode index to 46205
  Match failed at index 46209
  Continuing at 46475
  Morphed node: t14: i64 = SUBREG_TO_REG t13, TargetConstant:i32<6>
ISEL: Match complete!

ISEL: Starting selection on root node: t13: i32 = or t8, t18
ISEL: Starting pattern match
  Initial Opcode index to 32563
  TypeSwitch[i32] from 32595 to 32626
  Dropping mem operands
  Created node: t23: i32 = COPY t2
  Created node: t24: i8,ch = MOV8rm<Mem:(load (s8) from %ir.byte)> t4, TargetConstant:i8<1>, Register:i64 $noreg, TargetConstant:i32<0>, Register:i16 $noreg, t0
  Dropping mem operands
  Morphed node: t13: i32,ch = INSERT_SUBREG t23, t24, TargetConstant:i32<1>, t24:1
ISEL: Match complete!
```

https://github.com/llvm/llvm-project/pull/205600


More information about the llvm-commits mailing list