#793 SDCC int genOr bug

closed-rejected
None
5
2013-05-25
2004-07-29
Anonymous
No

I has found several mistakes in SDCC:

Source:
#include <8051.h>

#define pin1 P1_0

static unsigned int temp;
static unsigned int work;

unsigned char wrk(void)
{
return 0;
}

unsigned int test(void)
{
register unsigned char tmp1, tmp2;
register unsigned int tmp3;
tmp1=wrk();
tmp2=wrk();
tmp3=256*tmp1;
tmp3|=(unsigned char)tmp2;
temp=tmp3;
tmp1=wrk();
tmp2=wrk();
tmp3=(unsigned char)tmp1;
tmp3|=tmp2 << 8;
work=tmp3;
tmp3|=pin1;
temp=tmp3;
return tmp3;
}

unsigned int test2(void)
{
register unsigned int tmp;
register unsigned char wrk1, wrk2;
wrk1=wrk() ;
wrk2=wrk() ;
tmp=wrk2 << 8;
tmp|=wrk1;
return tmp;
}

void main(void)
{
}

SDCC run command:
sdcc --verbose --model-small --peep-asm -mmcs51 --
iram-size 128 --xram-size 0 --code-size 4096 --
nojtbound test.c

SDCC version:

SDCC :
mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51
/ds400/hc08 2.4.3 #779 (Jul 28 2004) (MINGW32)

Asm list:
329 ;------------------------------
------------------------------
330 ;Allocation info for local
variables in function 'test'
331 ;------------------------------
------------------------------
332 ;tmp1 Allocated
to registers r2
333 ;tmp2 Allocated
to registers r3
334 ;tmp3 Allocated
to registers r4 r5
335 ;------------------------------
------------------------------
336 ;test.c:13: unsigned int test
(void)
337 ; ---------------------------
--------------
338 ; function test
339 ; ---------------------------
--------------
0035 340 _test:
341 ;test.c:17: tmp1=wrk();
342 ; genCall
0035 12s00r31 343 lcall _wrk
0038 AA 82 344 mov r2,dpl
345 ;test.c:18: tmp2=wrk();
346 ; genCall
003A C0 02 347 push ar2
003C 12s00r31 348 lcall _wrk
003F AB 82 349 mov r3,dpl
0041 D0 02 350 pop ar2
351 ;test.c:19: tmp3=256*tmp1;
352 ; genCast
0043 8A 04 353 mov ar4,r2
354 ; genLeftShift
355 ; genLeftShiftLiteral
356 ; genlshTwo
357 ; peephole 177.e removed
redundant move
0045 8C 05 358 mov ar5,r4
0047 7C 00 359 mov r4,#0x00
360 ;test.c:20: tmp3|=(unsigned
char)tmp2;
361 ; genCast
0049 8B 06 362 mov ar6,r3
004B 7F 00 363 mov
r7,#0x00 <= Unneeded
operation
364 ; genOr
004D EE 365 mov a,r6
004E 42 04 366 orl ar4,a
0050 EF 367 mov
a,r7 <= Unneeded
operation
0051 42 05 368 orl
ar5,a <= Unneeded
operation
369 ;test.c:21: temp=tmp3;
370 ; genAssign
0053 8C*00 371 mov _temp,r4
0055 8D*01 372 mov (_temp
+ 1),r5
373 ;test.c:22: tmp1=wrk();
374 ; genCall
0057 12s00r31 375 lcall _wrk
005A AA 82 376 mov r2,dpl
377 ;test.c:23: tmp2=wrk();
378 ; genCall
005C C0 02 379 push ar2
005E 12s00r31 380 lcall _wrk
0061 AB 82 381 mov r3,dpl
0063 D0 02 382 pop ar2
383 ;test.c:24: tmp3=(unsigned
char)tmp1;
384 ; genCast
0065 8A 04 385 mov ar4,r2
0067 7D 00 386 mov r5,#0x00
387 ;test.c:25: tmp3|=tmp2 << 8;
388 ; genCast
389 ; genLeftShift
390 ; genLeftShiftLiteral
391 ; genlshTwo
392 ; peephole 177.e removed
redundant move
0069 8B 02 393 mov ar2,r3
006B 7B 00 394 mov
r3,#0x00 <= Unneeded
operation
395 ; genOr
006D EB 396 mov
a,r3 <= Unneeded
operation
006E 42 04 397 orl
ar4,a <= Unneeded
operation
0070 EA 398 mov a,r2
0071 42 05 399 orl ar5,a
400 ;test.c:26: work=tmp3;
401 ; genAssign
0073 8C*02 402 mov _work,r4
0075 8D*03 403 mov (_work +
1),r5
404 ;test.c:27: tmp3|=pin1;
405 ; genCast
0077 E4 406 clr a
0078 A2 90 407 mov c,_P1_0
007A 33 408 rlc a
409 ; genOr
410 ; Peephole 177.d removed
redundant move
007B FA 411 mov r2,a
007C 7B 00 412 mov
r3,#0x00 <= Unneeded
operation
007E 42 04 413 orl ar4,a
0080 EB 414 mov
a,r3 <= Unneeded
operation
0081 42 05 415 orl
ar5,a <= Unneeded
operation
416 ;test.c:28: temp=tmp3;
417 ; genAssign
0083 8C*00 418 mov _temp,r4
0085 8D*01 419 mov (_temp
+ 1),r5
420 ;test.c:29: return tmp3;
421 ; genRet
0087 8C 82 422 mov dpl,r4
0089 8D 83 423 mov dph,r5
008B 424 00101$:
008B 22 425 ret
426 ;------------------------------
------------------------------
427 ;Allocation info for local
variables in function 'test2'
428 ;------------------------------
------------------------------
429 ;tmp Allocated
to registers r3 r4
430 ;wrk1 Allocated
to registers r2
431 ;wrk2 Allocated
to registers r3
432 ;------------------------------
------------------------------
433 ;test.c:32: unsigned int test2
(void)
434 ; ---------------------------
--------------
435 ; function test2
436 ; ---------------------------
--------------
008C 437 _test2:
438 ;test.c:36: wrk1=wrk() ;
439 ; genCall
008C 12s00r31 440 lcall _wrk
008F AA 82 441 mov r2,dpl
442 ;test.c:37: wrk2=wrk() ;
443 ; genCall
0091 C0 02 444 push ar2
0093 12s00r31 445 lcall _wrk
0096 AB 82 446 mov r3,dpl
0098 D0 02 447 pop ar2
448 ;test.c:38: tmp=wrk2 << 8;
449 ; genCast
450 ; genLeftShift
451 ; genLeftShiftLiteral
452 ; genlshTwo
453 ; peephole 177.e removed
redundant move
009A 8B 04 454 mov ar4,r3
455 ;test.c:39: tmp|=wrk1;
456 ; genCast
457 ; genOr
458 ; Peephole 3.c changed
mov to clr
009C E4 459 clr
a <= Unneeded
operation
009D FB 460 mov
r3,a <= Unneeded
operation
009E FD 461 mov
r5,a <= Unneeded
operation
009F EA 462 mov
a,r2 <= Unneeded
operation
00A0 42 03 463 orl
ar3,a <= Unneeded
operation
00A2 ED 464 mov
a,r5 <= Unneeded
operation
00A3 42 04 465 orl
ar4,a <= Unneeded
operation
466 ;test.c:40: return tmp;
467 ; genRet
00A5 8B 82 468 mov dpl,r3
00A7 8C 83 469 mov dph,r4
00A9 470 00101$:
00A9 22 471 ret

I'm fix these bug by the following peephole rules:

replace {
clr a
mov r%1,a
mov r%2,a
mov a,r%3
orl ar%1,a
mov a,r%2
orl ar%4,a
} by {
; Peephole R.1 super optimized int genOr
mov ar%1,r%3
}

replace {
mov r%1,#0x00
mov a,r%1
orl ar%2,a
mov a,r%3
orl ar%4,a
} by {
; Peephole R.2 optimized int genOr (low byte skip)
mov a,r%3
orl ar%4,a
}

replace {
mov r%1,#0x00
mov a,r%2
orl ar%3,a
mov a,r%1
orl ar%4,a
} by {
; Peephole R.3 optimized int genOr (high byte skip)
mov a,r%2
orl ar%3,a
}

replace {
mov r%1,#0x00
orl ar%2,a
mov a,r%1
orl ar%3,a
} by {
; Peephole R.4 optimized int genOr (high byte skip)
mov r%2,a
}

With the best wishes, Ruslan.

Discussion

  • Bernhard Held

    Bernhard Held - 2004-07-29

    Logged In: YES
    user_id=203539

    For my feeling these are not bugs, because the results are
    correct. Please accept that even the best optimizing C
    compiler will never generate code, which can keep up with
    hand optimized assembler. There will always be some
    overhead.
    It doesn't make much sense to try to fix all these small sub-
    optimal code snippets with peephole rules, because there are
    many, many combinations of code, in which you can find
    them. It would only make sense on a per-project basis in a
    performance-critical loop or in an ISR.
    The superflous "mov r%1,%2" is already reported in your
    feature request #1000079.

     
  • Bernhard Held

    Bernhard Held - 2004-07-29
    • milestone: --> non_bugs
    • assigned_to: nobody --> bernhardheld
    • status: open --> closed-rejected
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks