瀏覽代碼

* check used registers properly for SETcc/TEST/Jcc -> Jcc, resolves #38940

git-svn-id: trunk@49405 -
florian 4 年之前
父節點
當前提交
f2e0af6d37
共有 3 個文件被更改,包括 26 次插入1 次删除
  1. 1 0
      .gitattributes
  2. 3 1
      compiler/x86/aoptx86.pas
  3. 22 0
      tests/webtbs/tw38940.pp

+ 1 - 0
.gitattributes

@@ -18861,6 +18861,7 @@ tests/webtbs/tw38802.pp svneol=native#text/pascal
 tests/webtbs/tw38832.pp svneol=native#text/pascal
 tests/webtbs/tw38832.pp svneol=native#text/pascal
 tests/webtbs/tw38833.pp svneol=native#text/plain
 tests/webtbs/tw38833.pp svneol=native#text/plain
 tests/webtbs/tw3893.pp svneol=native#text/plain
 tests/webtbs/tw3893.pp svneol=native#text/plain
+tests/webtbs/tw38940.pp svneol=native#text/pascal
 tests/webtbs/tw3898.pp svneol=native#text/plain
 tests/webtbs/tw3898.pp svneol=native#text/plain
 tests/webtbs/tw3899.pp svneol=native#text/plain
 tests/webtbs/tw3899.pp svneol=native#text/plain
 tests/webtbs/tw3900.pp svneol=native#text/plain
 tests/webtbs/tw3900.pp svneol=native#text/plain

+ 3 - 1
compiler/x86/aoptx86.pas

@@ -6951,7 +6951,9 @@ unit aoptx86;
                     taicpu(hp2).SetCondition(SetC);
                     taicpu(hp2).SetCondition(SetC);
                   end;
                   end;
 
 
-                if not RegUsedAfterInstruction(taicpu(p).oper[0]^.reg, hp2, TmpUsedRegs) then
+                { as hp2 is a jump, we cannot use RegUsedAfterInstruction but we have to check if it is included in
+                  TmpUsedRegs }
+                if not TmpUsedRegs[getregtype(taicpu(p).oper[0]^.reg)].IsUsed(taicpu(p).oper[0]^.reg) then
                   begin
                   begin
                     RemoveCurrentp(p, hp2);
                     RemoveCurrentp(p, hp2);
                     DebugMsg(SPeepholeOptimization + 'SETcc/TEST/Jcc -> Jcc',p);
                     DebugMsg(SPeepholeOptimization + 'SETcc/TEST/Jcc -> Jcc',p);

+ 22 - 0
tests/webtbs/tw38940.pp

@@ -0,0 +1,22 @@
+{ %OPT=-O3 }
+procedure Test;
+var b:boolean;
+    i:longint;
+begin
+// the following loop should be done 2 time, but it hangs up;
+ b:=true;
+ i:=0;
+ repeat
+   inc(i);
+   if i>2 then 
+     halt(1);
+   b:=not b; // first time b is set to false thats why the loop should be done again
+              // second time b is set to true thats why the loop should be leave,
+              // but hangs up
+ until b;
+end;
+
+begin
+  Test;
+  writeln('ok');
+end.