my new favourite wrong code bug

claptrap clap at trap.com
Sun Feb 26 20:47:47 UTC 2023


On Sunday, 26 February 2023 at 12:49:25 UTC, ag0aep6g 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.

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?


More information about the Digitalmars-d mailing list