ToT ARM Code generator causing - Error: invalid constant (xxx) after fixup in assembly output

Hello,

This problem happens in ToT under specific conditions - namely there is a big BB#671 basic block of code
the just copies data from memory location to another. At the beginning of BBB#671 r0 is loaded
from the jumptable in the constant pool immediately after it. Displacement from the pc
in this case is #1476 which is way above magic #1020 hence the error after fixup.
Both ARMCodeEmitter::emitLEApcrelJTInstruction() and emitJumpTableAddress()
are responsible for the offending instruction adr r0, #.LJTI8485_1_1
But besides the fact that they do not complain about the invalid offset from the pc I do not see
anything wrong here.

The problem seems to be in the ARMConstantIslands which is not splitting BB#671 into
smaller pieces and thus producing over the limit 'add' opcode.

This code fragment below is produced from a rather large bitcode file that resists being reduced to something
more manageable. As a result keystrokes in gdb are very "expensive " and taxing my machine rather heavily.

Any thoughts and hints on debugging this issue would be much appreciated!

I have used llc with these options to produce the output:

llc -O0 -regalloc=fast -relocation-model=pic l.bc -o ll-2.8.s

     bhi .LBB8485_455
@ BB#671: @ %bb154
                                         @ in Loop: Header=BB8485_1112 Depth=5
     adr r0, #.LJTI8485_1_1
     ldr r1, [sp, #3300]
     ldr r2, [r0, r1, lsl #2]
     ...
     lots of boring code omitted
     ...
     add pc, r2, r0
.LJTI8485_1_1:
     .set .L8485_1_1_set_70,.LBB8485_70-.LJTI8485_1_1
     .long .L8485_1_1_set_70
     .set .L8485_1_1_set_49,.LBB8485_49-.LJTI8485_1_1
     .long .L8485_1_1_set_49
     .set .L8485_1_1_set_419,.LBB8485_419-.LJTI8485_1_1
     .long .L8485_1_1_set_419
     .set .L8485_1_1_set_1085,.LBB8485_1085-.LJTI8485_1_1
     .long .L8485_1_1_set_1085
     .set .L8485_1_1_set_439,.LBB8485_439-.LJTI8485_1_1

When assembler runs on the output we get:

ll-2.8.s:1916640: Error: invalid constant (5c4) after fixup

Standard disclaimer:
All of the tools used were proper ARM cross compiler,assembler, etc running on x86_64
and no bitcode was ever harmed during debugging.

Cheers,
Pawel

I can look at this, but you'll need to send the .bc file. Please open a PR?

There have been lots of bugs in ARMConstantIslands where it's off by 1, but I haven't seen one where it's off by a lot like this.

I can look at this, but you'll need to send the .bc file. Please open a PR?

I would do it but I am in a bit of a pickle as the .bc is from propriety code and
I can not post it.
Anyway, I have been trying to re-create the problem in a simpler test case.
Since, I do not have access to the source for the .bc I am trying to guess
the kind of code that created the problem. So far I was able to replicate
the one large basic block but I not sure how to produce the constant pool
with the jumptable like in the description below.

There have been lots of bugs in ARMConstantIslands where it's off by 1, but I haven't seen one where it's off by a lot like this.

The big offset is due to this one large basic block and is not a problem with alignment or any off by 1 issue.

I can look at this, but you'll need to send the .bc file. Please open a PR?

I would do it but I am in a bit of a pickle as the .bc is from propriety code and
I can not post it.

Can't help much then. You might look into obfuscating the code, some companies are OK with distributing obfuscated IR.
-debug-only=arm-cp-islands will show you what ARMConstantIslands is thinking pretty well.

I can look at this, but you'll need to send the .bc file. Please open a PR?

I would do it but I am in a bit of a pickle as the .bc is from propriety code and
I can not post it.

Can't help much then. You might look into obfuscating the code, some companies are OK with distributing obfuscated IR.
-debug-only=arm-cp-islands will show you what ARMConstantIslands is thinking pretty well.

Oh -debug-only=arm-cp-islands works very very well! It just that now after running it I have
a 1.5GB log file problem in addition to the original issue.