xref: /llvm-project/lldb/test/API/lang/c/fpeval/TestFPEval.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""Tests IR interpreter handling of basic floating point operations (fadd, fsub, etc)."""
2
3import lldb
4from lldbsuite.test.decorators import *
5from lldbsuite.test.lldbtest import *
6from lldbsuite.test import lldbutil
7
8
9class FPEvalTestCase(TestBase):
10    def setUp(self):
11        # Call super's setUp().
12        TestBase.setUp(self)
13        self.jit_opts = lldb.SBExpressionOptions()
14        self.jit_opts.SetAllowJIT(True)
15        self.no_jit_opts = lldb.SBExpressionOptions()
16        self.no_jit_opts.SetAllowJIT(False)
17        # Find the line number to break inside main().
18        self.line = line_number("main.c", "// Set break point at this line.")
19
20    def test(self):
21        """Test floating point expressions while jitter is disabled."""
22        self.build()
23        exe = self.getBuildArtifact("a.out")
24        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
25
26        # Break inside the main.
27        lldbutil.run_break_set_by_file_and_line(
28            self, "main.c", self.line, num_expected_locations=1, loc_exact=True
29        )
30
31        value = self.frame().EvaluateExpression("a + b", self.no_jit_opts)
32
33        self.runCmd("run", RUN_SUCCEEDED)
34        # test double
35        self.expect(
36            "expr --allow-jit false  -- a + b",
37            VARIABLES_DISPLAYED_CORRECTLY,
38            substrs=["double", "44"],
39        )
40        self.expect(
41            "expr --allow-jit false  -- a - b",
42            VARIABLES_DISPLAYED_CORRECTLY,
43            substrs=["double", "40"],
44        )
45        self.expect(
46            "expr --allow-jit false  -- a / b",
47            VARIABLES_DISPLAYED_CORRECTLY,
48            substrs=["double", "21"],
49        )
50        self.expect(
51            "expr --allow-jit false  -- a * b",
52            VARIABLES_DISPLAYED_CORRECTLY,
53            substrs=["double", "84"],
54        )
55        self.expect(
56            "expr --allow-jit false  -- a + 2",
57            VARIABLES_DISPLAYED_CORRECTLY,
58            substrs=["double", "44"],
59        )
60        self.expect(
61            "expr --allow-jit false  -- a > b",
62            VARIABLES_DISPLAYED_CORRECTLY,
63            substrs=["true"],
64        )
65        self.expect(
66            "expr --allow-jit false  -- a >= b",
67            VARIABLES_DISPLAYED_CORRECTLY,
68            substrs=["true"],
69        )
70        self.expect(
71            "expr --allow-jit false  -- a < b",
72            VARIABLES_DISPLAYED_CORRECTLY,
73            substrs=["false"],
74        )
75        self.expect(
76            "expr --allow-jit false  -- a <= b",
77            VARIABLES_DISPLAYED_CORRECTLY,
78            substrs=["false"],
79        )
80        self.expect(
81            "expr --allow-jit false  -- a == b",
82            VARIABLES_DISPLAYED_CORRECTLY,
83            substrs=["false"],
84        )
85        self.expect(
86            "expr --allow-jit false  -- a != b",
87            VARIABLES_DISPLAYED_CORRECTLY,
88            substrs=["true"],
89        )
90
91        # test single
92        self.expect(
93            "expr --allow-jit false  -- f + q",
94            VARIABLES_DISPLAYED_CORRECTLY,
95            substrs=["float", "44"],
96        )
97        self.expect(
98            "expr --allow-jit false  -- f - q",
99            VARIABLES_DISPLAYED_CORRECTLY,
100            substrs=["float", "40"],
101        )
102        self.expect(
103            "expr --allow-jit false  -- f / q",
104            VARIABLES_DISPLAYED_CORRECTLY,
105            substrs=["float", "21"],
106        )
107        self.expect(
108            "expr --allow-jit false  -- f * q",
109            VARIABLES_DISPLAYED_CORRECTLY,
110            substrs=["float", "84"],
111        )
112        self.expect(
113            "expr --allow-jit false  -- f + 2",
114            VARIABLES_DISPLAYED_CORRECTLY,
115            substrs=["float", "44"],
116        )
117        self.expect(
118            "expr --allow-jit false  -- f > q",
119            VARIABLES_DISPLAYED_CORRECTLY,
120            substrs=["true"],
121        )
122        self.expect(
123            "expr --allow-jit false  -- f >= q",
124            VARIABLES_DISPLAYED_CORRECTLY,
125            substrs=["true"],
126        )
127        self.expect(
128            "expr --allow-jit false  -- f < q",
129            VARIABLES_DISPLAYED_CORRECTLY,
130            substrs=["false"],
131        )
132        self.expect(
133            "expr --allow-jit false  -- f <= q",
134            VARIABLES_DISPLAYED_CORRECTLY,
135            substrs=["false"],
136        )
137        self.expect(
138            "expr --allow-jit false  -- f == q",
139            VARIABLES_DISPLAYED_CORRECTLY,
140            substrs=["false"],
141        )
142        self.expect(
143            "expr --allow-jit false  -- f != q",
144            VARIABLES_DISPLAYED_CORRECTLY,
145            substrs=["true"],
146        )
147
148        # compare jit and interpreter output
149        self.assertTrue(self.process().IsValid())
150        thread = lldbutil.get_stopped_thread(self.process(), lldb.eStopReasonBreakpoint)
151        self.assertTrue(thread.IsValid())
152        frame = thread.GetSelectedFrame()
153        self.assertTrue(frame.IsValid())
154
155        dividents = [42, 79, 666]
156        divisors = [1.618, 2.718281828, 3.1415926535, 6.62607015]
157
158        for x in dividents:
159            for y in divisors:
160                vardef = "double x = {0}, y = {1};".format(x, y)
161                v1 = frame.EvaluateExpression(
162                    "{0}; eval(x, y, 2)".format(vardef), self.jit_opts
163                )
164                v2 = frame.EvaluateExpression(
165                    "{0}; x / y".format(vardef), self.no_jit_opts
166                )
167                self.assertTrue(v1.IsValid() and v2.IsValid())
168                self.assertEqual(str(v1.GetData()), str(v2.GetData()))
169