How do I prevent DAGCombiner from combining ZExt/SExt(load) into LoadZExt?

In our toy ISA, we don’t have a dedicated ZExtLoad instruction. However DAGCombiner tends to combine ZERO_EXTEND(LOAD) into a LoadZExt node which can’t be trivially selected:

Combining: t5: i32 = zero_extend t4
Creating new node: t9: i32,ch = load<(dereferenceable load 1 from %ir.2), zext from i1> t0, FrameIndex:i64<0>, undef:i64

Reading through the implementation of tryToFoldExtOfLoad is still equally confusing

Hi Zhang,

Thanks. I’ve already called:

for (MVT VT : {MVT::i32, MVT::i64, MVT::i8}) {
setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote);
setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Expand);
setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Expand);
setTruncStoreAction(MVT::i1, VT, Promote);

Ah, I didn't notice it was i1, that's special because the smallest
load you have is probably actually an i8. I think most systems define
this problem away by saying that an i1 in memory occupies an entire
byte and must be either 0x00 or 0x01. Then a normal load from that
byte *is* a zext load.

For a sextload, I think LLVM converts that to an anyext load (also
implementable by your normal load instruction) followed by a separate
extension operation. At least that's what happens on AArch64.

If that doesn't work for you for some reason, you'll probably just
have to live with zextload from i1 being produced anyway and emit
multiple instructions to implement it.