diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -413,9 +413,11 @@ uint32_t GetPoundLineLine() const { return m_pound_line_line; } - void SetResultIsInternal(bool b) { m_result_is_internal = b; } + void SetSuppressPersistentResult(bool b) { m_suppress_persistent_result = b; } - bool GetResultIsInternal() const { return m_result_is_internal; } + bool GetSuppressPersistentResult() const { + return m_suppress_persistent_result; + } void SetAutoApplyFixIts(bool b) { m_auto_apply_fixits = b; } @@ -446,7 +448,7 @@ bool m_repl = false; bool m_generate_debug_info = false; bool m_ansi_color_errors = false; - bool m_result_is_internal = false; + bool m_suppress_persistent_result = false; bool m_auto_apply_fixits = true; uint64_t m_retries_with_fixits = 1; /// True if the executed code should be treated as utility code that is only diff --git a/lldb/source/API/SBExpressionOptions.cpp b/lldb/source/API/SBExpressionOptions.cpp --- a/lldb/source/API/SBExpressionOptions.cpp +++ b/lldb/source/API/SBExpressionOptions.cpp @@ -178,13 +178,13 @@ bool SBExpressionOptions::GetSuppressPersistentResult() { LLDB_INSTRUMENT_VA(this); - return m_opaque_up->GetResultIsInternal(); + return m_opaque_up->GetSuppressPersistentResult(); } void SBExpressionOptions::SetSuppressPersistentResult(bool b) { LLDB_INSTRUMENT_VA(this, b); - return m_opaque_up->SetResultIsInternal(b); + return m_opaque_up->SetSuppressPersistentResult(b); } const char *SBExpressionOptions::GetPrefix() const { diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp --- a/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -290,7 +290,7 @@ options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); options.SetTryAllThreads(true); - options.SetResultIsInternal( + options.SetSuppressPersistentResult( true); // Don't generate a user variable for condition expressions. Status expr_error; diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" +#include "lldb/lldb-private-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -346,6 +347,9 @@ CommandObjectExpression::GetEvalOptions(const Target &target) { EvaluateExpressionOptions options; options.SetCoerceToId(m_varobj_options.use_objc); + if (m_command_options.m_verbosity == + eLanguageRuntimeDescriptionDisplayVerbosityCompact) + options.SetSuppressPersistentResult(m_varobj_options.use_objc); options.SetUnwindOnError(m_command_options.unwind_on_error); options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints); options.SetKeepInMemory(true); diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp --- a/lldb/source/Expression/UserExpression.cpp +++ b/lldb/source/Expression/UserExpression.cpp @@ -424,7 +424,7 @@ lldb::ExpressionResults expr_result = DoExecute( diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var); Target *target = exe_ctx.GetTargetPtr(); - if (options.GetResultIsInternal() && result_var && target) { + if (options.GetSuppressPersistentResult() && result_var && target) { if (auto *persistent_state = target->GetPersistentExpressionStateForLanguage(m_language)) persistent_state->RemovePersistentVariable(result_var); diff --git a/lldb/test/API/commands/expression/po_persistent_result/Makefile b/lldb/test/API/commands/expression/po_persistent_result/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/commands/expression/po_persistent_result/Makefile @@ -0,0 +1,3 @@ +OBJC_SOURCES := main.m + +include Makefile.rules diff --git a/lldb/test/API/commands/expression/po_persistent_result/TestPoPersistentResult.py b/lldb/test/API/commands/expression/po_persistent_result/TestPoPersistentResult.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/commands/expression/po_persistent_result/TestPoPersistentResult.py @@ -0,0 +1,35 @@ +""" +Test behavior of `po` and persistent results. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from lldbsuite.test import lldbutil + + +class TestCase(TestBase): + def setUp(self): + TestBase.setUp(self) + self.build() + lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m")) + + @skipUnlessDarwin + def test_po_does_not_print_persistent_result(self): + """Test `po` doesn't advertise a persistent result variable.""" + self.expect("po obj", matching=False, substrs=["$0 = "]) + + @skipUnlessDarwin + def test_po_does_not_keep_persistent_result(self): + """Test `po` doesn't leak a persistent result variable.""" + self.expect("po obj") + # Verify `po` used a temporary persistent result. In other words, there + # should be no $0 at this point. + self.expect("expression $0", error=True) + self.expect("expression obj", substrs=["$0 = "]) + + @skipUnlessDarwin + def test_expression_description_verbosity(self): + """Test printing object description _and_ opt-in to persistent results.""" + self.expect("expression -O -vfull -- obj", substrs=["$0 = "]) + self.expect("expression $0", substrs=["$0 = "]) diff --git a/lldb/test/API/commands/expression/po_persistent_result/main.m b/lldb/test/API/commands/expression/po_persistent_result/main.m new file mode 100644 --- /dev/null +++ b/lldb/test/API/commands/expression/po_persistent_result/main.m @@ -0,0 +1,6 @@ +#import + +int main() { + NSObject *obj = [NSObject new]; + return 0; // break here +} diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -274,6 +274,10 @@ def : Pat<(any_fma (fneg FPR64:$rs1), FPR64:$rs2, FPR64:$rs3), (FNMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; +//fnmsub: - (rs1 * rs2) + rs3 +def : Pat<(fsub FPR64:$rs3 , (fmul FPR64:$rs1, FPR64:$rs2)), + (FNMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + // fnmadd: -rs1 * rs2 - rs3 def : Pat<(any_fma (fneg FPR64:$rs1), FPR64:$rs2, (fneg FPR64:$rs3)), (FNMADD_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; @@ -282,6 +286,10 @@ def : Pat<(fneg (any_fma_nsz FPR64:$rs1, FPR64:$rs2, FPR64:$rs3)), (FNMADD_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; +// fnmadd: - (rs1 * rs2) - rs3 +def : Pat<(fsub (fmul FPR64:$rs2,(fneg FPR64:$rs1)) , FPR64:$rs3), + (FNMADD_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + // The ratified 20191213 ISA spec defines fmin and fmax in a way that matches // LLVM's fminnum and fmaxnum. // . diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -483,6 +483,10 @@ def : Pat<(any_fma (fneg FPR32:$rs1), FPR32:$rs2, FPR32:$rs3), (FNMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; +// fnmsub: -(rs1 * rs2) + rs3 +def : Pat<(fsub FPR32:$rs3,(fmul FPR32:$rs1, FPR32:$rs2)), + (FNMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + // fnmadd: -rs1 * rs2 - rs3 def : Pat<(any_fma (fneg FPR32:$rs1), FPR32:$rs2, (fneg FPR32:$rs3)), (FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; @@ -491,6 +495,10 @@ def : Pat<(fneg (any_fma_nsz FPR32:$rs1, FPR32:$rs2, FPR32:$rs3)), (FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; +// fnmadd: - (rs1 * rs2) - rs3 +def : Pat<(fsub (fmul FPR32:$rs2,(fneg FPR32:$rs1)) , FPR32:$rs3), + (FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + // The ratified 20191213 ISA spec defines fmin and fmax in a way that matches // LLVM's fminnum and fmaxnum // . diff --git a/llvm/test/CodeGen/RISCV/double-arith.ll b/llvm/test/CodeGen/RISCV/double-arith.ll --- a/llvm/test/CodeGen/RISCV/double-arith.ll +++ b/llvm/test/CodeGen/RISCV/double-arith.ll @@ -693,6 +693,26 @@ ret double %neg } +define double @fnmadd_d_4(double %a, double %b, double %c) nounwind { +; RV32IFD-LABEL: fnmadd_d_4: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: fcvt.d.w ft0, zero +; RV32IFD-NEXT: fadd.d ft0, fa0, ft0 +; RV32IFD-NEXT: fnmadd.d fa0, ft0, fa1, fa2 +; RV32IFD-NEXT: ret +; +; RV64IFD-LABEL: fnmadd_d_4: +; RV64IFD: # %bb.0: +; RV64IFD-NEXT: fmv.d.x ft0, zero +; RV64IFD-NEXT: fadd.d ft0, fa0, ft0 +; RV64IFD-NEXT: fnmadd.d fa0, ft0, fa1, fa2 +; RV64IFD-NEXT: ret + %a_ = fadd double 0.0, %a + %nega = fsub double -0.0, %a_ + %fmul = fmul double %nega, %b + %sub = fsub double %fmul, %c + ret double %sub +} define double @fnmadd_nsz(double %a, double %b, double %c) nounwind { ; CHECKIFD-LABEL: fnmadd_nsz: @@ -875,6 +895,16 @@ ret double %1 } +define double @fnmsub_d_3(double %a, double %b, double %c) nounwind { +; CHECKIFD-LABEL: fnmsub_d_3: +; CHECKIFD: # %bb.0: +; CHECKIFD-NEXT: fnmsub.d fa0, fa0, fa1, fa2 +; CHECKIFD-NEXT: ret + %1 = fmul double %a, %b + %add = fsub double %c, %1 + ret double %add +} + define double @fmadd_d_contract(double %a, double %b, double %c) nounwind { ; CHECKIFD-LABEL: fmadd_d_contract: ; CHECKIFD: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/float-arith.ll b/llvm/test/CodeGen/RISCV/float-arith.ll --- a/llvm/test/CodeGen/RISCV/float-arith.ll +++ b/llvm/test/CodeGen/RISCV/float-arith.ll @@ -643,6 +643,27 @@ ret float %neg } +define float @fnmadd_s_4(float %a, float %b, float %c) nounwind { +; RV32IFD-LABEL: fnmadd_s_4: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: fcvt.s.w ft0, zero +; RV32IFD-NEXT: fadd.s ft0, fa0, ft0 +; RV32IFD-NEXT: fnmadd.s fa0, ft0, fa1, fa2 +; RV32IFD-NEXT: ret +; +; RV64IFD-LABEL: fnmadd_s_4: +; RV64IFD: # %bb.0: +; RV64IFD-NEXT: fmv.s.x ft0, zero +; RV64IFD-NEXT: fadd.s ft0, fa0, ft0 +; RV64IFD-NEXT: fnmadd.s fa0, ft0, fa1, fa2 +; RV64IFD-NEXT: ret + %a_ = fadd float 0.0, %a + %nega = fsub float -0.0, %a_ + %fmul = fmul float %nega, %b + %sub = fsub float %fmul, %c + ret float %sub +} + define float @fnmadd_nsz(float %a, float %b, float %c) nounwind { ; RV32IF-LABEL: fnmadd_nsz: ; RV32IF: # %bb.0: @@ -797,6 +818,16 @@ ret float %1 } +define float @fnmsub_s_3(float %a, float %b, float %c) nounwind { +; CHECKIFD-LABEL: fnmsub_s_3: +; CHECKIFD: # %bb.0: +; CHECKIFD-NEXT: fnmsub.s fa0, fa0, fa1, fa2 +; CHECKIFD-NEXT: ret + %1 = fmul float %a, %b + %add = fsub float %c, %1 + ret float %add +} + define float @fmadd_s_contract(float %a, float %b, float %c) nounwind { ; CHECKIF-LABEL: fmadd_s_contract: ; CHECKIF: # %bb.0: