Menu

#480 16 bit compare unexpectedly used in compare and switch statements

None
closed-fixed
None
5
2016-01-04
2016-01-02
No

The issue "[sdcc-devel] pic14 code size increase from sdcc 3.5.0 to 3.5.5-trunk"
https://sourceforge.net/p/sdcc/mailman/message/34689491/
is not specific to the pic14 port.

The attached source reproduces the unexpected (at least for me) use of 16 bit instead of 8 bit operations for e.g. mcs51 with sdcc 3.5.5 #9437

1 Attachments

Discussion

  • Ben Shi

    Ben Shi - 2016-01-03
    • status: open --> closed-wont-fix
    • assigned_to: Philipp Klaus Krause
    • Category: other --> Front-end
     
  • Ben Shi

    Ben Shi - 2016-01-03

    Philipp changed char literal from char type to int for supporting _Generic in C11.

     
  • Maarten Brock

    Maarten Brock - 2016-01-03

    This feels ridiculous. SDCC is especially for targettng 8 bit processors. This should be solved instead waved away.

     
  • Ben Shi

    Ben Shi - 2016-01-04

    Need further optimization.

     
  • Ben Shi

    Ben Shi - 2016-01-04
    • status: closed-wont-fix --> open
    • assigned_to: Philipp Klaus Krause --> Ben Shi
     
  • Philipp Klaus Krause

    Quick comparison using current (#9441) sdcc.

    character literals as int:

    Running mcs51-stack-auto regression tests
    Summary for 'mcs51-stack-auto': 0 failures, 7419 tests, 1760 test cases, 2689421 bytes, 235491120 ticks
    
    Running stm8 regression tests
    Summary for 'stm8': 0 failures, 9424 tests, 1761 test cases, 2048855 bytes, 7770241 ticks
    
    Running ucz80 regression tests
    Summary for 'ucz80': 0 failures, 9425 tests, 1761 test cases, 2532575 bytes, 12944431 ticks
    
    Running ucr2k regression tests
    Summary for 'ucr2k': 0 failures, 9414 tests, 1761 test cases, 2468444 bytes, 12017427 ticks
    
    Running ds390 regression tests
    Summary for 'ds390': 0 failures, 9385 tests, 1760 test cases, 7108096 bytes, 907790868 ticks
    

    character literals as char:

    Running mcs51-stack-auto regression tests
    Summary for 'mcs51-stack-auto': 3 failures, 7419 tests, 1760 test cases, 2686689 bytes, 235711440 ticks
       Failure: gen/mcs51-stack-auto/charconst/charconst
       Failure: gen/mcs51-stack-auto/generic/generic
    
    Running stm8 regression tests
    Summary for 'stm8': 3 failures, 9424 tests, 1761 test cases, 2046513 bytes, 7771709 ticks
       Failure: gen/stm8/charconst/charconst
       Failure: gen/stm8/generic/generic
    
    Running ucz80 regression tests
    Summary for 'ucz80': 3 failures, 9425 tests, 1761 test cases, 2526870 bytes, 12949251 ticks
       Failure: gen/ucz80/charconst/charconst
       Failure: gen/ucz80/generic/generic
    
    Running ucr2k regression tests
    Summary for 'ucr2k': 3 failures, 9414 tests, 1761 test cases, 2463296 bytes, 12022194 ticks
       Failure: gen/ucr2k/charconst/charconst
       Failure: gen/ucr2k/generic/generic
    
    Running ds390 regression tests
    Summary for 'ds390': 3 failures, 9385 tests, 1760 test cases, 7106220 bytes, 908665968 ticks
       Failure: gen/ds390/charconst/charconst
       Failure: gen/ds390/generic/generic
    

    Philipp

     
  • Philipp Klaus Krause

    Ticket moved from /p/sdcc/bugs/2447/

    Can't be converted:

    • _category: Front-end
    • assigned_to: benshi (user not in project)
     
  • Philipp Klaus Krause

    Moved to feature requests, since I consider this to be a feature request for optimization: Where a character literal is compared to a char, SDCC should optimize the comparison into an 8-bit one.
    For some reason, SDCC currently is sometimes able to optimize comparisons of char to integer constant expressions other than character literals. We would want the optimization to work for character literals, too.

    Both of the following should result in an 8-bit comparison:

    (c == 7)
    (c == 'c')
    

    Similar for the switch case labels.

    Philipp

     
    • Philipp Klaus Krause

      Actually, it seems, in SDCC, integer constants without suffix in the range -128 to -1 have type signed char, and those in 0 to 255 have unsigned char.

      Looking at constVal() integer constants seem to be quite a mess wrt. their type. IMO, integer constants should have the type the standard says. And an optimization should later deal with making the operations cheaper.

      Philipp

       
  • Philipp Klaus Krause

    Ticket moved from /p/schlange/feature-requests/3/

     
    • Philipp Klaus Krause

      I accidentially moved the ticket to the wrong project when moving it to feature requests.

      Philipp

       
  • Philipp Klaus Krause

    In revision [r9442], I introduced an optimization for comparions of cheap variables to expensive constants. This makes comparisons 8-bit again, even with int character literals. And it optimizes some further cases. e.g. for an unsigned char d,

    d == 7ul
    

    was a 32-bit comparison before, but now its an 8-bit comparison. The optimization makes code size go down on the regression tests, but not as much as character literals being char. This is not surprising, since I only implemented the optimization for explicit comparisons, but didn't look at switch or other constructs yet.

    Philipp

     

    Last edit: Maarten Brock 2016-01-04
    • Philipp Klaus Krause

      Actually the switch from the example is optimized, too, since geniCodeLogic() is involved, and I implemented the optimization there. I'll have to investigate which other places will need optimizations to completly eliminate the code size increase from changing the type of character literals to int.

      Philipp

       
  • Philipp Klaus Krause

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

    I just forgot to recompile the library before comparing the code size on the regression test. I just recompiled it now, and it turns out that code size with the optimization and character literalsof type int is already lower compared to without the optimization and type char. So I'm closing this issue now.

    Philipp

    P.S.: I compared code sizes using stm8 and mcs51-stack-auto.

     
  • Maarten Brock

    Maarten Brock - 2016-01-04

    If I read you right, you only optimized comparisons. I would expect the same issue with arithmetic. E.g.
    unsigned char x, y;
    x = y + 10;
    My suspicion is that the constant 10 is now a (signed) int, y gets cast to int too and the addition is done in 16 bit before the result is cast back to an unsigned char and assigned to x.

    But worse, [r9442] fails to build the hc08 library:

    ../_atof.c:94: error 9: FATAL Compiler Internal Error in file 'gen.c' line number '2244' : aopForSym should never reach here
    Contact Author with source code
    make[5]: *** [_atof.rel] Error 1
    make[4]: [port-specific-objects] Error 2 (ignored)
    ../_atof.c:94: error 9: FATAL Compiler Internal Error in file 'gen.c' line number '2244' : aopForSym should never reach here
    Contact Author with source code
    make[5]: *** [_atof.rel] Error 1
    

    If you always build with "make > /dev/null" this should have been easy to catch.

     
    • Philipp Klaus Krause

      I havent changed 10 from char to int yet. But assume x = y + 'c';

      Old behaviour: 'c' is char, integer promotion casts y and 'c' to int. Optimiziation makes the + 8 bits since x is unsigned char.

      New behaviour: 'c' is int, integer promotion casts y to int. Optimiziation makes the + 8 bits since x is unsigned char.

      Same code results.

      Philipp

       
    • Philipp Klaus Krause

      In revision #9443 I disabled the optimization for hc08 and s08. See also bug #2450.

      Philipp

       
      • Philipp Klaus Krause

        Enabled for hc08 and s08 in rev #9681.

        Philipp

         
  • Philipp Klaus Krause

    Even though in general, character literals of type int + the optimization for compares tends to give much smaller code than character literals of type char, there are exceptions:

    bug-751703
    bug-927659 
    bug1057979
    bug1115321
    bug1509084
    bug1838000
    bug3381400
    gcc-torture-execute-20021120-3
    gcc-torture-execute-20030626-1
    gcc-torture-execute-20030626-2
    gcc-torture-execute-20070201-1
    gcc-torture-execute-20080529-1
    gcc-torture-execute-930123-1
    gcc-torture-execute-930513-1
    gcc-torture-execute-940122-1
    gcc-torture-execute-960327-1
    scott-add
    scott-for
    scott-sub
    snprintf
    

    I'll look into these when I find time, maybe tomorrow.

    Philipp

     

Log in to post a comment.