teemperor updated this revision to Diff 220857.
teemperor marked 7 inline comments as done.
teemperor added a comment.

- Addressed feedback.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67227/new/

https://reviews.llvm.org/D67227

Files:
  
lldb/packages/Python/lldbsuite/test/commands/expression/ir-interpreter/TestIRInterpreter.py

Index: lldb/packages/Python/lldbsuite/test/commands/expression/ir-interpreter/TestIRInterpreter.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/commands/expression/ir-interpreter/TestIRInterpreter.py
+++ lldb/packages/Python/lldbsuite/test/commands/expression/ir-interpreter/TestIRInterpreter.py
@@ -5,6 +5,7 @@
 from __future__ import print_function
 
 import unittest2
+import ctypes
 
 import lldb
 from lldbsuite.test.decorators import *
@@ -40,6 +41,37 @@
 
         self.runCmd("run", RUN_SUCCEEDED)
 
+    class Variable:
+        def __init__(self, uid, type, value):
+            self.name = "$i_" + str(uid) + "_" + type.replace(" ", "_")
+            self.type = type
+            self.value = value
+            # The value may be different if it's negative and we have an
+            # unsigned type. Let's ask Python for the actual converted value on
+            # the current platform.
+            if type == "unsigned int":
+                self.value = ctypes.c_uint(self.value)
+            elif "unsigned" in type:
+                assert False, "Unsupported unsigned type: " + type
+            self.decl_expr = type + " " + self.name + " = " + str(self.value)
+
+    class Operator:
+        def __init__(self, name):
+           self.name = name
+
+        def can_handle_operands(self, lhs, rhs):
+            """True iff this operator can handle the variables as operands."""
+            if self.name in ['<<', '>>']:
+                # Shifting negative values, shifting by negative values and
+                # shifting by too large values will make this test fail (as
+                # the interpreter will evaluate this differently than the JIT).
+                # FIXME: This is probably a bug in the IRInterpreter.
+                if lhs.value <= 0:
+                    return False
+                if rhs.value <= 0 or rhs.value >= 32:
+                    return False
+            return True
+
     @add_test_categories(['pyapi'])
     # getpid() is POSIX, among other problems, see bug
     @expectedFailureAll(
@@ -50,35 +82,74 @@
         oslist=['linux'],
         archs=['arm'],
         bugnumber="llvm.org/pr27868")
-    def test_ir_interpreter(self):
+    def test_ir_interpreter_int_ops(self):
         self.build_and_run()
 
+        # Normal expression options we use for JITed expressions.
         options = lldb.SBExpressionOptions()
         options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
 
-        set_up_expressions = ["int $i = 9", "int $j = 3", "int $k = 5"]
-
-        expressions = ["$i + $j",
-                       "$i - $j",
-                       "$i * $j",
-                       "$i / $j",
-                       "$i % $k",
-                       "$i << $j",
-                       "$i & $j",
-                       "$i | $j",
-                       "$i ^ $j"]
-
-        for expression in set_up_expressions:
-            self.frame().EvaluateExpression(expression, options)
-
-        for expression in expressions:
+        # Expression options that prevent that we use the JIT.
+        nojit_options = lldb.SBExpressionOptions()
+        nojit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+        nojit_options.SetAllowJIT(False)
+
+        # List of operators the interpreter supports and we want to test.
+        operators = ['+', '-', '*', '%', '/',
+                     '<<', '>>', '&', '|', '^',
+                     '>', '<', '>=', '<=', '!=', '==']
+        operator_list = []
+        for opname in operators:
+            operator_list.append(self.Operator(opname))
+
+        # Variable types that should be tested with the operators.
+        types_to_test = ['int', 'unsigned int']
+
+        # Values these variables can have.
+        values_to_test = [255, 256, -1, 0, 1, 255, 256]
+
+        # Id for every variable to give them unique names.
+        uid = 0
+        # Define a variable for every type and for every value in LLDB.
+        variable_list = []
+        for t in types_to_test:
+            for value in values_to_test:
+                v = self.Variable(uid, t, value)
+                variable_list.append(v)
+                # FIXME: We should check for errors here, but declaring
+                # $variables just returns some empty error it seems...
+                self.frame().EvaluateExpression(v.decl_expr, nojit_options)
+                uid += 1
+
+        # Create a list of expressions that use every operator.
+        exprs_to_run = []
+        for op in operator_list:
+            # Try all combinations of variables with the operator.
+            for var1 in variable_list:
+                for var2 in variable_list:
+                    if not op.can_handle_operands(var1, var2):
+                        continue
+                    # Create an expression using the operator.
+                    expr = var1.name + " " + op.name + " " + var2.name
+                    # Resolve the variable values and add that as a comment
+                    # to the expression. This will be shown when the test fails.
+                    expr += " // " + str(var1.value) + " " + op.name + " " + str(var2.value)
+                    exprs_to_run.append(expr)
+
+        # Make sure we actually did generate a list of expressions.
+        assert len(exprs_to_run) != 0
+        for expression in exprs_to_run:
             interp_expression = expression
+            # We call 'getpid()' as a trick to force the expression to JITed.
+            # FIXME: Find a non-hacky way to tell LLDB to enforce this.
             jit_expression = "(int)getpid(); " + expression
 
+            # Run the expression in the interpreter and in the JIT. Both
+            # should produce the same result.
             interp_result = self.frame().EvaluateExpression(
-                interp_expression, options).GetValueAsSigned()
+                interp_expression, nojit_options).GetValueAsUnsigned()
             jit_result = self.frame().EvaluateExpression(
-                jit_expression, options).GetValueAsSigned()
+                jit_expression, options).GetValueAsUnsigned()
 
             self.assertEqual(
                 interp_result,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to