Menu

#2820 wrong code generation for union

closed-fixed
None
redundancy elimination
7
2018-10-15
2018-10-12
Nikolay
No

Hi!

Compiling the code below SDCC 10612 (MINGW32)

typedef union
{
    int32_t i;
    float f;
} intflt;

void sum(int8_t tp, intflt *if1, intflt *if2)
{
    if(tp)
        (*if1).f *= (*if2).f;
    else
        (*if1).i *= (*if2).i;
}

gives the next assembly:

    .area CODE
;   .\Source\main.c: 11: void sum(int8_t tp, intflt *if1, intflt *if2)
;   -----------------------------------------
;    function sum
;   -----------------------------------------
_sum:
    sub sp, #10
;   .\Source\main.c: 15: (*if1).f *= (*if2).f;
    ldw y, (0x0e, sp)
    ldw (0x09, sp), y
    ldw y, (0x10, sp)
    ldw x, (0x09, sp)
    ld  a, (0x3, x)
    ld  (0x08, sp), a
    ld  a, (0x2, x)
    ld  (0x07, sp), a
    ldw x, (x)
    ldw (0x05, sp), x
    ldw x, y
    ldw y, (0x2, y)
    ldw x, (x)
    pushw   y
    pushw   x
    ldw x, (0x0b, sp)
    pushw   x
    ldw x, (0x0b, sp)
    pushw   x
;   .\Source\main.c: 13: if(tp)
    call    ___fsmul
    addw    sp, #8
    ldw (0x01, sp), y
    tnz (0x0d, sp)
    jreq    00102$
;   .\Source\main.c: 15: (*if1).f *= (*if2).f;
    ldw y, (0x09, sp)
    ldw (0x2, y), x
    ldw x, (0x01, sp)
    ldw (y), x
    jra 00104$
00102$:
;   .\Source\main.c: 19: (*if1).i *= (*if2).i;
    ldw y, (0x09, sp)
    ldw (0x2, y), x
    ldw x, (0x01, sp)
    ldw (y), x
00104$:
;   .\Source\main.c: 21: }
    addw    sp, #10
    ret

Unfortunately I don't see 32bit integer multiplication there :(

This code is ok:

void sum(int8_t tp, intflt *if1, intflt *if2)
{
    if(tp == 1)
        (*if1).f *= (*if2).f;
    else
    if(tp == 0)
        (*if1).i *= (*if2).i;
}

PS
Also I'm very upset with very inefficient indirection operation processing: it takes 10 bytes of stack memory. And the second variant of sum function uses 20 bytes of stack...

Discussion

  • Philipp Klaus Krause

    • Category: STM8 --> redundancy elimination
    • Priority: 5 --> 7
     
  • Philipp Klaus Krause

    Looks as if lospre doesn't see the difference between float and long multiplication here. The bug is not stm8-specific.
    Workaround: Use --nolospre.
    Increasing priority, since bad code is generated silently.

    Philipp

     
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    Fixed in [r10615].

    Philipp

     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
     

Log in to post a comment.

MongoDB Logo MongoDB