Thread overview
my new favourite wrong code bug
Feb 26, 2023
ag0aep6g
Feb 26, 2023
H. S. Teoh
Feb 26, 2023
claptrap
Feb 27, 2023
user1234
February 26, 2023
void main()
{
    ubyte[] a = [1];
    foreach (x; a)
    {
        ubyte v = x >= 1 ? 255 : 0;
        assert(v == 255); /* fails; should pass */
    }
}

Astonishing.

Filed as issue 23743.

Reminds me of issue 18315 ("wrong code for i > 0") which was similarly ridiculous.

February 26, 2023
On Sun, Feb 26, 2023 at 12:49:25PM +0000, ag0aep6g via Digitalmars-d wrote:
> ```d
> void main()
> {
>     ubyte[] a = [1];
>     foreach (x; a)
>     {
>         ubyte v = x >= 1 ? 255 : 0;
>         assert(v == 255); /* fails; should pass */
>     }
> }
> ```
> 
> Astonishing.
> 
> Filed as [issue 23743](https://issues.dlang.org/show_bug.cgi?id=23743).
> 
> Reminds me of [issue 18315](https://issues.dlang.org/show_bug.cgi?id=18315)
> ("wrong code for `i > 0`") which was similarly ridiculous.

LDC and GDC both work fine.


T

-- 
Trying to define yourself is like trying to bite your own teeth. -- Alan Watts
February 26, 2023

On Sunday, 26 February 2023 at 12:49:25 UTC, ag0aep6g wrote:

>
void main()
{
    ubyte[] a = [1];
    foreach (x; a)
    {
        ubyte v = x >= 1 ? 255 : 0;
        assert(v == 255); /* fails; should pass */
    }
}

Astonishing.

Filed as issue 23743.

Reminds me of issue 18315 ("wrong code for i > 0") which was similarly ridiculous.

Looking via godbolt

this line : ubyte v = x >= 1 ? 255 : 0; -->

xor EBX,EBX // 1 foreach index counter set to zero
mov RAX,-8[RBP] // 2 load address of array litteral
cmp [RAX][RBX],1 // 3 compare array element with 1
sbb R12D,R12D // 4 set R12D to zero, or FFFFFFFF if borrow flag set
not R12B // 5 invert the bits
mov EDI,R12D // lets pretent the result is 32 bits now?

I think the problem is that (4) does 32 bits 0 or FFFFFFF, and that (5) inverts only the lower 8 bits. IIRC writing to lower 32 bits register zeros the upper 64 bits, but writing to 16 or 8 bits doesn't affect the upper bits at all. I mean it would have broken a ton of existing code if they done that.

So i dont know if the error is that the NOT should be 32 bits, or that the following code should be using R12B and not thinking its a 32 bit value.

Even the (3) compare looks iffy, its an array of bytes but looks like the compare is 32 bit?

February 27, 2023

On Sunday, 26 February 2023 at 20:47:47 UTC, claptrap wrote:

>

[...]
Even the (3) compare looks iffy, its an array of bytes but looks like the compare is 32 bit?

I bet it's because of integral promotion. Once an element loaded it's promoted to int, i.e there should be a "signed extension". I see ldc does it in the form of a "movzx" instruction.