Question on pattern matching extractelt

Hi,
I have an issue with pattern matching.
I have the following SelectionDAG:
t13: i32 = extract_vector_elt t2, Constant:i64<1>

That I am trying to match with the following pattern:

def : Pat<(extractelt (v4i16 SingleReg:$v), 1), (SRADd1 SingleReg :$v, (i64 16))>;

But for some reason the pattern does not match.
It seems to be due to the fact extract_vector_elt's result type is i32 (because i16 is not a legal type on our processor), but according to the comment in ISDOpcodes.h, it is allowed for EXTRACT_VECTOR_ELT to have a result type larger than the element type of the vector, so I would expect to be able to match such pattern.

I tried specifying the result type in the pattern:
def : Pat<(i32 (extractelt (v4i16 SingleReg:$v), 1)), (SRADd1 SingleReg :$v, (i64 16))>;

But in that case I get a tblgen error:

possible type contradiction in the pattern below (use -print-records with llvm-tblgen to see all expanded records).
anonymous_1188: (extractelt:{ *: } SingleReg:{ *: }:$v, 0:{ *:[i64] })

Is there anyway to match such pattern?

Thanks in advacne!
regards,
Sebastien

I think it’s disallowed by the SDTypeProfile in TargetSelectionDAG.td. You can use vector_extract instead of extractelt which is what some other targets like WebAssembly are doing for this issue. It’s type profile is more relaxed on this.

It works, thanks a lot!

Vector_extract / vector_insert have a comment that says they are deprecated.

I think this should be updated to say that they can be used when the result’s type is larger than the element type.

The (i32 extract_vector_elt (v4i16)) doesn’t guarantee any particular value in the extra bits of the result. So type legalization may have inserted an AND or SIGN_EXTEND_INREG after the extra node if the original code had zero extended or sign extended the original i16 result. If you target has a well defined behavior for the extra bits that would make an AND or SIGN_EXTEND_INREG reduncant, it might be better to lower this to a target specific opcode and then teach computeKnownBitsForTargetNode or computeNumSignBitsForTarget node the property that your hardware guarantees. This will allow DAG combine to remove extra nodes based on this information.

WebAssembly has explicit patterns for and+vector_extract and sign_extend_inreg+vector_extract to pick specific instructions that have guarantees for the upper bits. But that might not cover all possible cases that a DAG combine with known bits or sign bits information would have been able to do.