Browse Source

* New tests that evaluate CMOVcc using a reference even if IfRefSafe returns False because the previous condition reads it

J. Gareth "Curious Kit" Moreton 2 years ago
parent
commit
b997e41366
2 changed files with 98 additions and 0 deletions
  1. 47 0
      tests/test/cg/tcond2.pp
  2. 51 0
      tests/test/cg/tcond2a.pp

+ 47 - 0
tests/test/cg/tcond2.pp

@@ -0,0 +1,47 @@
+{ %CPU=i386,x86_64 }
+{ %OPT=-a -O2 -CpCOREI }
+
+{ This test evaluates IsRefSafe returning false but still permitting CMOV
+  because the condition reads it }
+
+program tcond2;
+
+uses
+  CPU;
+
+type
+  PLongInt = ^LongInt;
+
+const
+  InputVal: array[0..3] of LongInt = (-1, 0, 2147483647, -2147483648);
+  Expected: array[0..3] of LongInt = (0, 0, 2147483647, 0);
+
+function ZeroClamp(const Reference: PLongInt): LongInt; noinline;
+  begin
+    ZeroClamp := 0;
+    if Reference^ > 0 then
+      ZeroClamp := Reference^;
+  end;
+
+var
+  X, Output: LongInt;
+
+begin
+  if not CMOVSupport then
+    begin
+      WriteLn('unsupported');
+      Halt(0);
+    end;      
+
+  for X := 0 to 3 do
+    begin
+      Output := ZeroClamp(@InputVal[X]);
+      if Output <> Expected[X] then
+        begin
+          WriteLn('FAIL: ZeroClamp(', InputVal[X], ') returned ', Output, '; expected ', Expected[X]);
+          Halt(1);
+        end;
+    end;
+
+  WriteLn('ok');
+end.

+ 51 - 0
tests/test/cg/tcond2a.pp

@@ -0,0 +1,51 @@
+{ %CPU=i386,x86_64 }
+{ %OPT=-a -O2 -CpCOREI }
+
+{ This test evaluates IsRefSafe returning false but still permitting CMOV
+  because the condition reads it }
+
+program tcond2a;
+
+uses
+  CPU;
+
+type
+  PLongInt = ^LongInt;
+
+const
+  InputVal: array[0..3] of LongInt = (-1, 0, 2147483647, -2147483648);
+  Expected: array[0..3] of LongInt = (0, 0, 2147483647, 0);
+
+function ZeroClamp(const Reference: PLongInt): LongInt; noinline;
+  begin
+    { Note, reversing the if-statement so the Reference^ write is not in the
+      'else' block causes the code for "ZeroClamp := Reference^" to be a
+      regular MOV }
+    if Reference^ <= 0 then
+      ZeroClamp := 0
+    else
+      ZeroClamp := Reference^
+  end;
+
+var
+  X, Output: LongInt;
+
+begin
+  if not CMOVSupport then
+    begin
+      WriteLn('unsupported');
+      Halt(0);
+    end;      
+
+  for X := 0 to 3 do
+    begin
+      Output := ZeroClamp(@InputVal[X]);
+      if Output <> Expected[X] then
+        begin
+          WriteLn('FAIL: ZeroClamp(', InputVal[X], ') returned ', Output, '; expected ', Expected[X]);
+          Halt(1);
+        end;
+    end;
+
+  WriteLn('ok');
+end.