Bug 16268 – Wrong loop optimization in code with integer overflow
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2016-07-12T10:50:01Z
Last change time
2020-09-04T09:07:27Z
Keywords
backend, pull, wrong-code
Assigned to
No Owner
Creator
Guillaume Boucher
Comments
Comment #0 by guillaume.boucher.d — 2016-07-12T10:50:01Z
The following program behaves incorrectly when compiled with "-O":
import std.stdio;
void f(byte x)
{
for (byte i = 0; i <= x && i >= 0; ++i)
{
assert(i >= 0);
writeln(i);
}
}
void main()
{
f(byte.max);
}
Compiled without flags, this program prints the numbers from 0 to 127 and terminates.
Compiled with "-O", this program prints the numbers from 0 to 127, and then repeats -128, -127, ..., 127 infinitely. It does not terminate.
The program should print the numbers from 0 to 127 once. Signed overflow is defined behaviour, therefore "i >= 0" can not be assumed to be true. Note how even the assertion is ignored.
Same problem happens with short and int instead of byte.
If one replaces 0 with 1, the program prints 0..127, -128..-1 and terminates. It should only print 1..127.
(DMD v2.071.1)
Comment #1 by lodovico — 2016-07-12T18:17:20Z
Looking at the generated assembly, it looks like, as a check x >= 0 is performed before entering the loop, the compiler establishes that overflow will not happen while condition i <= x holds (with x not negative).
Of course this is false for the edge case of x = typeof(x).max.
00 push rbp
01 mov rbp,rsp
04 push rbx
05 push r12
07 mov r12,rdi
0a xor ebx,ebx ; i = 0
0c test r12b,r12b
0f js 21 ; if x < 0 skip for loop
11 movsx edi,bl
15 call <writeln> ; call writeln
1a inc bl ; i++
1c cmp bl,r12b
1f jle 11 ; if i <= x continue for loop
21 pop r12
23 pop rbx
24 pop rbp
25 ret
Comment #2 by dlang-bot — 2020-09-04T01:31:21Z
@WalterBright created dlang/dmd pull request #11682 "fix Issue 16268 - Wrong loop optimization in code with integer overflow" fixing this issue:
- fix Issue 16268 - Wrong loop optimization in code with integer overflow
https://github.com/dlang/dmd/pull/11682
Comment #3 by dlang-bot — 2020-09-04T09:07:27Z
dlang/dmd pull request #11682 "fix Issue 16268 - Wrong loop optimization in code with integer overflow" was merged into master:
- 1242db33a498b15ea7fe40e951d1d44e82440b89 by Walter Bright:
fix Issue 16268 - Wrong loop optimization in code with integer overflow
https://github.com/dlang/dmd/pull/11682