[LLVMdev] Types inference in tblgen: Multiple exceptions

Llopard Ivan ivanllopard at gmail.com
Fri Dec 9 04:46:29 PST 2011


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







More information about the llvm-dev mailing list