[LLVMdev] Types inference in tblgen: Multiple exceptions

Eli Friedman eli.friedman at gmail.com
Fri Dec 9 16:32:24 PST 2011

On Fri, Dec 9, 2011 at 4:12 PM, Ivan Llopard <ivanllopard at gmail.com> wrote:
> Hi Eli,
> Thanks for your response. Please see my responses below.
> On 10/12/2011 00:28, Eli Friedman wrote:
>> On Fri, Dec 9, 2011 at 4:46 AM, Llopard Ivan<ivanllopard at gmail.com>
>>  wrote:
>>> 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 ?
>> If TableGen crashes, it's a bug.
> Yes, it crashes.
>>> 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 ?
>> Your email doesn't really make one thing clear: does your architecture
>> have i16 registers?
> No, my architecture does not support i16 type.

Then I don't think this pattern will ever match anyway; there won't be
any nodes of i16 type to match.

You might be able to fix the error by writing "(set RARegs:$dst,
(v2i16 (insertelt RARegs:$src," to explicitly note the result type of
the insertelt.  TableGen generally isn't very smart about figuring out
types, so explicitly writing out the types of every node can help.


More information about the llvm-dev mailing list