[LLVMdev] Branch delay slots broken.

Richard Pennington rich at pennware.com
Tue Dec 14 13:46:21 PST 2010


The Sparc, Microblaze, and Mips code generators implement branch delay 
slots. They all seem to exhibit the same bug, which is not surprising 
since the code is very similar. If I compile code with this snippit:

   while (n--)
     *s++ = (char) c;

I get this (for the Microblaze):

         swi       r19, r1, 0
         add       r3, r0, r0
         cmp       r3, r3, r7
         beqid     r3, ($BB0_3)
         brid      ($BB0_1)
         add       r19, r1, r0
         add       r3, r5, r0
$BB0_2:
         addi      r4, r3, 1
         addi      r7, r7, -1
         add       r8, r0, r0
         sbi       r6, r3, 0
         cmp       r8, r8, r7
         bneid     r8, ($BB0_2)
         brid      ($BB0_3)
         add       r3, r4, r0
$BB0_3:

Notice that the label $BB0_1 is missing. If I disable filling in the 
branch delay slots, I get:

         swi       r19, r1, 0
         add       r19, r1, r0
         add       r3, r0, r0
         cmp       r3, r3, r7
         beqid     r3, ($BB0_3)
         brid      ($BB0_1)
$BB0_1:
         add       r3, r5, r0
$BB0_2:
         addi      r4, r3, 1
         addi      r7, r7, -1
         add       r8, r0, r0
         sbi       r6, r3, 0
         cmp       r8, r8, r7
         add       r3, r4, r0
         bneid     r8, ($BB0_2)
         brid      ($BB0_3)
$BB0_3:

A similar thing happens with the Mips and Sparc, although they just fill 
in the delay slots with NOPs.

My question is, why would inserting a NOP or splicing an instruction in 
a MachineBasicBlock cause a label to go missing? Could someone point me 
to appropriate places to look?

FYI, clang is the front end.

-Rich



More information about the llvm-dev mailing list