#722 conditional instructions bug

closed-rejected
5
2013-05-25
2004-03-12
Anonymous
No

Hello

In attached file "bug.txt" you will find a piece of C code
and assembler listing for this code. In short bug is
following:

after using code "if (a == 0 && b ==0)" variable "a"
changes. If I use code "if (a != 0)" in following
instructions it doesn't work correctly because "a" was
already changed. This bug appears also in lastest
version.

My mail
krzysztof.bak@wilk.com.pl

Discussion

  • Nobody/Anonymous

    bug

     
  • Bernhard Held

    Bernhard Held - 2004-03-12

    Logged In: YES
    user_id=203539

    Unfortunately your bug report is incomplete.

    What happens is:
    - variable a is stored r2
    - then the result of (a == 0) is stored in r2
    - this result is reused for (a != 0)

    This is a legal optimization, because your source fragments
    don't change variable a between step 2 and 3.
    Please supply a _complete_, _compileable_ sample code to
    reproduce the problem. Or consider using the
    modifier "volatile", if variable a is modified by an interrupt
    service routine.

     
  • Nobody/Anonymous

    Logged In: NO

    Hi

    I have writen an example code which shows bug. In this
    example you can see that instruction "if (a ==0 && b ==0)"
    changes local variable "a" which is allocated to registers "r2".
    If I use "a" next - for example "if (a == 5)", this condition will
    be never true, because "a" (my register "r2") is a=0 or a=1.
    See this code/compile (I have sdcc version 2.4.0):

    264 ;test.c:18: if (a == 0 && b == 0)
    265 ; genCmpEq
    266 ; Peephole 241.c optimized
    compare
    0035 E4 267 clr a
    0036 BA 00 01 268 cjne r2,#0x00,00114$
    0039 04 269 inc a
    003A 270 00114$:
    003A 271 00115$:
    272 ; genIfx
    273 ; Peephole 105 removed
    redundant mov
    003A FA 274 mov r2,a

    SAMPLE CODE

    #include "8051.h"

    char global1;
    char global2;

    char test_function()
    {
    char a;
    char b;

    a =0;
    b =0;

    a = a | global1;
    b = b | global2;

    if (a == 0 && b == 0)
    return 0;

    if (a != 0)
    return 1;

    if (b != 0)
    return 2;

    return 3;
    }

    void main()
    {

    global1 = P0;
    global2 = P2;

    P3 = test_function();

    for (;;);

    }

     
  • Bernhard Held

    Bernhard Held - 2004-03-13
    • status: open --> closed
     
  • Bernhard Held

    Bernhard Held - 2004-03-13

    Logged In: YES
    user_id=203539

    You're fooled by the optimizations of SDCC. The variable "a" is stored in
    r2 until the comparison (a == 0). The life range analysis of SDCC
    detects, that "a" is no longer needed after this comparison. Therefore the
    register r2 can be assigned another temporary variable, in your case it's
    the result of (a == 0). The "allocation information for local variables" at
    the beginning of each funtion is only true for the first life range. After the
    end of the life range of variable "a" anything could be assigned to r2.

    > If I use "a" next - for example "if (a == 5)", this condition
    > will be never true
    If you use "a" at another place, the life ranges and with them the register
    allocation would be different. Don't assume anything, try it!

    There's still no code with a real problem, therefore I'm obliged to reject
    this bug report.

     
  • Bernhard Held

    Bernhard Held - 2004-03-13
    • milestone: 100454 --> non_bugs
    • assigned_to: nobody --> bernhardheld
    • status: closed --> closed-rejected
     

Log in to post a comment.