Подтвердить что ты не робот

Ошибка оптимизации Delphi 2006

В Delphi 2006 есть ошибка, если активировать проверку и оптимизацию переполнения. Кажется, что ошибка появляется только в конкретной ситуации, когда 32-битное целое добавляется к себе, а затем байт добавляется к этой предыдущей сумме в этом конкретном порядке, как показано ниже в программе.

program OptimizationBug;
{$OPTIMIZATION ON}
{$APPTYPE CONSOLE}

{$OVERFLOWCHECKS ON}
function f: integer;
var i: integer;
    b: byte;
begin
    i:=0;
    b:=1;
    Result:=i+i+b;  
end;

{$OVERFLOWCHECKS OFF}
function g: integer;
var i: integer;
    b: byte;
begin
    i:=0;
    b:=1;
    Result:=i+i+b;
end;

begin
    writeLn(f);  //wrong, prints "2" in D2006
    writeLn(g);  //good,  prints "1"
    readLn;
end.

Примечание. Проверка переполнения должна быть закодирована в исходном файле, а не через параметры проекта. Это приводит нас к еще одной ошибке: обнаружение переполнения через параметры проекта не влияет.

Как видно на окне CPU, оптимизатор отвлекается на перемещение с нулевым расширением movzx (расширяя 8-битное значение до 32-битного значения) и проверкой переполнения, забывая загрузить байт b в отдельный регистр, перезаписывая предыдущее содержание, с чистым эффектом добавления b к себе вместо 2i. Верхняя половина ниже кода сборки относится к прослушанной функции, а нижняя - к строковой конструкции.

OptimizationBug.dpr.20: i:=0;
00403EAC 33C0             xor eax,eax
OptimizationBug.dpr.21: b:=1;
00403EAE B201             mov dl,$01
OptimizationBug.dpr.22: Result:=i+i+b;  
00403EB0 03C0             add eax,eax
00403EB2 7105             jno $00403eb9
00403EB4 E82BF5FFFF       call @IntOver
00403EB9 0FB6C2           movzx eax,dl    //BUG: should have x-moved DL to EDX register!
00403EBC 03C0             add eax,eax     //     (and added EDX to EAX)
00403EBE 7105             jno $00403ec5
00403EC0 E81FF5FFFF       call @IntOver
OptimizationBug.dpr.23: end;
00403EC5 C3               ret 
00403EC6 8BC0             mov eax,eax
OptimizationBug.dpr.30: i:=0;
00403EC8 33C0             xor eax,eax
OptimizationBug.dpr.31: b:=1;
00403ECA B201             mov dl,$01
OptimizationBug.dpr.32: Result:=i+i+b;
00403ECC 03C0             add eax,eax
00403ECE 0FB6D2           movzx edx,dl    //OK!
00403ED1 03C2             add eax,edx     //ok
OptimizationBug.dpr.33: end;
00403ED3 C3               ret 

Кстати, этот код не является патологическим примером, я нашел его, адаптируя великолепную программу TeX от D.Knuth к современному Паскалю. При проверке эффекта включения оптимизации и отключения всех проверок компилятора на окончательный размер *.exe он не смог правильно интерпретировать сохраненные хэш-таблицы диска (которые были сгенерированы с отключенной оптимизацией), которые я проследил до над ошибкой, которая является частью, которая генерирует таблицы.

Вопрос прост, может ли кто-нибудь проверить программу на более новой версии Delphi?

4b9b3361

Ответ 1

Ошибка не была исправлена ​​даже в последней версии Delphi, XE6. Ошибка не влияет на 64-битный компилятор Windows. Ошибка присутствует еще в Delphi 6, самой старой версии, которую я могу запустить.

Я настоятельно рекомендую вам представить отчет о контроле качества.