[PATCH] D50095: Verification test of SolveQuadraticEquationWrap from D48283

Krzysztof Parzyszek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 31 11:46:27 PDT 2018


kparzysz created this revision.
Herald added a subscriber: llvm-commits.

Brute force test for solutions of all equations with a given value bit width.

Successfully ran for all widths from 2 to 10 inclusive.


Repository:
  rL LLVM

https://reviews.llvm.org/D50095

Files:
  quadratic-test.cpp
  quadratic-test.mak


Index: quadratic-test.cpp
===================================================================
--- /dev/null
+++ quadratic-test.cpp
@@ -0,0 +1,76 @@
+#include <llvm/ADT/APInt.h>
+#include <llvm/ADT/Optional.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Support/Debug.h>
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+
+using namespace llvm;
+
+int64_t OverflowBits(int64_t V, unsigned W) {
+  return V & -(1 << W);
+}
+
+void Validate(int A, int B, int C, unsigned Width, int Solution) {
+  int Mask = (1 << Width) - 1;
+
+  if (Solution == 0) {
+    assert((C & Mask) == 0 && "Invalid zero solution");
+    return;
+  }
+  assert(Solution >= 0 && "Solution should be non-negative");
+
+  auto Error = [&] (StringRef Msg, int64_t X, int64_t OverEntry,
+                    int64_t OverX) {
+    std::cerr << Msg.str() << A << "x^2 + " << B << "x + " << C
+              << ", solution " << Solution << "\nOverflow bits on entry: "
+              << OverEntry << ", overflow bits at iteration " << X << ": "
+              << OverX << '\n';
+    abort();
+  };
+
+  int64_t Over0 = OverflowBits(C, Width);
+
+  // This is the important part: make sure that there is no solution that
+  // is less than the calculated one.
+  for (int X = 1; X < Solution-1; ++X) {
+    int64_t VX = A*X*X + B*X + C;
+    int64_t OverX = OverflowBits(VX, Width);
+    if ((VX & Mask) == 0 || OverX != Over0)
+      Error("Unexpected early overflow: ", X, Over0, OverX);
+  }
+
+  // Verify that the calculated solution is indeed a solution.
+  int64_t VS = A*Solution*Solution + B*Solution + C;
+  int64_t OverS = OverflowBits(VS, Width);
+  if ((VS & Mask) != 0 && OverS == Over0)
+    Error("Expected overflow: ", Solution, Over0, OverS);
+}
+
+void Iterate(unsigned Width) {
+  assert(1 < Width && Width < 32);
+  int Low = -(1 << (Width-1));
+  int High = (1 << (Width-1));
+
+  for (int A = Low; A != High; ++A) {
+    if (A == 0)
+      continue;
+    for (int B = Low; B != High; ++B) {
+      for (int C = Low; C != High; ++C) {
+        Optional<APInt> S = APIntOps::SolveQuadraticEquationWrap(
+                              APInt(Width, A), APInt(Width, B), APInt(Width, C),
+                              Width);
+        if (S.hasValue())
+          Validate(A, B, C, Width, S->getSExtValue());
+      }
+    }
+  }
+}
+
+int main() {
+  for (unsigned i = 2; i != 11; ++i) {
+    std::cout << "Checking width " << i << '\n';
+    Iterate(i);
+  }
+}
Index: quadratic-test.mak
===================================================================
--- /dev/null
+++ quadratic-test.mak
@@ -0,0 +1,10 @@
+CPPFLAGS = $(shell llvm-config --cppflags)
+SYSLIBS  = $(shell llvm-config --system-libs)
+LDFLAGS  = $(shell llvm-config --ldflags)
+CC = clang++
+
+quadratic-test: quadratic-test.o
+	$(CC) $< -lLLVMSupport $(LDFLAGS) $(SYSLIBS) -lc++ -o $@
+
+%.o : %.cpp
+	$(CC) -O2 $(CPPFLAGS) -c $<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50095.158352.patch
Type: text/x-patch
Size: 2900 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180731/251d68a1/attachment.bin>


More information about the llvm-commits mailing list