[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