浏览代码

+ testcse2

Jonas Maebe 25 年之前
父节点
当前提交
6e996c65e5
共有 2 个文件被更改,包括 74 次插入1 次删除
  1. 2 1
      tests/testopt/readme.txt
  2. 72 0
      tests/testopt/testcse2.pp

+ 2 - 1
tests/testopt/readme.txt

@@ -4,4 +4,5 @@ Register variables:
   Readln ................................ testreg2.pp
   Range checking ........................ testreg3.pp
 Common subexpression elimination (assembler)
-  Multidimensional array index operation. testcse1.pp 
+  Multidimensional array index operation. testcse1.pp
+  CSE and range checking ................ testcse2.pp

+ 72 - 0
tests/testopt/testcse2.pp

@@ -0,0 +1,72 @@
+{ $OPT=-OG2}
+{$r+}
+
+type
+  tsubr = 1..100000;
+  tarr = array[1..10] of longint;
+
+function test(b: tsubr): longint;
+begin
+ test := b;
+end;
+
+var
+  p: ^longint;
+  l: longint;
+  a, a2: tarr;
+
+begin
+  getmem(p,4);
+  p^ := 100000;
+  l := 5;
+  { clear the optimizer state }
+  asm
+  end;
+{$r-}
+  { get p^ in eax, the following statement generates the code }
+  {   movl A,%eax                                             }
+  {   movl (%eax),%eax                                        }
+  a[p^] := l;
+{$r+}
+  { now, p^ gets rangechecked, this generates the code                  }
+  {   movl A,%eax        (1)                                            }
+  {   movl (%eax),%ecx   (1)                                            }
+  {   ...                                                               }
+  {   call rangecheck_procedure                                         }
+  {   pushl (%eax)                                                      }
+  {                                                                     }
+  { With the bug in the optimizer, the instructions marked with (1) are }
+  { replaced by                                                         }
+  {   movl %eax,%ecx                                                    }
+  {                                                                     }
+  { and as such the "pushl (%eax)" pushes a wrong value afterwards      }
+  l := test(p^);
+  if l <> 100000 then
+    begin
+      writeln('Problem 1!');
+      halt(1);
+    end;
+  p^ := 5;
+  l := 5;
+  { clear the optimizer state }
+  asm
+  end;
+{$r-}
+  { the following moves p^ in %edx }
+  a2[l] := a[p^];
+{$r+}
+  { same test as before, but now the original value comes from edx }
+  { instead of that it is already in eax (so check that it doesn't }
+  { replace the                                                    }
+  {   movl P,%eax                                                  }
+  {   movl (%eax),%ecx                                             }
+  { with                                                           }
+  {   movl %edx,%ecx                                               }
+  l := test(p^);
+  if l <> 5 then
+    begin
+      writeln('Problem 2!');
+      halt(1);
+    end;
+  freemem(p,4);
+end.