Compiler Bug? (DC 9.50)

I’m seeing what looks like a nasty bug in DC 9.50. I have the following code:


printf("q = ++p(%p)
", p);
if (!p)
  q = ++p;
else
{
  ++p;
  q=p;
}
printf("[done]q(%p)=++p(%p)
", q, p);

This generates the output:


q = ++p(8453)
[done]q(8711)=++p(8454)

Yikes!

If I invert that if condition (whose sole purpose is probing this bug), I get the following output:

 
q = ++p(8453)
[done]q(8454)=++p(8454)

Before we were using DC 9.25, but upgraded because we need to do commandline compiles, and 9.25’s commandline compiler can’t compile the tcp library. :frowning:

The assembly listing generated by DC9.50 for this is:


[MOTION.C(985:1)]: printf("q = ++p(%p)
", p);
00:e527 E4F0     ld hl, (ix + -16)              9
00:e529 E5       push hl                        10
00:e52a 21082B   ld hl, 0x2B08                  6
00:e52d E5       push hl                        10
[MOTION.C(985:23)]: , p);
00:e52e CFEDE919 lcall printf                   19
00:e532 2704     add sp, 4                      4
[MOTION.C(986:1)]: if (p)
00:e534 E4F0     ld hl, (ix + -16)              9
00:e536 CC       bool hl                        2
00:e537 CA67E5   jp z, 0xE567                   7
[MOTION.C(987:3)]: q = ++p;
00:e53a 211801   ld hl, 0x0118                  6
00:e53d D5       push de                        10
00:e53e DD5E00   ld e, (ix + 0)                 9
00:e541 DD5601   ld d, (ix + 1)                 9
00:e544 19       add hl, de                     2
00:e545 D1       pop de                         7
00:e546 E5       push hl                        10
00:e547 211A01   ld hl, 0x011A                  6
00:e54a D5       push de                        10
00:e54b DD5E00   ld e, (ix + 0)                 9
00:e54e DD5601   ld d, (ix + 1)                 9
00:e551 19       add hl, de                     2
00:e552 D1       pop de                         7
00:e553 E5       push hl                        10
00:e554 DDE400   ld hl, (hl + 0)                11
00:e557 23       inc hl                         2
00:e558 44       ld b, h                        2
00:e559 4D       ld c, l                        2
00:e55a E1       pop hl                         7
00:e55b 71       ld (hl), c                     6
00:e55c 23       inc hl                         2
00:e55d 70       ld (hl), b                     6
00:e55e 44       ld b, h                        2
00:e55f 4D       ld c, l                        2
00:e560 E1       pop hl                         7
00:e561 71       ld (hl), c                     6
00:e562 23       inc hl                         2
00:e563 70       ld (hl), b                     6
00:e564 C393E5   jp 0xE593                      7
[MOTION.C(988:1)]: else
[MOTION.C(990:1)]: ++p;
00:e567 211A01   ld hl, 0x011A                  6
00:e56a D5       push de                        10
00:e56b DD5E00   ld e, (ix + 0)                 9
00:e56e DD5601   ld d, (ix + 1)                 9
00:e571 19       add hl, de                     2
00:e572 D1       pop de                         7
00:e573 E5       push hl                        10
00:e574 DDE400   ld hl, (hl + 0)                11
00:e577 23       inc hl                         2
00:e578 44       ld b, h                        2
00:e579 4D       ld c, l                        2
00:e57a E1       pop hl                         7
00:e57b 71       ld (hl), c                     6
00:e57c 23       inc hl                         2
00:e57d 70       ld (hl), b                     6
[MOTION.C(991:1)]: q=p;
00:e57e 211801   ld hl, 0x0118                  6
00:e581 D5       push de                        10
00:e582 DD5E00   ld e, (ix + 0)                 9
00:e585 DD5601   ld d, (ix + 1)                 9
00:e588 19       add hl, de                     2
00:e589 D1       pop de                         7
00:e58a E5       push hl                        10
00:e58b E4F0     ld hl, (ix + -16)              9
00:e58d 44       ld b, h                        2
00:e58e 4D       ld c, l                        2
00:e58f E1       pop hl                         7
00:e590 71       ld (hl), c                     6
00:e591 23       inc hl                         2
00:e592 70       ld (hl), b                     6
[MOTION.C(992:1)]: }
[MOTION.C(993:1)]: printf("[done]q(%p)=++p(%p)
", q, p);
00:e593 E4F0     ld hl, (ix + -16)              9
00:e595 E5       push hl                        10
00:e596 E4EE     ld hl, (ix + -18)              9
00:e598 E5       push hl                        10
00:e599 213C2A   ld hl, 0x2A3C                  6
00:e59c E5       push hl                        10
[MOTION.C(993:31)]: , q, p);
00:e59d CFEDE919 lcall printf                   19
00:e5a1 2706     add sp, 6                      4

I’m far from an expert at rabbit assembly, but the two sides of the if ought to look similar, and there are some marked differences between the two.

I compiled the same chunk of code with DC 9.25, and got this assembly, which is markedly different and shorter:


[MOTION.C(976:1)]: printf("q = ++p(%p)
", p);
00:e9e7 E4F0     ld     hl,(ix-16)         9
00:e9e9 E5       push   hl                10
00:e9ea 21A32E   ld     hl,0x2EA3          6
00:e9ed E5       push   hl                10
[MOTION.C(976:27)]: ;
00:e9ee CF2EE219 lcall  printf            19
00:e9f2 2704     add    sp,0x04            4
[MOTION.C(977:1)]: if (!p)
00:e9f4 E4F0     ld     hl,(ix-16)         9
00:e9f6 CC       bool   hl                 2
00:e9f7 2B       dec    hl                 2
00:e9f8 CC       bool   hl                 2
00:e9f9 CA06EA   jp     z,0xEA06           7
[MOTION.C(978:3)]: q = ++p;
00:e9fc E4F0     ld     hl,(ix-16)         9
00:e9fe 23       inc    hl                 2
00:e9ff F4F0     ld     (ix-16),hl        11
00:ea01 F4EE     ld     (ix-18),hl        11
00:ea03 C30FEA   jp     0xEA0F             7
[MOTION.C(979:1)]: else
[MOTION.C(981:3)]: ++p;
00:ea06 E4F0     ld     hl,(ix-16)         9
00:ea08 23       inc    hl                 2
00:ea09 F4F0     ld     (ix-16),hl        11
[MOTION.C(982:3)]: q=p;
00:ea0b E4F0     ld     hl,(ix-16)         9
00:ea0d F4EE     ld     (ix-18),hl        11
[MOTION.C(983:1)]: }
[MOTION.C(984:1)]: printf("[done]q(%p)=++p(%p)
", q, p);
00:ea0f E4F0     ld     hl,(ix-16)         9
00:ea11 E5       push   hl                10
00:ea12 E4EE     ld     hl,(ix-18)         9
00:ea14 E5       push   hl                10
00:ea15 218E2E   ld     hl,0x2E8E          6
00:ea18 E5       push   hl                10
[MOTION.C(984:38)]: ;
00:ea19 CF2EE219 lcall  printf            19
00:ea1d 2706     add    sp,0x06            4