Menu

#2501 [z80] union and 64-bit type fatal internal compiler error

closed-fixed
None
other
5
2018-12-12
2016-05-06
alvin
No

sdcc -v
3.5.6 #3584 (MINGW64)

extern long long llabs(long long i);
extern char *lltoa(long long i, char *buf, int radix);

struct long_s
{
   unsigned long ls32;
   unsigned long ms32;
};

union u64_s
{
   long long a;
   struct long_s b;
};

char buff[100];

union u64_s z;

void main(void)
{
   z.a = llabs(z.a);
   lltoa(z.a, buff, 10);
}

sdcc -mz80 -S error.c

Results in this error repeated about 10 times:

error.c:24: error 9: FATAL Compiler Internal Error in file '/home/sdcc-builder/build/sdcc-build/orig/sdcc/src/z80/gen.c' line number '1579' : Symbol in register, but no register assigned.
Contact Author with source code
Symbol iTemp10 at ic 14.

Related

Wiki: z80

Discussion

  • alvin

    alvin - 2016-05-08

    This bug occurs in nearly all 64-bit programs I have been test compiling. The compiler is attempting to keep a 64-bit value in registers for reuse in a following statement but can't do that.

    Some more examples where this occurs:

    printf("[#2] ");
    scanf("%s", buffer_1);
    y.a = strtoll(buffer_1, NULL, 0);
    /// bug occurs here for y.a
    lltoa(y.a, buffer_1, 10);
    /// bug occurs here for y.a
    z.a = x.a + y.a;
    
    z.a = llabs(x.a);
    /// bug occurs here for z.a
    lltoa(z.a, buffer_2, 10);
    

    In all cases inserting a do-nothing function call at the point where the bug occurs ensures the compiler cannot keep values in registers so that's not attempted and the bug does not occur.

     

    Related

    Bugs: #2

  • Philipp Klaus Krause

    iTemp10 has an empty live-range, its only use is as the result of a dead iCode. Dead code elimination should have killed that, but didn't.
    As a workaround, the z80 backend could assume such variables to live on the stack for evaluation of the cost function (since that is where they will end up after RegFix() anyway. But there is still a bug in dead code elimination here (and it affects all backends; but only for z80 do we get an error as opposed to inefficient code).

    Philipp

     
  • Philipp Klaus Krause

    Dead code elimination leaves ic 14, since it is a read from a union member, which currently are all considered volatile by SDCC.

    Philipp

     
  • Maarten Brock

    Maarten Brock - 2016-05-14

    IMO then the primary fix should be to perform the (volatile) read and drop the result. Reading a volatile when instructed to is an important concept in embedded C software.

     
    • Philipp Klaus Krause

      Sicne we are reading through a pointer, we use GET_POINTER, not DUMMY_READ_VOLATILE. GET_POINTER has a result operand. But that result has an empty live range, so it is not considered in register allocation.

      However, for the following code

      volatile int *i;
      
      void f(void)
      {
          int j = *i;
      }
      

      for both z80 and stm8, all result bytes are written to register a.

      Philipp

       

      Last edit: Maarten Brock 2018-12-15
    • Philipp Klaus Krause

      Also, I wonder if making union members volatile really makes sense. Probably not. After all, one could create pointers to the union members, pass them to somewhere else, and the volatile would be lost.
      Pointer analysis should take care of stuff. On the other hand, we have some issues in our pointer analysis, and developer expectations may not match the standard on union behaviour.

      Philipp

       
  • Maarten Brock

    Maarten Brock - 2016-05-15

    Making union members volatile is a hack to make sure modifying one member will result in all members being modified. I guess union analysis is as difficult as pointer analysis. SDCC could certainly benefit from replacing this hack with a proper solution.

     
  • Philipp Klaus Krause

    For now, IMO, the right thing at register allocation is to just allocate the temporary to somewhere. Just like SDCC does with long, etc. The bug is that long long is treated differently somehow.

    Philipp

    P.S.: I can reproduce the issue in current SDCC [r10755] for both stm8 and z80.

     

    Last edit: Philipp Klaus Krause 2018-12-12
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
     
  • Philipp Klaus Krause

    Fixed in [r10756].

    Philipp

     

Log in to post a comment.