[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
igorkudrin wrote: This caused failures on Windows build bots because `long` is `i32`, not `i64`. I've reverted the patch. I'll fix the test and prepare a new PR. https://github.com/llvm/llvm-project/pull/175292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,101 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f", # sitofp i32 to float
+"$d - $n", # sitofp i32 to double
+"$u + $f", # uitofp i32 to float
+"$u + $d", # uitofp i32 to double
+"(int)$d", # fptosi double to i32
+"(int)$f", # fptosi float to i32
+"(long)$d", # fptosi double to i64
+"(short)$f", # fptosi float to i16
+"(long)$nf", # fptosi float to i64
+"(unsigned short)$f", # fptoui float to i16
+"(unsigned)$d", # fptoui double to i32
+"(unsigned long)$d", # fptoui double to i64
+"(float)$d", # fptrunc double to float
+"(double)$f", # fpext float to double
+"(double)$nf", # fpext float to double
+]
+
+for expression in set_up_expressions:
+self.frame().EvaluateExpression(expression, interp_options)
+
+func_call = "(int)getpid()"
+if lldbplatformutil.getPlatform() == "windows":
+func_call = "(int)GetCurrentProcessId()"
+
+for expression in expressions:
+interp_expression = expression
+# Calling a function forces the expression to be executed with JIT.
+jit_expression = func_call + "; " + expression
+
+interp_result = self.frame().EvaluateExpression(
+interp_expression, interp_options
+)
+jit_result = self.frame().EvaluateExpression(jit_expression,
jit_options)
+
+self.assertEqual(
+interp_result.GetValue(),
+jit_result.GetValue(),
+"Values match for " + expression,
+)
+self.assertEqual(
+interp_result.GetTypeName(),
+jit_result.GetTypeName(),
+"Types match for " + expression,
+)
+
+def test_fpconv_ub(self):
+target = self.dbg.GetDummyTarget()
+
+set_up_expressions = [
+"float $f = 3e9",
+"double $d = 1e20",
+"float $nf = -1.5",
+]
+
+expressions = [
+"(int)$f",
+"(long)$d",
+"(unsigned)$nf",
+]
+
+for expression in set_up_expressions:
+target.EvaluateExpression(expression)
+
+# The IR Interpreter returns an error if a value cannot be converted.
+for expression in expressions:
+result = target.EvaluateExpression(expression)
+self.assertIn(
+"Interpreter couldn't convert a value", str(result.GetError())
+)
Michael137 wrote:
Yea that seems like a reasonable compromise, thanks!
> I think we should report any UB we find.
I'm not so sure. The way i see it, the expression evaluator should just run
whatever C++ code is given to it, with the expectation that the compiler will
diagnose anything wrong with the expression. If the code made it into a
runnable executable, then we should support it. I'm sure that line has already
been blurred with DIL expressions (we do our own type-checking there etc.), but
at least those don't ever get run via the `expr` command. This is not a major
violation of this model (and I might be wrong about this in the first place),
so a clearer error message would suffice.
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
https://github.com/igorkudrin updated
https://github.com/llvm/llvm-project/pull/175292
>From ba9318db283858884e395ec2329ef2f8891370b4 Mon Sep 17 00:00:00 2001
From: Igor Kudrin
Date: Thu, 8 Jan 2026 22:53:38 -0800
Subject: [PATCH 1/7] [lldb] Add FP conversion instructions to IR interpreter
This allows expressions that use these conversions to be executed when
JIT is not available.
---
lldb/source/Expression/IRInterpreter.cpp | 73 +++
.../ir-interpreter/TestIRInterpreter.py | 70 ++
2 files changed, 143 insertions(+)
diff --git a/lldb/source/Expression/IRInterpreter.cpp
b/lldb/source/Expression/IRInterpreter.cpp
index 91404831aeb9b..3c43646f51eff 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -611,6 +611,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module,
llvm::Function &function,
} break;
case Instruction::And:
case Instruction::AShr:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
case Instruction::IntToPtr:
case Instruction::PtrToInt:
case Instruction::Load:
@@ -635,6 +637,18 @@ bool IRInterpreter::CanInterpret(llvm::Module &module,
llvm::Function &function,
case Instruction::FMul:
case Instruction::FDiv:
break;
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+if (!ii.getType()->isFloatTy() && !ii.getType()->isDoubleTy()) {
+ LLDB_LOGF(log, "Unsupported instruction: %s",
+PrintValue(&ii).c_str());
+ error =
+ lldb_private::Status::FromErrorString(unsupported_opcode_error);
+ return false;
+}
+break;
}
for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {
@@ -1256,6 +1270,65 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ S.GetAPFloat().convertToInteger(result, llvm::APFloat::rmTowardZero,
+ &isExact);
+ lldb_private::Scalar R(result);
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
+case Instruction::UIToFP:
+case Instruction::SIToFP:
+case Instruction::FPTrunc:
+case Instruction::FPExt: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+ lldb_private::Scalar R;
+
+ Type *result_type = inst->getType();
+ assert(
+ (result_type->isFloatTy() || result_type->isDoubleTy()) &&
+ "Unsupported result type; CanInterpret() should have checked that");
+ if (result_type->isFloatTy())
+R = S.Float();
+ else
+R = S.Double();
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
case Instruction::Load: {
const LoadInst *load_inst = cast(inst);
diff --git
a/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
b/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
index 23188ef898d56..26be9ab952db7 100644
--- a/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
+++ b/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
@@ -172,3 +172,73 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_v
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
https://github.com/Michael137 approved this pull request. LGTM, with just the question about UB conversions left https://github.com/llvm/llvm-project/pull/175292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,101 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f", # sitofp i32 to float
+"$d - $n", # sitofp i32 to double
+"$u + $f", # uitofp i32 to float
+"$u + $d", # uitofp i32 to double
+"(int)$d", # fptosi double to i32
+"(int)$f", # fptosi float to i32
+"(long)$d", # fptosi double to i64
+"(short)$f", # fptosi float to i16
+"(long)$nf", # fptosi float to i64
+"(unsigned short)$f", # fptoui float to i16
+"(unsigned)$d", # fptoui double to i32
+"(unsigned long)$d", # fptoui double to i64
+"(float)$d", # fptrunc double to float
+"(double)$f", # fpext float to double
+"(double)$nf", # fpext float to double
+]
+
+for expression in set_up_expressions:
+self.frame().EvaluateExpression(expression, interp_options)
+
+func_call = "(int)getpid()"
+if lldbplatformutil.getPlatform() == "windows":
+func_call = "(int)GetCurrentProcessId()"
+
+for expression in expressions:
+interp_expression = expression
+# Calling a function forces the expression to be executed with JIT.
+jit_expression = func_call + "; " + expression
+
+interp_result = self.frame().EvaluateExpression(
+interp_expression, interp_options
+)
+jit_result = self.frame().EvaluateExpression(jit_expression,
jit_options)
+
+self.assertEqual(
+interp_result.GetValue(),
+jit_result.GetValue(),
+"Values match for " + expression,
+)
+self.assertEqual(
+interp_result.GetTypeName(),
+jit_result.GetTypeName(),
+"Types match for " + expression,
+)
+
+def test_fpconv_ub(self):
+target = self.dbg.GetDummyTarget()
+
+set_up_expressions = [
+"float $f = 3e9",
+"double $d = 1e20",
+"float $nf = -1.5",
+]
+
+expressions = [
+"(int)$f",
+"(long)$d",
+"(unsigned)$nf",
+]
+
+for expression in set_up_expressions:
+target.EvaluateExpression(expression)
+
+# The IR Interpreter returns an error if a value cannot be converted.
+for expression in expressions:
+result = target.EvaluateExpression(expression)
+self.assertIn(
+"Interpreter couldn't convert a value", str(result.GetError())
+)
Michael137 wrote:
Don't feel too strongly about this but I'm a bit wary of making the expression
evaluation more restrictive. What if a user has this in their code and wants to
run it as an expression? If the compiler didn't reject it and codegenned
something for it, should the expression evaluator really refuse to run the
expression because our IRInterpreter decided it wouldn't? Is there precedent
for that? I'm not fussed about checking that they evaluate to something
consistent/deterministic/sensible. Just whether we run the code in the first
place.
But there's probably not good way to fall back to JITted expressions? Or still
somehow try and perform the conversion?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
https://github.com/igorkudrin edited https://github.com/llvm/llvm-project/pull/175292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
https://github.com/igorkudrin updated
https://github.com/llvm/llvm-project/pull/175292
>From ba9318db283858884e395ec2329ef2f8891370b4 Mon Sep 17 00:00:00 2001
From: Igor Kudrin
Date: Thu, 8 Jan 2026 22:53:38 -0800
Subject: [PATCH 1/5] [lldb] Add FP conversion instructions to IR interpreter
This allows expressions that use these conversions to be executed when
JIT is not available.
---
lldb/source/Expression/IRInterpreter.cpp | 73 +++
.../ir-interpreter/TestIRInterpreter.py | 70 ++
2 files changed, 143 insertions(+)
diff --git a/lldb/source/Expression/IRInterpreter.cpp
b/lldb/source/Expression/IRInterpreter.cpp
index 91404831aeb9b..3c43646f51eff 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -611,6 +611,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module,
llvm::Function &function,
} break;
case Instruction::And:
case Instruction::AShr:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
case Instruction::IntToPtr:
case Instruction::PtrToInt:
case Instruction::Load:
@@ -635,6 +637,18 @@ bool IRInterpreter::CanInterpret(llvm::Module &module,
llvm::Function &function,
case Instruction::FMul:
case Instruction::FDiv:
break;
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+if (!ii.getType()->isFloatTy() && !ii.getType()->isDoubleTy()) {
+ LLDB_LOGF(log, "Unsupported instruction: %s",
+PrintValue(&ii).c_str());
+ error =
+ lldb_private::Status::FromErrorString(unsupported_opcode_error);
+ return false;
+}
+break;
}
for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {
@@ -1256,6 +1270,65 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ S.GetAPFloat().convertToInteger(result, llvm::APFloat::rmTowardZero,
+ &isExact);
+ lldb_private::Scalar R(result);
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
+case Instruction::UIToFP:
+case Instruction::SIToFP:
+case Instruction::FPTrunc:
+case Instruction::FPExt: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+ lldb_private::Scalar R;
+
+ Type *result_type = inst->getType();
+ assert(
+ (result_type->isFloatTy() || result_type->isDoubleTy()) &&
+ "Unsupported result type; CanInterpret() should have checked that");
+ if (result_type->isFloatTy())
+R = S.Float();
+ else
+R = S.Double();
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
case Instruction::Load: {
const LoadInst *load_inst = cast(inst);
diff --git
a/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
b/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
index 23188ef898d56..26be9ab952db7 100644
--- a/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
+++ b/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
@@ -172,3 +172,73 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_v
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1279,73 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ llvm::APFloatBase::opStatus status = S.GetAPFloat().convertToInteger(
+ result, llvm::APFloat::rmTowardZero, &isExact);
+ // Casting floating point values that are out of bounds of the target
type
+ // is undefined behaviour.
+ if (status & llvm::APFloatBase::opInvalidOp) {
+LLDB_LOGF(log, "Couldn't convert %s to %s", PrintScalar(S).c_str(),
+ PrintType(inst->getType()).c_str());
Michael137 wrote:
Can we use `LLDB_LOG` for the logs? And use the LLVM format specifiers?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,101 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f", # sitofp i32 to float
+"$d - $n", # sitofp i32 to double
+"$u + $f", # uitofp i32 to float
+"$u + $d", # uitofp i32 to double
+"(int)$d", # fptosi double to i32
+"(int)$f", # fptosi float to i32
+"(long)$d", # fptosi double to i64
+"(short)$f", # fptosi float to i16
+"(long)$nf", # fptosi float to i64
+"(unsigned short)$f", # fptoui float to i16
+"(unsigned)$d", # fptoui double to i32
+"(unsigned long)$d", # fptoui double to i64
+"(float)$d", # fptrunc double to float
+"(double)$f", # fpext float to double
+"(double)$nf", # fpext float to double
+]
+
+for expression in set_up_expressions:
+self.frame().EvaluateExpression(expression, interp_options)
+
+func_call = "(int)getpid()"
+if lldbplatformutil.getPlatform() == "windows":
+func_call = "(int)GetCurrentProcessId()"
+
+for expression in expressions:
+interp_expression = expression
+# Calling a function forces the expression to be executed with JIT.
+jit_expression = func_call + "; " + expression
+
+interp_result = self.frame().EvaluateExpression(
+interp_expression, interp_options
+)
+jit_result = self.frame().EvaluateExpression(jit_expression,
jit_options)
+
+self.assertEqual(
+interp_result.GetValue(),
+jit_result.GetValue(),
+"Values match for " + expression,
+)
+self.assertEqual(
+interp_result.GetTypeName(),
+jit_result.GetTypeName(),
+"Types match for " + expression,
+)
+
+def test_fpconv_ub(self):
+target = self.dbg.GetDummyTarget()
+
+set_up_expressions = [
+"float $f = 3e9",
+"double $d = 1e20",
+"float $nf = -1.5",
+]
+
+expressions = [
+"(int)$f",
+"(long)$d",
+"(unsigned)$nf",
+]
+
+for expression in set_up_expressions:
+target.EvaluateExpression(expression)
+
+# The IR Interpreter returns an error if a value cannot be converted.
+for expression in expressions:
+result = target.EvaluateExpression(expression)
+self.assertIn(
+"Interpreter couldn't convert a value", str(result.GetError())
+)
Michael137 wrote:
Would this pass with jitted expressions?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1279,73 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ llvm::APFloatBase::opStatus status = S.GetAPFloat().convertToInteger(
+ result, llvm::APFloat::rmTowardZero, &isExact);
+ // Casting floating point values that are out of bounds of the target
type
+ // is undefined behaviour.
+ if (status & llvm::APFloatBase::opInvalidOp) {
Michael137 wrote:
Checking for `opInvalidOp` seems to be pretty inconsistent across LLVM and
Clang. From a cursory grep, some use it as a flag and compare it with equality.
Checking that the status `!= llvm::APFloatBase::opOK` seems like the most
accurate way of determining whether there was *any* error right?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1279,73 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
igorkudrin wrote:
Instructions validate that they are created with a non-null type, no?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,69 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f",
+"$d - $n",
+"$u + $f",
+"$u + $d",
+"(int)$d",
+"(int)$f",
+"(long)$d",
+"(short)$f",
+"(long)$nf",
+"(unsigned short)$f",
+"(unsigned)$d",
+"(unsigned long)$d",
+"(float)$d",
+"(double)$f",
+"(double)$nf",
+]
+
+for expression in set_up_expressions:
+self.frame().EvaluateExpression(expression, interp_options)
+
+func_call = "(int)getpid()"
+if lldbplatformutil.getPlatform() == "windows":
+func_call = "(int)GetCurrentProcessId()"
Michael137 wrote:
Lets add a comment to that effect
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/175292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,69 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f",
+"$d - $n",
+"$u + $f",
+"$u + $d",
+"(int)$d",
+"(int)$f",
+"(long)$d",
+"(short)$f",
+"(long)$nf",
+"(unsigned short)$f",
+"(unsigned)$d",
+"(unsigned long)$d",
+"(float)$d",
+"(double)$f",
+"(double)$nf",
+]
Michael137 wrote:
Even when they live in variables in the source?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1279,73 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ llvm::APFloatBase::opStatus status = S.GetAPFloat().convertToInteger(
+ result, llvm::APFloat::rmTowardZero, &isExact);
+ // Casting floating point values that are out of bounds of the target
type
+ // is undefined behaviour.
+ if (status & llvm::APFloatBase::opInvalidOp) {
Michael137 wrote:
`status == llvm::APFloatBase::opOK` instead?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1279,73 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
Michael137 wrote:
should we `assert`/check `inst->getType()` too before dereferencing?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1270,65 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ S.GetAPFloat().convertToInteger(result, llvm::APFloat::rmTowardZero,
+ &isExact);
+ lldb_private::Scalar R(result);
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
+case Instruction::UIToFP:
+case Instruction::SIToFP:
+case Instruction::FPTrunc:
Michael137 wrote:
Ah right i was looking at the intrinsic
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
igorkudrin wrote: Ping.. https://github.com/llvm/llvm-project/pull/175292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
https://github.com/igorkudrin edited https://github.com/llvm/llvm-project/pull/175292 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1270,65 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ S.GetAPFloat().convertToInteger(result, llvm::APFloat::rmTowardZero,
+ &isExact);
+ lldb_private::Scalar R(result);
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
+case Instruction::UIToFP:
+case Instruction::SIToFP:
+case Instruction::FPTrunc:
igorkudrin wrote:
If I understand correctly, the
[FPTrunc](https://llvm.org/docs/LangRef.html#id2226) instruction does not have
a rounding mode argument, unlike the
[llvm.fptrunc.round](https://llvm.org/docs/LangRef.html#id2442) intrinsic.
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
https://github.com/igorkudrin updated
https://github.com/llvm/llvm-project/pull/175292
>From ba9318db283858884e395ec2329ef2f8891370b4 Mon Sep 17 00:00:00 2001
From: Igor Kudrin
Date: Thu, 8 Jan 2026 22:53:38 -0800
Subject: [PATCH 1/4] [lldb] Add FP conversion instructions to IR interpreter
This allows expressions that use these conversions to be executed when
JIT is not available.
---
lldb/source/Expression/IRInterpreter.cpp | 73 +++
.../ir-interpreter/TestIRInterpreter.py | 70 ++
2 files changed, 143 insertions(+)
diff --git a/lldb/source/Expression/IRInterpreter.cpp
b/lldb/source/Expression/IRInterpreter.cpp
index 91404831aeb9b..3c43646f51eff 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -611,6 +611,8 @@ bool IRInterpreter::CanInterpret(llvm::Module &module,
llvm::Function &function,
} break;
case Instruction::And:
case Instruction::AShr:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
case Instruction::IntToPtr:
case Instruction::PtrToInt:
case Instruction::Load:
@@ -635,6 +637,18 @@ bool IRInterpreter::CanInterpret(llvm::Module &module,
llvm::Function &function,
case Instruction::FMul:
case Instruction::FDiv:
break;
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+if (!ii.getType()->isFloatTy() && !ii.getType()->isDoubleTy()) {
+ LLDB_LOGF(log, "Unsupported instruction: %s",
+PrintValue(&ii).c_str());
+ error =
+ lldb_private::Status::FromErrorString(unsupported_opcode_error);
+ return false;
+}
+break;
}
for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {
@@ -1256,6 +1270,65 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ S.GetAPFloat().convertToInteger(result, llvm::APFloat::rmTowardZero,
+ &isExact);
+ lldb_private::Scalar R(result);
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
+case Instruction::UIToFP:
+case Instruction::SIToFP:
+case Instruction::FPTrunc:
+case Instruction::FPExt: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+ lldb_private::Scalar R;
+
+ Type *result_type = inst->getType();
+ assert(
+ (result_type->isFloatTy() || result_type->isDoubleTy()) &&
+ "Unsupported result type; CanInterpret() should have checked that");
+ if (result_type->isFloatTy())
+R = S.Float();
+ else
+R = S.Double();
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
case Instruction::Load: {
const LoadInst *load_inst = cast(inst);
diff --git
a/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
b/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
index 23188ef898d56..26be9ab952db7 100644
--- a/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
+++ b/lldb/test/API/commands/expression/ir-interpreter/TestIRInterpreter.py
@@ -172,3 +172,73 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_v
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,69 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f",
+"$d - $n",
+"$u + $f",
+"$u + $d",
+"(int)$d",
+"(int)$f",
+"(long)$d",
+"(short)$f",
+"(long)$nf",
+"(unsigned short)$f",
+"(unsigned)$d",
+"(unsigned long)$d",
+"(float)$d",
+"(double)$f",
+"(double)$nf",
+]
igorkudrin wrote:
Expressions like these can and will be fully optimized by the compiler; the
prepared module will not contain instructions that we want to check in this
test.
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1270,65 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ S.GetAPFloat().convertToInteger(result, llvm::APFloat::rmTowardZero,
+ &isExact);
Michael137 wrote:
Should we check the returned `opStatus == opOK`?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,69 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f",
+"$d - $n",
+"$u + $f",
+"$u + $d",
+"(int)$d",
+"(int)$f",
+"(long)$d",
+"(short)$f",
+"(long)$nf",
+"(unsigned short)$f",
+"(unsigned)$d",
+"(unsigned long)$d",
+"(float)$d",
+"(double)$f",
+"(double)$nf",
+]
Michael137 wrote:
Any reason to split these up instead of running the expressions like:
```
EvaluateExpression("1 + 1.0")
EvaluateExpression("(long)1.0")
...
```
?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -172,3 +172,69 @@ def test_type_conversions(self):
self.assertEqual(short_val.GetValueAsSigned(), -1)
long_val = target.EvaluateExpression("(long) " + short_val.GetName())
self.assertEqual(long_val.GetValueAsSigned(), -1)
+
+def test_fpconv(self):
+self.build_and_run()
+
+interp_options = lldb.SBExpressionOptions()
+interp_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+interp_options.SetAllowJIT(False)
+
+jit_options = lldb.SBExpressionOptions()
+jit_options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+jit_options.SetAllowJIT(True)
+
+set_up_expressions = [
+"int $i = 3",
+"int $n = -3",
+"unsigned $u = 5",
+"long $l = -7",
+"float $f = 9.0625",
+"double $d = 13.75",
+"float $nf = -11.25",
+]
+
+expressions = [
+"$i + $f",
+"$d - $n",
+"$u + $f",
+"$u + $d",
+"(int)$d",
+"(int)$f",
+"(long)$d",
+"(short)$f",
+"(long)$nf",
+"(unsigned short)$f",
+"(unsigned)$d",
+"(unsigned long)$d",
+"(float)$d",
+"(double)$f",
+"(double)$nf",
+]
+
+for expression in set_up_expressions:
+self.frame().EvaluateExpression(expression, interp_options)
+
+func_call = "(int)getpid()"
+if lldbplatformutil.getPlatform() == "windows":
+func_call = "(int)GetCurrentProcessId()"
Michael137 wrote:
What is this for?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add FP conversion instructions to IR interpreter (PR #175292)
@@ -1256,6 +1270,65 @@ bool IRInterpreter::Interpret(llvm::Module &module,
llvm::Function &function,
LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
}
} break;
+case Instruction::FPToUI:
+case Instruction::FPToSI: {
+ Value *src_operand = inst->getOperand(0);
+
+ lldb_private::Scalar S;
+ if (!frame.EvaluateValue(S, src_operand, module)) {
+LLDB_LOGF(log, "Couldn't evaluate %s",
PrintValue(src_operand).c_str());
+error = lldb_private::Status::FromErrorString(bad_value_error);
+return false;
+ }
+
+ assert(inst->getType()->isIntegerTy() && "Unexpected target type");
+ llvm::APSInt result(inst->getType()->getIntegerBitWidth(),
+ /*isUnsigned=*/inst->getOpcode() ==
+ Instruction::FPToUI);
+ assert(S.GetType() == lldb_private::Scalar::e_float &&
+ "Unexpected source type");
+ bool isExact;
+ S.GetAPFloat().convertToInteger(result, llvm::APFloat::rmTowardZero,
+ &isExact);
+ lldb_private::Scalar R(result);
+
+ frame.AssignValue(inst, R, module);
+ if (log) {
+LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());
+LLDB_LOGF(log, " Src : %s",
frame.SummarizeValue(src_operand).c_str());
+LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());
+ }
+} break;
+case Instruction::UIToFP:
+case Instruction::SIToFP:
+case Instruction::FPTrunc:
Michael137 wrote:
`FPTrunc` takes a rounding mode as an argument. Are we intentionally ignoring
it?
https://github.com/llvm/llvm-project/pull/175292
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
