kpdev42 created this revision.
kpdev42 added reviewers: clayborg, granata.enrico, davide, k8stone.
kpdev42 added a project: LLDB.
Herald added a subscriber: JDevlieghere.
Herald added a project: All.
kpdev42 requested review of this revision.
Patch adds support for fadd, fsub, fdiv, fmul and fcmp to IR interpreter.
~~~
OS Laboratory. Huawei RRI. Saint-Petersburg
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D126359
Files:
lldb/source/Expression/IRInterpreter.cpp
lldb/test/API/lang/c/fpeval/Makefile
lldb/test/API/lang/c/fpeval/TestFPEval.py
lldb/test/API/lang/c/fpeval/main.c
Index: lldb/test/API/lang/c/fpeval/main.c
===================================================================
--- /dev/null
+++ lldb/test/API/lang/c/fpeval/main.c
@@ -0,0 +1,10 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+int main (int argc, char const *argv[])
+{
+ double a = 42.0;
+ double b = 2.0;
+ return (long)(a + b); //// Set break point at this line.
+}
Index: lldb/test/API/lang/c/fpeval/TestFPEval.py
===================================================================
--- /dev/null
+++ lldb/test/API/lang/c/fpeval/TestFPEval.py
@@ -0,0 +1,52 @@
+"""Show bitfields and check that they display correctly."""
+
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class FPEvalTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.c', '// Set break point at this line.')
+
+ def test_and_run_command(self):
+ """Test 'frame variable ...' on a variable with bitfields."""
+ self.build()
+ exe = self.getBuildArtifact("a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break inside the main.
+ lldbutil.run_break_set_by_file_and_line(
+ self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ self.expect("expr --allow-jit false -- a + b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['double', '44'])
+ self.expect("expr --allow-jit false -- a - b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['double', '40'])
+ self.expect("expr --allow-jit false -- a / b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['double', '21'])
+ self.expect("expr --allow-jit false -- a * b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['double', '84'])
+ self.expect("expr --allow-jit false -- a + 2", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['double', '44'])
+ self.expect("expr --allow-jit false -- a > b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['true'])
+ self.expect("expr --allow-jit false -- a >= b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['true'])
+ self.expect("expr --allow-jit false -- a < b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['false'])
+ self.expect("expr --allow-jit false -- a <= b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['false'])
+ self.expect("expr --allow-jit false -- a == b", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs=['false'])
+
Index: lldb/test/API/lang/c/fpeval/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/lang/c/fpeval/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
Index: lldb/source/Expression/IRInterpreter.cpp
===================================================================
--- lldb/source/Expression/IRInterpreter.cpp
+++ lldb/source/Expression/IRInterpreter.cpp
@@ -167,6 +167,18 @@
const Constant *constant = dyn_cast<Constant>(value);
if (constant) {
+ if (constant->getValueID() == Value::ConstantFPVal) {
+ if (auto *cfp = dyn_cast<ConstantFP>(constant)) {
+ if (cfp->getType()->isDoubleTy())
+ scalar = cfp->getValueAPF().convertToDouble();
+ else if (cfp->getType()->isFloatTy())
+ scalar = cfp->getValueAPF().convertToFloat();
+ else
+ return false;
+ return true;
+ }
+ return false;
+ }
APInt value_apint;
if (!ResolveConstantValue(value_apint, constant))
@@ -189,9 +201,18 @@
lldb::offset_t offset = 0;
if (value_size <= 8) {
- uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
- return AssignToMatchType(scalar, llvm::APInt(64, u64value),
- value->getType());
+ Type *ty = value->getType();
+ if (ty->isDoubleTy()) {
+ scalar = value_extractor.GetDouble(&offset);
+ return true;
+ } else if (ty->isFloatTy()) {
+ scalar = value_extractor.GetFloat(&offset);
+ return true;
+ } else {
+ uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
+ return AssignToMatchType(scalar, llvm::APInt(64, u64value),
+ value->getType());
+ }
}
return false;
@@ -205,11 +226,15 @@
return false;
lldb_private::Scalar cast_scalar;
-
- scalar.MakeUnsigned();
- if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),
- value->getType()))
- return false;
+ Type *vty = value->getType();
+ if (vty->isFloatTy() || vty->isDoubleTy()) {
+ cast_scalar = scalar;
+ } else {
+ scalar.MakeUnsigned();
+ if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),
+ value->getType()))
+ return false;
+ }
size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
@@ -543,16 +568,17 @@
} break;
case Instruction::GetElementPtr:
break;
+ case Instruction::FCmp:
case Instruction::ICmp: {
- ICmpInst *icmp_inst = dyn_cast<ICmpInst>(&ii);
+ CmpInst *cmp_inst = dyn_cast<CmpInst>(&ii);
- if (!icmp_inst) {
+ if (!cmp_inst) {
error.SetErrorToGenericError();
error.SetErrorString(interpreter_internal_error);
return false;
}
- switch (icmp_inst->getPredicate()) {
+ switch (cmp_inst->getPredicate()) {
default: {
LLDB_LOGF(log, "Unsupported ICmp predicate: %s",
PrintValue(&ii).c_str());
@@ -561,11 +587,17 @@
error.SetErrorString(unsupported_opcode_error);
return false;
}
+ case CmpInst::FCMP_OEQ:
case CmpInst::ICMP_EQ:
+ case CmpInst::FCMP_UNE:
case CmpInst::ICMP_NE:
+ case CmpInst::FCMP_OGT:
case CmpInst::ICMP_UGT:
+ case CmpInst::FCMP_OGE:
case CmpInst::ICMP_UGE:
+ case CmpInst::FCMP_OLT:
case CmpInst::ICMP_ULT:
+ case CmpInst::FCMP_OLE:
case CmpInst::ICMP_ULE:
case CmpInst::ICMP_SGT:
case CmpInst::ICMP_SGE:
@@ -595,6 +627,11 @@
case Instruction::Xor:
case Instruction::ZExt:
break;
+ case Instruction::FAdd:
+ case Instruction::FSub:
+ case Instruction::FMul:
+ case Instruction::FDiv:
+ break;
}
for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {
@@ -709,7 +746,11 @@
case Instruction::AShr:
case Instruction::And:
case Instruction::Or:
- case Instruction::Xor: {
+ case Instruction::Xor:
+ case Instruction::FAdd:
+ case Instruction::FSub:
+ case Instruction::FMul:
+ case Instruction::FDiv: {
const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
if (!bin_op) {
@@ -748,12 +789,15 @@
default:
break;
case Instruction::Add:
+ case Instruction::FAdd:
result = L + R;
break;
case Instruction::Mul:
+ case Instruction::FMul:
result = L * R;
break;
case Instruction::Sub:
+ case Instruction::FSub:
result = L - R;
break;
case Instruction::SDiv:
@@ -766,6 +810,9 @@
R.MakeUnsigned();
result = L / R;
break;
+ case Instruction::FDiv:
+ result = L / R;
+ break;
case Instruction::SRem:
L.MakeSigned();
R.MakeSigned();
@@ -1028,8 +1075,9 @@
LLDB_LOGF(log, " Poffset : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+ case Instruction::FCmp:
case Instruction::ICmp: {
- const ICmpInst *icmp_inst = cast<ICmpInst>(inst);
+ const CmpInst *icmp_inst = cast<CmpInst>(inst);
CmpInst::Predicate predicate = icmp_inst->getPredicate();
@@ -1059,9 +1107,11 @@
default:
return false;
case CmpInst::ICMP_EQ:
+ case CmpInst::FCMP_OEQ:
result = (L == R);
break;
case CmpInst::ICMP_NE:
+ case CmpInst::FCMP_UNE:
result = (L != R);
break;
case CmpInst::ICMP_UGT:
@@ -1074,16 +1124,28 @@
R.MakeUnsigned();
result = (L >= R);
break;
+ case CmpInst::FCMP_OGE:
+ result = (L >= R);
+ break;
+ case CmpInst::FCMP_OGT:
+ result = (L > R);
+ break;
case CmpInst::ICMP_ULT:
L.MakeUnsigned();
R.MakeUnsigned();
result = (L < R);
break;
+ case CmpInst::FCMP_OLT:
+ result = (L < R);
+ break;
case CmpInst::ICMP_ULE:
L.MakeUnsigned();
R.MakeUnsigned();
result = (L <= R);
break;
+ case CmpInst::FCMP_OLE:
+ result = (L <= R);
+ break;
case CmpInst::ICMP_SGT:
L.MakeSigned();
R.MakeSigned();
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits