Hi all,
I am writing a back-end for a processor that has complex type registers. It has two functional units to perform complex multiplications.
From clang, I emulate a complex multiplication using vectors and, at the IR, I got this tblgen-friendly pattern (real component) :
(set RARegs:$dst, (insertelt RARegs:$src,
(i16 (trunc (add
(ncmul
(sext (i16 (extractelt RARegs:$a, imm))),
(sext (i16 (extractelt RARegs:$b, imm)))
),
(ncmul
(sext (i16 (extractelt RARegs:$a, imm))),
(sext (i16 (extractelt RARegs:$b, imm)))
)
))),
imm) )
where RARegs is a register class of type [i32, v2i16]. I want to match that pattern in order to have one instruction which takes 2 vectors (complex numbers) and gives me another vector. Unfortunately, I am running into multiple tblgen type inference exceptions. I am new to llvm codegen.
First of all, I realized that I need to explicitly cast intermediate i16 type results because they are not supported by the architecture, is it right?
For example, if I do not cast extractelt's node type I get the following error when I run tblgen with -gen-instr-info:
llvm[3]: Building Meph.td instruction information with tblgen
llvm-tblgen: llvm/include/llvm/ADT/SmallVector.h:150: T& llvm::SmallVectorTemplateCommon<T>::operator[](unsigned int) [with T = llvm::MVT::SimpleValueType]: Assertion `begin() + idx < end()' failed.
which comes from utils/TableGen/CodeGenDAGPatterns.cpp:450:
for (unsigned i = 1, e = Other.TypeVec.size(); i != e; ++i)
if (isInteger(Other.TypeVec[i]) && Other.TypeVec[i] > LargestInt)
LargestInt = Other.TypeVec[i];
but Other.TypeVec is empty throwing an exception when accessing Other.TypeVec[1].
As far as I know, tblgen analyzes sext node and tries to infer operand types by applying the specified type constraints of the node. The 2nd type constraint of sext enforces extractelt to be scalar and extractelt gets i32:v2i16 types (legal types or RARegs types). After that, it tries to apply the 3rd type constraint (SDTCisOpSmallerThanOp) and it reaches the abnormal condition I shown.
I presume this is a bug in tblgen, should not it verify that TypeVec is empty before entering the loop ?
Casting intermediate i16 type results, I manage to generate instruction information but it throws another exception when generating the instruction selector :-(.
vtInt: (vt:Other)<<P:Predicate_vtInt>>
Type constraint application shouldn't fail!
Looking again into the code, tblgen does not take into account the explicit casts when generating the instruction selector (RemoveAllTypes -> InferPossibleTypes) so it gets stuck earlier into the pattern (insertelt-trunc). insertelt enforces trunc to be scalar and I have the same situation as before. Do you know how can I solve this problem ?
If it is either not possible or too hard, how should I proceed to detect the pattern ?
Ivan