Error when splitting v4i16 data into four i16 using DAG.ExtractVectorElements()

Hello, I’m trying to implement my original backend in LLVM. I have some errors and I would like you to help me.

I want to split v4i16 type data into four i16 data when storing v4i16 data, and want to execute some process using them. So I wrote the code like setOperationAction(ISD::STORE, MVT::v4i16, Custom); and defined the function like following in MyArcISelLowering.cpp.

SDValue MyArcTaLowering::LowerSTORE(SDValue Op,
                                          SelectionDAG &DAG) const {
  StoreSDNode *StoreNode = cast<StoreSDNode>(Op);
  SDValue StoreVal = StoreNode->getValue();
  SmallVector<SDValue, 4> Opr, StoreOpr;
  DAG.ExtractVectorElements(StoreVal, Opr, 0, 0, MVT::i16); // v4i16 -> i16, i16, i16, i16
  ... // going to write some processes using those data

But I have an error like followering and it seems that I have to guarantee the type of data at an earlier stage. MyArc has only 64 bit register.

Legalizing: t44: i16 = extract_vector_elt t7, Constant:i64<0>
void {anonymous}::SelectionDAGLegalize::LegalizeOp(llvm::SDNode*): Assertion `TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) == TargetLowering::TypeLegal && "Unexpected illegal type!"' failed.

What I should I do to avoid the error? Instead of DAG.ExtractVectorElements() function do I have to other functions?


My understanding of instruction selection is still rather new, apologies if I am saying wrong things.

Each backend defines the notion of “legal” types. Legal types are those who may be mapped on a register. and it is better if most operations are supported on them. i32 is usually legal on most backends because you can store the value in a register, and all i32 operations are usually covered.

When a type is illegal, it may try to modify the value into a legal type. For example, for legalizing an add between two i16 values, each of the values would be extended to i32.

However, I guess custom lowering bypasses this mechanism somehow (I am not sure about that part: the debug output should be reviewed) - so here it is up to you to insert those extensions (ZEXT or SEXT) so that you end up with legal types (for example i32 if i32 is legal in your backend). Perhaps you can try doing that.

1 Like

Thank you for your reply!
As you said, using node which have an opcode named ZEXT or SEXTT is a good idea to solve my idea.

But in the first place, I found it difficult to realize what I want to do by adopting that method. I can’t go into the deeper details of my research, but I found it almost impossible when I needed to access the v4i16 type values in other basic blocks. So I’ll be dropping my original policy and proceeding with implementation in a completely new way.