[LLVMdev] Sub-Register Allocation

Kenneth Waters kwwaters at gmail.com
Thu Jan 10 21:54:14 PST 2013


llvm-dev,

I'm trying to get a better understanding of sub-registers.  I'm seeing the
code generator make an odd decision that I was hoping someone could point
me in the right direction of explaining.

The architecture is 68000, which has 8, 16, and 32 bit views of all of it's
data registers.  In order to zero extend you can load a big view with zero,
and then copy into the small view.

I'm working on this llvm function,

define i16 @zext_i8_to_i16_simple(i8 %x) {
  %1 = zext i8 %x to i16
  ret i16 %1
}

I have a pattern where I load the 16 bit portion of the register with 0,
and then copy in the 8 bit portion.

def : Pat<(i16 (zextloadi8 addr:$src)),
          (INSERT_SUBREG (MOV16id 0), (MOV8md addr:$src), sub_byte)>;

which produces working but odd assembly,

zext_i8_to_i16_simple   PROC            ; @zext_i8_to_i16_simple
; BB#0:
        move.b  4(a7), d1
        move.w  #0, d0
        move.b  d1, d0
        rts

Notice the extraneous use of d1, as

move.w #0, d0
move.b 4(a7), d0

would work just as well.

If however, I load the 32 bit portion of the register with 0, truncate it
to 16bits, and then copy in the 8 bit portion, I get what I expect.

def : Pat<(i16 (zextloadi8 addr:$src)),
          (INSERT_SUBREG (EXTRACT_SUBREG (MOVQ32 0), sub_word),
                         (MOV8md addr:$src),
                         sub_byte)>;

zext_i8_to_i16_simple   PROC            ; @zext_i8_to_i16_simple
; BB#0:
        moveq   #0, d0
        move.b  4(a7), d0
        rts

I'm building off of the llvm 3.2 release, if it matters.  I'm mostly
looking for where to look to understand what's going on and/or extra
documentation on how subregisters work inside the instruction and registers
selectors.

Thank you,
-- Kenneth Waters

P.S. If it helps, my register definitions look like,

multiclass M68kDataReg<bits<3> num, string defn, string n> {
  def B : M68kReg<num, n>;
  def W : M68kRegWithSubregs<num, n, [!cast<Register>(defn # "B")]> {
    let SubRegIndices = [sub_byte];
  }
  def L : M68kRegWithSubregs<num, n, [!cast<Register>(defn # "W")]> {
    let SubRegIndices = [sub_word];
  }
}
defm D0 : M68kDataReg<0, "D0", "d0">;
defm D1 : M68kDataReg<1, "D1", "d1">;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130110/a5b63424/attachment.html>


More information about the llvm-dev mailing list