[LLVMdev] Instruction Selection sanity check

Tom Stellard tom at stellard.net
Tue Sep 2 09:10:54 PDT 2014


On Tue, Sep 02, 2014 at 04:09:09PM +0100, Johnny Val wrote:
> On Tue, Sep 2, 2014 at 3:38 PM, Tom Stellard <tom at stellard.net> wrote:
> >
> > On Tue, Sep 02, 2014 at 11:12:23AM +0100, Johnny Val wrote:
> > > Hi,
> > >
> > > I am working on a new back-end for LLVM. This architecture has two
> register
> > > types, data(A) and accumulator(B).
> > >
> > > A registers are i32 where as B registers are i64. This is causing me
> some
> > > headaches, as far as I can tell, it's not really possible to mix the two
> > > using tablegen?
> > >
> > > In the hardware, every instruction can either take an A register or a B
> > > register, in tablegen (as far as I can understand) this is not possible.
> > >
> > > I ended up creating instructions like
> > >
> > > MOV32ri (register immediate)
> > > MOV32rr (register register)
> > > MOV64rr, MOV64ri etc.
> > >
> > > I've done this for essentially every instruction. This kind of works,
> but
> > > there are issues.
> > >
> > > It results in unneeded copies between A registers and B registers. If a
> > > value is in an A register and the other is in a B, LLVM will do a copy
> > > between registers to make sure both registers are the same "type"(same
> > > bank) before doing the operation.
> > >
> >
> > Is it legal to have to mix register classes in an instruction?  For
> example,
> > ADD AReg, BReg?
> >
> > If so you will need add more instruction variants e.g.
> > ADD3264rr, ADD6432rr.
> 
> This is what I attempted to do. I get errors such as:
> 
> "Type inference contradiction found, merging 'i32' into 'i64' "
> 
> Which is where I got the idea that mixing types in the tablegen
> instructions was not allowed.
> 

This error comes from the instruction patterns.  You need to use types in
the patterns to match the register classes that are being used.

Since add requires inputs of the same type, your pattern would have to
be something like:


def : Pat <
  (add i32:$src0, i32:$src1)
  (ADD3264rr $src0, (i64 (MOV_B_A $src1))
>;


> > > Is there any way around this? Also is it really necessary to define a
> > > different instruction for each register type (even though it's the same
> > > instruction in hardware, with the same encoding etc).
> > >
> >
> > There is not really a good way around this, but it is not so bad if
> > you use multiclasses.
> >
> > > Another issue is that when multiplying, the result must always be
> stored in
> > > a B (accumulator register). So I did some custom lowering for the MUL
> node,
> > > and got the instruction to always write the result to a B register.
> > >
> >
> > How are you defining your MUL instruction?  If you define the MUL
> > instruction in tablegen with a B register as destination register,
> > then it should always output to a B register.
> >
> 
> I did do that, and that is indeed what happens. My C++ lowering code, quite
> literally, just replaces ISD::MUL nodes with my target specific MUL node. I
> leave the pattern empty in the tablegen description of the instruction to
> avoid the previously described error. Is this the correct way of solving
> this problem?

You can still use tablegen patterns to match target specific nodes.  You
just need to define them in your tablegen file.
See lib/Target/R600/AMDGPUInstrInfo.td for examples.

I'm still not sure why it would try using an A register when the MUL instruction
is defined with a B register.  Do your A and B register classes overlap?

-Tom


> 
> > -Tom
> >
> > > The problem is that later on LLVM will move it from a B register to an A
> > > register which means the result getting truncated (64 bit -> 32 bit). I
> am
> > > also unsure how to deal with this.
> > >
> > > I just want to confirm that I'm doing this somewhat correctly and there
> > > isn't a much more obvious and better way of doing this.
> > >
> > > Kind Regards,
> > >
> > > Jonathan
> >
> > > _______________________________________________
> > > LLVM Developers mailing list
> > > LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> 
> Thanks for the help!



More information about the llvm-dev mailing list