[LLVMdev] illegal code generated for special architecture

Boris Boesler baembel at gmx.de
Fri Dec 5 07:13:13 PST 2014


Hi!

 I'm making a strange observation in my backend, that ends in illegal code:

Version 1:
- I lower FrameIndex to TargetFrameIndex (nothing special)
- I generate a special address-register ADD instruction in eliminateFrameIndex() to write FramePointer + offset into a new address-register
- I use explicit load and store and address-registers in my target instruction patterns:
  eg (store (add (load AddressRegs:$a), DataRegs:$b), AddressRegs:$dst)

 This works quite well, but if I access an array on the stack (LLVM generates FrameIndex to access it):

  int buffer[BUFFER_SIZE];
  for(int i = 0; i < end_loop_index; i++) {
    buffer[i] = i;
  }

 then LLVM generates the target instruction "ADD D1, A1, D0" which is an illegal instruction - all operands have to be data-registers Dx. I've checked more than once, that address-registers are not in the set of data-registers. The generated instruction is not part of my spec.

 I guess this happens, because I replace the TargetFrameIndex by the address-register in eliminateFrameIndex without checking the parent operation (ADD in this case); it would be valid for some load/store instructions, but not for ADD. Can I run some legalization function for the illegal instruction?


Version 2:
 The situation worsens (or improves, depending on the point of view) when I replace explicit address-register usage by common complex patterns, like ADDRx and MEMx: for the instruction where the first version generates illegal code, LLVM gives the error message:

LLVM ERROR: Cannot select: 0x7fc7a9034f10: ch = store 0x7fc7a9034d10:1, 0x7fc7a9034d10, 0x7fc7a9034b10, 0x7fc7a9034810<ST1[%arrayidx](align=4)> [ORD=18] [ID=7]
  0x7fc7a9034d10: i32,ch = load 0x7fc7a8c12c08, 0x7fc7a9034410, 0x7fc7a9034810<LD1[%i](align=4)> [ORD=15] [ID=5]
    0x7fc7a9034410: i32 = TargetFrameIndex<3> [ID=4]
    0x7fc7a9034810: i32 = undef [ID=1]
  0x7fc7a9034b10: i32 = add 0x7fc7a9034e10, 0x7fc7a9034d10 [ORD=17] [ID=6]
    0x7fc7a9034e10: i32 = TargetFrameIndex<2> [ID=3]
    0x7fc7a9034d10: i32,ch = load 0x7fc7a8c12c08, 0x7fc7a9034410, 0x7fc7a9034810<LD1[%i](align=4)> [ORD=15] [ID=5]
      0x7fc7a9034410: i32 = TargetFrameIndex<3> [ID=4]
      0x7fc7a9034810: i32 = undef [ID=1]
  0x7fc7a9034810: i32 = undef [ID=1]

 This is the instruction where the array's base address and some offset are added to get the i-th's element address (buffer[i] from the C code above). Basically, I understand the error message, because such an instruction does not exist. But I do not understand why the big expression is not splitted into smaller parts.

 I have absolutely no idea why this fails! Why cant LLVM write the operand 0x7fc7a9034e10: i32 = TargetFrameIndex<2> [ID=3] into an address-register (via my eliminateFrameIndex) and then copy it to a data-register, perform the add and copy the result back into an address-register?

Thanks in advance,
Boris





More information about the llvm-dev mailing list