[TI C6x] BUG: Incorrect assembly generated

Timon ter Braak timon@terbraak.org
Tue Mar 12 10:59:00 GMT 2013


Hi,

I have a piece of code that results in invalid assembly. This is just an 
example, as I suspect a general issue with the assembler, due to the 
SIGBUS and SIGILL signals I receive in a larger codebase.

I use binutils 2.23.1 and gcc 4.7.2. The function that serves as an 
example is the gcc-builtin __sync_bool_compare_and_swap. When I put a 
printf statement in front of it, different assembly is generated which 
works correctly. The second (normal) part of the code results in 
assembly where a specific register (b2) is being reused, although it is 
already overwritten by the result of a comparison. This results in an 
infinite loop, as __sync_bool_compare_and_swap always returns a value 
indicating that the swap failed.

In the incorrect assembly, at address 0xed0, register b2 is reused, 
showing a behavior like 'return (*val == (*val == current));'.

I am not sure whether this issue should be directed to binutils or gcc; 
please advice.
Hopefully this can be fixed.

Timon

===== C-code ===== Compiled with '-O2 -g'

#include <stdio.h>
#include <stdlib.h>

#define NITER 500

int main (){
          long val = 0;
          while (val < NITER){
                  while (1) {
                          long current = val;
                          long next = current+1; 
printf("__sync_bool_compare_and_swap(%p,%d,%d)\n", &val, current, next);
                          if ( __sync_bool_compare_and_swap (&val, 
current, next)) {
                                  break;
                          }
                  }
          }

          val = 0;
          while (val < NITER){
                  while (1) {
                          long current = val;
                          long next = current+1;
                          if ( __sync_bool_compare_and_swap (&val, 
current, next)) {
                                  break;
                          }
                  }
                  printf(".");
          }
          printf("\n");
}

===== Correct Assembly =====

b4 = val, b10 = current, b11 = next, *+b15(28) = *val

      e5c:       002808f2        or .D2 0,b10,b0
      e60:       00000293        b .S2 e74 <main+0x74>
      e64:       023ce2e6        || ldw .D2T2 *+b15(28),b4
      e68:       00006001        nop 4
      e6c:       00000312        || b .S2 e78 <main+0x78>
      e70:       00008a7a        cmpeq .L2 b4,b0,b0
      e74:       25bce2f6        [b0] stw .D2T2 b11,*+b15(28)
      e78:       05114a7a        cmpeq .L2 b10,b4,b10
      e7c:       00000000        nop 1
      e80:       00281fd9        or .L1X 0,b10,a0
      e84:       053ce2e6        || ldw .D2T2 *+b15(28),b10
      e88:       dffff790        [!a0] b .S1 e3c <main+0x3c>
      e8c:       00004000        nop 3

===== Incorrect Assembly =====

b6 = val, b2 = current, b5 = next, *+b15(28) = *val

      eb8:       00000593        b .S2 ecc <main+0xcc>
      ebc:       033ce2e6        || ldw .D2T2 *+b15(28),b6
      ec0:       00006001        nop 4
      ec4:       00000212        || b .S2 ed0 <main+0xd0>
      ec8:       0108ca7a        cmpeq .L2 b6,b2,b2
      ecc:       62bce2f6        [b2] stw .D2T2 b5,*+b15(28)
      ed0:       00984a7b        cmpeq .L2 b2,b6,b1
      ed4:       02001728        || mvk .S1 46,a4
      ed8:       50000e10        [!b1] b .S1 f30 <main+0x130>
      edc:       00008000        nop 5



More information about the Binutils mailing list