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