[LLVMdev] Types inference in tblgen: Multiple exceptions
Ivan Llopard
ivanllopard at gmail.com
Fri Dec 9 17:11:45 PST 2011
On 10/12/2011 01:32, Eli Friedman wrote:
> 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.
The fact is that those i16 nodes are intermediate results that I wanted
to mask into one machine instruction. No operand is needed for them.
>
> 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.
It is exactly what I did for i16 results. But it seems that, in order to
generate the ISel, tblgen removes all types in patterns (even those that
I explicitly enforced by casting) and then tries to re-infer them. This
does not happen in the process of instr-info generation.
I think I am missing something regarding the general idea of tblgen
pattern matching but if I am not wrong, all patterns with intermediate
type results that are not supported by the architecture are forbidden.
Is it correct?
>
> -Eli
More information about the llvm-dev
mailing list