Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#1364 Constants fold incorrectly under Mac OS X Intel gcc

closed-fixed
Borut Ražem
5
2013-05-25
2007-08-20
Jeremy Cooper
No

SUMMARY

SDCC 2.7.0 does not run correctly under Mac OS X Intel using gcc 4.0.1, in some cases it produces incorrect code, and in other cases it crashes. I have isolated one specific (non-crash) behavior to the following minimal test case.

The following test code compiles correctly under gcc version 3.4.2 [FreeBSD] 20040728 and incorrectly under gcc version 4.0.1 (Apple Computer, Inc. build 5367). To isolate the problem, I ran SDCC in '--dumptree' mode and found that the bug occurs at the intermediate code level.

To reproduce:

sdcc --dumptree -mmcs51 -c test.c -o test.rel

EXAMPLE PROGRAM

char
epcs (char ep)
{
ep &= ~0x80;

return ep;
}

EXPECTED BEHAVIOR: (obtained from SDCC 2.7.0 under FreeBSD gcc 3.4.2)
...
sdcc-test.c:4: CONSTANT (0x82db180) value = 127, 0x7f 127.000000 type (literal-char)
...

ACTUAL BEHAVIOR: (obtained from SDCC 2.7.0 under Mac OS X gcc 4.0.1)
...
sdcc-test.c:4: CONSTANT (0x5399e0) value = 0, 0x0, 0.000000 type(literal-char)
...

SDCC Version:
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.0 #4818 (Aug 17 2007) (UNIX)

Discussion

  • Logged In: NO

    I have tracked down the source of this bug to the assignment of 'l' in the function valCastLiteral(), in SDCCval.c.

    value *
    valCastLiteral (sym_link * dtype, double fval)
    {
    value *val;
    TYPE_TARGET_ULONG l = (TYPE_TARGET_ULONG)fval;

    In this particular case, 'fval' has the value -129. As such, the result of this assignment operation is undefined; an unsigned long cannot hold the value -129. According to the C99 specification:

    6.3.1.4 Real floating and integer

    ... If the value of the integral part cannot be represented by the integer type, the behavior is undefined.

    I believe this was also pointed out in track item #1739860.

     
  • Jeremy Cooper
    Jeremy Cooper
    2007-08-21

    Patch to src/SDCCval.c

     
    Attachments
  • Jeremy Cooper
    Jeremy Cooper
    2007-08-21

    Logged In: YES
    user_id=531281
    Originator: YES

    I have tested and suggest the following (attached) patch to SDCCval.c (2.7.0). It removes the offending upfront cast and uses 'fval' directly where needed.
    File Added: sdcc.1777758.patch

     
  • Borut Ražem
    Borut Ražem
    2007-08-21

    Logged In: YES
    user_id=568035
    Originator: NO

    Just FYI: the problem is not reproducible on ppc Mac OS X. It seems that only x86 Mac OS X is affected :-(

    Borut

     
  • Maarten Brock
    Maarten Brock
    2007-08-22

    Logged In: YES
    user_id=888171
    Originator: NO

    It seems the intermediate 'l' was introduced by Sandeep in revision 1551 to overcome a bug in gcc when converting float to short. Maybe it's better to use an intermediate 'signed long l' and 'unsigned long ul'.

     
  • Borut Ražem
    Borut Ražem
    2007-08-22

    Logged In: YES
    user_id=568035
    Originator: NO

    An other curiosity: I tried it on x86 Mac OS X with Darwin Kernel Version 8.1.0 and gcc --version:
    i686-apple-darwin8-gcc-4.0.0 (GCC) 4.0.0 (Apple Computer, Inc. build 5026)
    and the problem is not reproducible!

    Jeremy (or somebody else), can you please run the regression test with the patched version, since I'm not convinced that the patch fixes all problems: I found other cases where double is converted to unsigned?

    BTW: how can I find out the Mac OS X version I'm using? uname -a returns only the Darwin kernel version (excuse my ignorance, but OS X is not my "native" OS ;-)...

    And an other BTW:
    I tried to execute sdcc unified binary generated by snapshot build, but I've got the following error:
    $./sdcc
    -bash: ./sdcc: Bad executable (or shared library)

    File type seems to be correct:
    $ file ./sdcc
    ./sdcc: Mach-O fat file with 2 architectures
    ./sdcc (for architecture i386): Mach-O executable i386
    ./sdcc (for architecture ppc): Mach-O executable ppc

    Any idea why I'm not able to run sdcc universal binary?

    Borut

     
  • Maarten Brock
    Maarten Brock
    2007-08-24

    updated valCastLiteral function

     
    Attachments
  • Maarten Brock
    Maarten Brock
    2007-08-24

    Logged In: YES
    user_id=888171
    Originator: NO

    Looking at this function some more I wonder why the signedness is not checked for bitfields. Or the other way around: why is signedness checked for those other types?

    And also are bitfields not allowed for long int's?

    I've attached a modified version of valCastLiteral. I think it's right, but I also get the feeling this is overdone. Anyway if nobody comments/objects I'll commit this next week.
    File Added: valCastLiteral.c

     
  • Borut Ražem
    Borut Ražem
    2007-08-24

    Logged In: YES
    user_id=568035
    Originator: NO

    I'm wondering if

    SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG)(TYPE_TARGET_LONG)fval;

    and similar double casts in other places where double is converted to unsigned int wouldn't do the job.

    Unfortunately currently I can't test it. I hope I'll be able to do it in few days.

    And one small additional correction: I think it would be more appropriate to use (TYPE_TARGET_CHAR) and (TYPE_TARGET_UCHAR) instead (TYPE_BYTE) and (TYPE_UBYTE).

    ... and change the sequence of "if (SPEC_NOUN (val->etype) == ...)" with a switch statement.

    Borut

     
  • Maarten Brock
    Maarten Brock
    2007-09-01

    Logged In: YES
    user_id=888171
    Originator: NO

    Borut,

    Were you able to do any testing?

    I also thought about double-casting but decided not to use it, because I'm afraid some compiler might throw away the inner cast.

    TYPE_TARGET_CHAR instead of TYPE_BYTE is fine by me. And so is using a switch.

    I have no access to a MacIntel, so I cannot test this.

    Maarten

     
  • Borut Ražem
    Borut Ražem
    2007-09-02

    Logged In: YES
    user_id=568035
    Originator: NO

    > Were you able to do any testing?

    Not yet, I'm still working on it.

    Borut

     
  • Borut Ražem
    Borut Ražem
    2007-10-01

    • assigned_to: nobody --> borutr
     
  • Logged In: NO

    Borut (et al.),

    I ran the regression suite with my patch and found that you are right; there are still plenty of other casting problems like this in the compiler.

    On the bright side, however, I have examined and compared the object code of valCastLiteral() on both the Mac OS X Intel and FreeBSD versions of SDCC and I can confidently tell you that the difference in behavior between these versions is that the Mac OS X version appears to use SSE instructions for floating point math while the FreeBSD version uses i387 instructions.

    To test whether this change alone accounts for all of the recent Mac OS X Intel failures I ran a simple experiment. I configured SDCC to be compiled with the GCC flag '-mfpmath=397'. When I did so, all of the regression tests passed!

    So for the short term, you can work around this bug by setting the environment variable CFLAGS to the value '-mfpmath=397' before running 'configure'.

    For the long term, I think this clearly illustrates that there are a good number of undefined floating point operations in the SDCC code. The transition from 387 to SSE just seems to have exposed them.

     
  • Jeremy Cooper
    Jeremy Cooper
    2007-10-01

    Logged In: YES
    user_id=531281
    Originator: YES

    In my previous comment please change all references to '-mfpmath=397' to read '-mfpmath=387'.

     
  • Borut Ražem
    Borut Ražem
    2007-10-02

    Logged In: YES
    user_id=568035
    Originator: NO

    Jeremy,

    thanks for the workaround, but I already fixed the bug 1739860: "sdcc does not work correctly on some platforms.", which is a superset of this bug, so it should be now fixed too.

    Do you know which -mfpmath option is used on gcc 4.0.1 on Mac OS X by default (probably -mfpmath=sse)?

    Can you please rerun the regtests on the latest svn version and retry to reproduce the bug? Let me know about results.

    Borut

     
  • Borut Ražem
    Borut Ražem
    2007-10-02

    Logged In: YES
    user_id=568035
    Originator: NO

    Fixed in svn release #4926.

    Borut

     
  • Borut Ražem
    Borut Ražem
    2007-10-02

    • milestone: --> fixed
    • status: open --> closed-fixed
     
  • Jeremy Cooper
    Jeremy Cooper
    2007-10-10

    Logged In: YES
    user_id=531281
    Originator: YES

    I can confirm that the bug has been fixed in release #4929. Thanks!