Menu

#2519 SDCC optimizes away statement even tough it shouldn't when mixing C with inline assembly

open
nobody
None
other
5
2016-07-06
2016-06-28
Sam
No

Hi,

When mixing C and inline assembly, SDCC optimizes away statements even tough it shouldn't.
Example:

__bit foo = 0;

int main()
{
    foo = 1; // this line is optimized away even if it shouldn't!

    __asm
        jb _foo, somelabel
    __endasm;

    foo = 0; // because SDCC thinks this assignment makes the first one unnecessary

    __asm
somelabel:
    __endasm;

    // foo should be 1 one, but is actually 0 because SDCC optimized away the first assigment to foo

    return foo;
}

The resulting assembly code looks like this:

;   -----------------------------------------
;    function main
;   -----------------------------------------
_main:
    ar7 = 0x07
    ar6 = 0x06
    ar5 = 0x05
    ar4 = 0x04
    ar3 = 0x03
    ar2 = 0x02
    ar1 = 0x01
    ar0 = 0x00
;   test.c:9: __endasm;
    jb _foo, somelabel
;   test.c:11: foo = 0;
    clr _foo
;   test.c:15: __endasm;
    somelabel:
;   test.c:19: return foo;
    mov dptr,#0x0000
    ret

Clearly, there is a setb _foo instruction missing.

new asm() format results in the same behaviour:
__asm__("jb _foo, somelabel");

Inserting a function call between the two assignments forces correct behaviour of the optimizer.

Compile the attached test.c with sdcc -c test.c

**$ sdcc-sdcc --version**
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.5.0 #9253 (Jul  4 2015) (Linux)
published under GNU General Public License (GPL)
2 Attachments

Discussion

  • Maarten Brock

    Maarten Brock - 2016-06-28

    Make foo volatile and it will be ok.

    I wonder what others think of this. Should inline asm be treated as a function call which can make all sorts of side effects or not? It could inhibit optimizations that the inline asm was supposed to bring as well. My take is that with inline asm comes a responsibility to take full control.

     
    • Sam

      Sam - 2016-06-29

      Using volatile is an excellent suggestion and indeed alleviates the problem.

      I would suggest to at least make note of this kind of issue in the SDCC manual.
      I concur that using inline assembly makes optimization your responsibility; At least in my case, that is exactly why I'm using it. I want to have as much control over the generated code as possible without the compiler interfering.

       
    • alvin

      alvin - 2016-07-04

      No, the compiler would be forced to generate poor code which would wipe out any gains. The way it is now is the right way I think. The compiler builds code around the inlined asm as if it weren't there and the peepholer assumes all registers are live leading into an inlined asm block unless it's allowed to look into the inlined asm via compile line argument. What we are really talking about is inlining a few instructions to access hw features not (efficiently?) available from C (disabling interrupts might be an example). If there is a significant amount of inlined asm, the function should be completely written in asm in the first place.

       
  • Sam

    Sam - 2016-07-06

    Well, at least the poor code would be correct ;)

    And no, we are not talking about inlining a few instructions (in which case I would more or less agree with you). At least I'm not. I have a project here where I have a few hundred lines of hand-optimized assembly for the hot path of some signal processing stuff. The rest of this function where speed is less essential is written in C as I find that much less cumbersome to write. I suppose, I could move these parts to separate functions, but that would incur additional overhead for the call and program flow.

    I find it very conventient to mix assembly and C, using the former when it matters and falling back to easier to read and write C when the generated code is good enough.

    How about a pragma to disable any optimizations? In my example, I really do not want the compiler to anything more fancy than simply assembling my instructions.

     

Log in to post a comment.