21 changes: 6 additions & 15 deletions lldb/include/lldb/Target/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -857,10 +857,10 @@ class Process : public std::enable_shared_from_this<Process>,
/// \see Thread:Resume()
/// \see Thread:Step()
/// \see Thread:Suspend()
Status Resume(lldb::RunDirection direction = lldb::eRunForward);
Status Resume();

/// Resume a process, and wait for it to stop.
Status ResumeSynchronous(Stream *stream, lldb::RunDirection direction = lldb::eRunForward);
Status ResumeSynchronous(Stream *stream);

/// Halts a running process.
///
Expand Down Expand Up @@ -1104,14 +1104,9 @@ class Process : public std::enable_shared_from_this<Process>,
/// \see Thread:Resume()
/// \see Thread:Step()
/// \see Thread:Suspend()
virtual Status DoResume(lldb::RunDirection direction) {
if (direction == lldb::RunDirection::eRunForward) {
return Status::FromErrorStringWithFormatv(
"error: {0} does not support resuming processes", GetPluginName());
} else {
return Status::FromErrorStringWithFormatv(
"error: {0} does not support reverse execution of processes", GetPluginName());
}
virtual Status DoResume() {
return Status::FromErrorStringWithFormatv(
"error: {0} does not support resuming processes", GetPluginName());
}

/// Called after resuming a process.
Expand Down Expand Up @@ -2337,8 +2332,6 @@ class Process : public std::enable_shared_from_this<Process>,

bool IsRunning() const;

lldb::RunDirection GetLastRunDirection() { return m_last_run_direction; }

DynamicCheckerFunctions *GetDynamicCheckers() {
return m_dynamic_checkers_up.get();
}
Expand Down Expand Up @@ -2858,7 +2851,7 @@ void PruneThreadPlans();
///
/// \return
/// An Status object describing the success or failure of the resume.
Status PrivateResume(lldb::RunDirection direction = lldb::eRunForward);
Status PrivateResume();

// Called internally
void CompleteAttach();
Expand Down Expand Up @@ -3134,8 +3127,6 @@ void PruneThreadPlans();
// m_currently_handling_do_on_removals are true,
// Resume will only request a resume, using this
// flag to check.
// The direction of execution from the last time this process was resumed.
lldb::RunDirection m_last_run_direction;

lldb::tid_t m_interrupt_tid; /// The tid of the thread that issued the async
/// interrupt, used by thread plan timeout. It
Expand Down
6 changes: 0 additions & 6 deletions lldb/include/lldb/Target/StopInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,6 @@ class StopInfo : public std::enable_shared_from_this<StopInfo> {
static lldb::StopInfoSP
CreateStopReasonProcessorTrace(Thread &thread, const char *description);

// This creates a StopInfo indicating that execution stopped because
// it was replaying some recorded execution history, and execution reached
// the end of that recorded history.
static lldb::StopInfoSP
CreateStopReasonHistoryBoundary(Thread &thread, const char *description);

static lldb::StopInfoSP CreateStopReasonFork(Thread &thread,
lldb::pid_t child_pid,
lldb::tid_t child_tid);
Expand Down
6 changes: 0 additions & 6 deletions lldb/include/lldb/lldb-enumerations.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,6 @@ FLAGS_ENUM(LaunchFlags){
/// Thread Run Modes.
enum RunMode { eOnlyThisThread, eAllThreads, eOnlyDuringStepping };

/// Execution directions
enum RunDirection { eRunForward, eRunReverse };

/// Byte ordering definitions.
enum ByteOrder {
eByteOrderInvalid = 0,
Expand Down Expand Up @@ -257,9 +254,6 @@ enum StopReason {
eStopReasonVFork,
eStopReasonVForkDone,
eStopReasonInterrupt, ///< Thread requested interrupt
// Indicates that execution stopped because the debugger backend relies
// on recorded data and we reached the end of that data.
eStopReasonHistoryBoundary,
};

/// Command Return Status Types.
Expand Down
5 changes: 2 additions & 3 deletions lldb/packages/Python/lldbsuite/test/gdbclientutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,8 @@ def start(self):
self._thread.start()

def stop(self):
if self._thread is not None:
self._thread.join()
self._thread = None
self._thread.join()
self._thread = None

def get_connect_address(self):
return self._socket.get_connect_address()
Expand Down
175 changes: 0 additions & 175 deletions lldb/packages/Python/lldbsuite/test/lldbgdbproxy.py

This file was deleted.

418 changes: 0 additions & 418 deletions lldb/packages/Python/lldbsuite/test/lldbreverse.py

This file was deleted.

2 changes: 0 additions & 2 deletions lldb/packages/Python/lldbsuite/test/lldbtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,6 @@

STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"

STOPPED_DUE_TO_HISTORY_BOUNDARY = "Process should be stopped due to history boundary"

DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"

VALID_BREAKPOINT = "Got a valid breakpoint"
Expand Down
8 changes: 2 additions & 6 deletions lldb/source/API/SBProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,10 +564,6 @@ uint32_t SBProcess::GetAddressByteSize() const {
}

SBError SBProcess::Continue() {
return Continue(RunDirection::eRunForward);
}

SBError SBProcess::Continue(RunDirection direction) {
LLDB_INSTRUMENT_VA(this);

SBError sb_error;
Expand All @@ -578,9 +574,9 @@ SBError SBProcess::Continue(RunDirection direction) {
process_sp->GetTarget().GetAPIMutex());

if (process_sp->GetTarget().GetDebugger().GetAsyncExecution())
sb_error.ref() = process_sp->Resume(direction);
sb_error.ref() = process_sp->Resume();
else
sb_error.ref() = process_sp->ResumeSynchronous(nullptr, direction);
sb_error.ref() = process_sp->ResumeSynchronous(nullptr);
} else
sb_error = Status::FromErrorString("SBProcess is invalid");

Expand Down
2 changes: 0 additions & 2 deletions lldb/source/API/SBThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ size_t SBThread::GetStopReasonDataCount() {
case eStopReasonInstrumentation:
case eStopReasonProcessorTrace:
case eStopReasonVForkDone:
case eStopReasonHistoryBoundary:
// There is no data for these stop reasons.
return 0;

Expand Down Expand Up @@ -234,7 +233,6 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
case eStopReasonInstrumentation:
case eStopReasonProcessorTrace:
case eStopReasonVForkDone:
case eStopReasonHistoryBoundary:
// There is no data for these stop reasons.
return 0;

Expand Down
7 changes: 5 additions & 2 deletions lldb/source/Core/DynamicLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ ModuleSP DynamicLoader::GetTargetExecutable() {
ModuleSpec module_spec(executable->GetFileSpec(),
executable->GetArchitecture());
auto module_sp = std::make_shared<Module>(module_spec);

// If we're a coredump and we already have a main executable, we don't
// need to reload the module list that target already has
if (!m_process->IsLiveDebugSession()) {
return executable;
}
// Check if the executable has changed and set it to the target
// executable if they differ.
if (module_sp && module_sp->GetUUID().IsValid() &&
Expand Down Expand Up @@ -369,4 +373,3 @@ void DynamicLoader::LoadOperatingSystemPlugin(bool flush)
if (m_process)
m_process->LoadOperatingSystemPlugin(flush);
}

3 changes: 1 addition & 2 deletions lldb/source/Interpreter/CommandInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2553,8 +2553,7 @@ bool CommandInterpreter::DidProcessStopAbnormally() const {
const StopReason reason = stop_info->GetStopReason();
if (reason == eStopReasonException ||
reason == eStopReasonInstrumentation ||
reason == eStopReasonProcessorTrace || reason == eStopReasonInterrupt ||
reason == eStopReasonHistoryBoundary)
reason == eStopReasonProcessorTrace || reason == eStopReasonInterrupt)
return true;

if (reason == eStopReasonSignal) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
Expand Down Expand Up @@ -866,3 +867,82 @@ bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
bool DynamicLoaderPOSIXDYLD::IsCoreFile() const {
return !m_process->IsLiveDebugSession();
}

// For our ELF/POSIX builds save off the fs_base/gs_base regions
static void AddThreadLocalMemoryRegions(Process &process, ThreadSP &thread_sp,
std::vector<MemoryRegionInfo> &ranges) {
lldb::RegisterContextSP reg_ctx = thread_sp->GetRegisterContext();
if (!reg_ctx)
return;

const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
lldb::RegisterKind::eRegisterKindGeneric, LLDB_REGNUM_GENERIC_TP);
if (!reg_info)
return;

lldb_private::RegisterValue thread_local_register_value;
bool success = reg_ctx->ReadRegister(reg_info, thread_local_register_value);
if (!success)
return;

const uint64_t fail_value = UINT64_MAX;
bool readSuccess = false;
const lldb::addr_t reg_value_addr =
thread_local_register_value.GetAsUInt64(fail_value, &readSuccess);
if (!readSuccess || reg_value_addr == fail_value)
return;

MemoryRegionInfo thread_local_region;
Status err = process.GetMemoryRegionInfo(reg_value_addr, thread_local_region);
if (err.Fail())
return;

ranges.push_back(thread_local_region);
}

// Save off the link map for core files.
static void AddLinkMapSections(Process &process,
std::vector<MemoryRegionInfo> &ranges) {
ModuleList &module_list = process.GetTarget().GetImages();
Target *target = &process.GetTarget();
for (size_t idx = 0; idx < module_list.GetSize(); idx++) {
ModuleSP module_sp = module_list.GetModuleAtIndex(idx);
if (!module_sp)
continue;

ObjectFile *obj = module_sp->GetObjectFile();
if (!obj)
continue;
Address addr = obj->GetImageInfoAddress(target);
addr_t load_addr = addr.GetLoadAddress(target);
if (load_addr == LLDB_INVALID_ADDRESS)
continue;

MemoryRegionInfo link_map_section;
Status err = process.GetMemoryRegionInfo(load_addr, link_map_section);
if (err.Fail())
continue;

ranges.push_back(link_map_section);
}
}

void DynamicLoaderPOSIXDYLD::CalculateDynamicSaveCoreRanges(
lldb_private::Process &process,
std::vector<lldb_private::MemoryRegionInfo> &ranges,
llvm::function_ref<bool(const lldb_private::Thread &)>
save_thread_predicate) {
ThreadList &thread_list = process.GetThreadList();
for (size_t idx = 0; idx < thread_list.GetSize(); idx++) {
ThreadSP thread_sp = thread_list.GetThreadAtIndex(idx);
if (!thread_sp)
continue;

if (!save_thread_predicate(*thread_sp))
continue;

AddThreadLocalMemoryRegions(process, thread_sp, ranges);
}

AddLinkMapSections(process, ranges);
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader {
lldb::addr_t base_addr,
bool base_addr_is_offset) override;

void CalculateDynamicSaveCoreRanges(
lldb_private::Process &process,
std::vector<lldb_private::MemoryRegionInfo> &ranges,
llvm::function_ref<bool(const lldb_private::Thread &)>
save_thread_predicate) override;

protected:
/// Runtime linker rendezvous structure.
DYLDRendezvous m_rendezvous;
Expand Down
3 changes: 0 additions & 3 deletions lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
case eStopReasonProcessorTrace:
log.Printf("%s: %s processor trace", __FUNCTION__, header);
return;
case eStopReasonHistoryBoundary:
log.Printf("%s: %s history boundary", __FUNCTION__, header);
return;
default:
log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
static_cast<uint32_t>(stop_info.reason));
Expand Down
10 changes: 1 addition & 9 deletions lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,17 +402,9 @@ lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() {

Status ProcessKDP::WillResume() { return Status(); }

Status ProcessKDP::DoResume(RunDirection direction) {
Status ProcessKDP::DoResume() {
Status error;
Log *log = GetLog(KDPLog::Process);

if (direction == RunDirection::eRunReverse) {
error.FromErrorStringWithFormatv(
"error: {0} does not support reverse execution of processes",
GetPluginName());
return error;
}

// Only start the async thread if we try to do any process control
if (!m_async_thread.IsJoinable())
StartAsyncThread();
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class ProcessKDP : public lldb_private::Process {
// Process Control
lldb_private::Status WillResume() override;

lldb_private::Status DoResume(lldb::RunDirection direction) override;
lldb_private::Status DoResume() override;

lldb_private::Status DoHalt(bool &caused_stop) override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,17 +204,11 @@ ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
return error;
}

Status ProcessWindows::DoResume(RunDirection direction) {
Status ProcessWindows::DoResume() {
Log *log = GetLog(WindowsLog::Process);
llvm::sys::ScopedLock lock(m_mutex);
Status error;

if (direction == RunDirection::eRunReverse) {
error.SetErrorStringWithFormatv(
"error: {0} does not support reverse execution of processes", GetPluginName());
return error;
}

StateType private_state = GetPrivateState();
if (private_state == eStateStopped || private_state == eStateCrashed) {
LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ProcessWindows : public Process, public ProcessDebugger {
Status DoAttachToProcessWithID(
lldb::pid_t pid,
const lldb_private::ProcessAttachInfo &attach_info) override;
Status DoResume(lldb::RunDirection direction) override;
Status DoResume() override;
Status DoDestroy() override;
Status DoHalt(bool &caused_stop) override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,20 +199,6 @@ uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
return m_max_packet_size;
}

bool GDBRemoteCommunicationClient::GetReverseContinueSupported() {
if (m_supports_reverse_continue == eLazyBoolCalculate) {
GetRemoteQSupported();
}
return m_supports_reverse_continue == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetReverseStepSupported() {
if (m_supports_reverse_step == eLazyBoolCalculate) {
GetRemoteQSupported();
}
return m_supports_reverse_step == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
if (m_supports_not_sending_acks == eLazyBoolCalculate) {
m_send_acks = true;
Expand Down Expand Up @@ -309,8 +295,6 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
m_supports_qXfer_siginfo_read = eLazyBoolCalculate;
m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
m_uses_native_signals = eLazyBoolCalculate;
m_supports_reverse_continue = eLazyBoolCalculate;
m_supports_reverse_step = eLazyBoolCalculate;
m_supports_qProcessInfoPID = true;
m_supports_qfProcessInfo = true;
m_supports_qUserName = true;
Expand Down Expand Up @@ -364,8 +348,6 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_memory_tagging = eLazyBoolNo;
m_supports_qSaveCore = eLazyBoolNo;
m_uses_native_signals = eLazyBoolNo;
m_supports_reverse_continue = eLazyBoolNo;
m_supports_reverse_step = eLazyBoolNo;

m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
// not, we assume no limit
Expand Down Expand Up @@ -419,10 +401,6 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_qSaveCore = eLazyBoolYes;
else if (x == "native-signals+")
m_uses_native_signals = eLazyBoolYes;
else if (x == "ReverseContinue+")
m_supports_reverse_continue = eLazyBoolYes;
else if (x == "ReverseStep+")
m_supports_reverse_step = eLazyBoolYes;
// Look for a list of compressions in the features list e.g.
// qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
// deflate,lzma
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,10 +331,6 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {

bool GetMultiprocessSupported();

bool GetReverseContinueSupported();

bool GetReverseStepSupported();

LazyBool SupportsAllocDeallocMemory() // const
{
// Uncomment this to have lldb pretend the debug server doesn't respond to
Expand Down Expand Up @@ -565,8 +561,6 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
LazyBool m_supports_memory_tagging = eLazyBoolCalculate;
LazyBool m_supports_qSaveCore = eLazyBoolCalculate;
LazyBool m_uses_native_signals = eLazyBoolCalculate;
LazyBool m_supports_reverse_continue = eLazyBoolCalculate;
LazyBool m_supports_reverse_step = eLazyBoolCalculate;

bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
m_supports_qUserName : 1, m_supports_qGroupName : 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,6 @@ static const char *GetStopReasonString(StopReason stop_reason) {
return "vforkdone";
case eStopReasonInterrupt:
return "async interrupt";
case eStopReasonHistoryBoundary:
case eStopReasonInstrumentation:
case eStopReasonInvalid:
case eStopReasonPlanComplete:
Expand Down
77 changes: 14 additions & 63 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,6 @@ class PluginProperties : public Properties {
}
};

std::chrono::seconds ResumeTimeout() {
return std::chrono::seconds(5);
}

} // namespace

static PluginProperties &GetGlobalPluginProperties() {
Expand Down Expand Up @@ -1184,11 +1180,10 @@ Status ProcessGDBRemote::WillResume() {
return Status();
}
Status ProcessGDBRemote::DoResume(RunDirection direction) {
Status ProcessGDBRemote::DoResume() {
Status error;
Log *log = GetLog(GDBRLog::Process);
LLDB_LOGF(log, "ProcessGDBRemote::Resume(%s)",
direction == RunDirection::eRunForward ? "" : "reverse");
LLDB_LOGF(log, "ProcessGDBRemote::Resume()");
ListenerSP listener_sp(
Listener::MakeListener("gdb-remote.resume-packet-sent"));
Expand All @@ -1202,21 +1197,12 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) {
StreamString continue_packet;
bool continue_packet_error = false;
// Number of threads continuing with "c", i.e. continuing without a signal to deliver.
const size_t num_continue_c_tids = m_continue_c_tids.size();
// Number of threads continuing with "C", i.e. continuing with a signal to deliver.
const size_t num_continue_C_tids = m_continue_C_tids.size();
// Number of threads continuing with "s", i.e. single-stepping.
const size_t num_continue_s_tids = m_continue_s_tids.size();
// Number of threads continuing with "S", i.e. single-stepping with a signal to deliver.
const size_t num_continue_S_tids = m_continue_S_tids.size();
if (direction == RunDirection::eRunForward &&
m_gdb_comm.HasAnyVContSupport()) {
if (m_gdb_comm.HasAnyVContSupport()) {
std::string pid_prefix;
if (m_gdb_comm.GetMultiprocessSupported())
pid_prefix = llvm::formatv("p{0:x-}.", GetID());
if (num_continue_c_tids == num_threads ||
if (m_continue_c_tids.size() == num_threads ||
(m_continue_c_tids.empty() && m_continue_C_tids.empty() &&
m_continue_s_tids.empty() && m_continue_S_tids.empty())) {
// All threads are continuing
Expand Down Expand Up @@ -1279,11 +1265,14 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) {
} else
continue_packet_error = true;
if (direction == RunDirection::eRunForward && continue_packet_error) {
if (continue_packet_error) {
// Either no vCont support, or we tried to use part of the vCont packet
// that wasn't supported by the remote GDB server, or it's the reverse
// direction. We need to try and make a simple packet that can do our
// continue.
// that wasn't supported by the remote GDB server. We need to try and
// make a simple packet that can do our continue
const size_t num_continue_c_tids = m_continue_c_tids.size();
const size_t num_continue_C_tids = m_continue_C_tids.size();
const size_t num_continue_s_tids = m_continue_s_tids.size();
const size_t num_continue_S_tids = m_continue_S_tids.size();
if (num_continue_c_tids > 0) {
if (num_continue_c_tids == num_threads) {
// All threads are resuming...
Expand Down Expand Up @@ -1374,41 +1363,9 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) {
}
}
if (direction == RunDirection::eRunReverse && continue_packet_error) {
if (num_continue_C_tids > 0 || num_continue_S_tids > 0) {
LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: Signals not supported");
return Status::FromErrorString("can't deliver signals while running in reverse");
}
if (num_continue_s_tids > 0) {
if (num_continue_s_tids > 1) {
LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: can't step multiple threads");
return Status::FromErrorString("can't step multiple threads while reverse-stepping");
}
if (!m_gdb_comm.GetReverseStepSupported()) {
LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: target does not support reverse-stepping");
return Status::FromErrorString("target does not support reverse-stepping");
}
m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());
continue_packet.PutCString("bs");
} else {
if (!m_gdb_comm.GetReverseContinueSupported()) {
LLDB_LOGF(log, "ProcessGDBRemote::DoResumeReverse: target does not support reverse-continue");
return Status::FromErrorString("target does not support reverse-continue");
}
// All threads continue whether requested or not ---
// we can't change how threads ran in the past.
continue_packet.PutCString("bc");
}

continue_packet_error = false;
}

if (continue_packet_error) {
return Status::FromErrorString("can't make continue packet for this resume");
error =
Status::FromErrorString("can't make continue packet for this resume");
} else {
EventSP event_sp;
if (!m_async_thread.IsJoinable()) {
Expand All @@ -1423,7 +1380,7 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) {
std::make_shared<EventDataBytes>(continue_packet.GetString());
m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue, data_sp);
if (!listener_sp->GetEvent(event_sp, ResumeTimeout())) {
if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) {
error = Status::FromErrorString("Resume timed out.");
LLDB_LOGF(log, "ProcessGDBRemote::DoResume: Resume timed out.");
} else if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
Expand Down Expand Up @@ -1906,10 +1863,6 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
*thread_sp, description.c_str()));
handled = true;
} else if (reason == "replaylog") {
thread_sp->SetStopInfo(StopInfo::CreateStopReasonHistoryBoundary(
*thread_sp, description.c_str()));
handled = true;
} else if (reason == "exec") {
did_exec = true;
thread_sp->SetStopInfo(
Expand Down Expand Up @@ -2365,8 +2318,6 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
description = std::string(ostr.GetString());
} else if (key.compare("swbreak") == 0 || key.compare("hwbreak") == 0) {
reason = "breakpoint";
} else if (key.compare("replaylog") == 0) {
reason = "replaylog";
} else if (key.compare("library") == 0) {
auto error = LoadModules();
if (error) {
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class ProcessGDBRemote : public Process,
// Process Control
Status WillResume() override;

Status DoResume(lldb::RunDirection direction) override;
Status DoResume() override;

Status DoHalt(bool &caused_stop) override;

Expand Down
20 changes: 19 additions & 1 deletion lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/JITLoaderList.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
Expand All @@ -34,6 +36,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Threading.h"

#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"

Expand Down Expand Up @@ -333,6 +336,16 @@ ArchSpec ProcessMinidump::GetArchitecture() {
return ArchSpec(triple);
}

DataExtractor ProcessMinidump::GetAuxvData() {
std::optional<llvm::ArrayRef<uint8_t>> auxv =
m_minidump_parser->GetStream(StreamType::LinuxAuxv);
if (!auxv)
return DataExtractor();

return DataExtractor(auxv->data(), auxv->size(), GetByteOrder(),
GetAddressByteSize(), GetAddressByteSize());
}

void ProcessMinidump::BuildMemoryRegions() {
if (m_memory_regions)
return;
Expand Down Expand Up @@ -534,7 +547,12 @@ void ProcessMinidump::ReadModuleList() {

module_sp = Module::CreateModuleFromObjectFile<ObjectFilePlaceholder>(
module_spec, load_addr, load_size);
GetTarget().GetImages().Append(module_sp, true /* notify */);
// If we haven't loaded a main executable yet, set the first module to be
// main executable
if (!GetTarget().GetExecutableModule())
GetTarget().SetExecutableModule(module_sp);
else
GetTarget().GetImages().Append(module_sp, true /* notify */);
}

bool load_addr_changed = false;
Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Plugins/Process/minidump/ProcessMinidump.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,11 @@ class ProcessMinidump : public PostMortemProcess {

Status DoLoadCore() override;

DynamicLoader *GetDynamicLoader() override { return nullptr; }
// Returns AUXV structure found in the core file
lldb_private::DataExtractor GetAuxvData() override;

llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

SystemRuntime *GetSystemRuntime() override { return nullptr; }

Status DoDestroy() override;

void RefreshStateAfterStop() override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ static void writeRegister(const void *reg_src, uint8_t *context,
memcpy(reg_dest.data(), reg_src, reg_dest.size());
}

// TODO: Fix the registers in this file!
// writeRegister checks x86_64 registers without base registers. This causes
// an overlap in the register enum values. So we were truncating fs_base.
// We should standardize to the x86_64_with_base registers.
static void writeBaseRegister(const void *reg_src, uint8_t *context,
const RegisterInfo &reg) {
auto bytes = reg.mutable_data(context);
llvm::MutableArrayRef<uint8_t> reg_dest = bytes.take_front(8);
memcpy(reg_dest.data(), reg_src, reg_dest.size());
}

lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64(
llvm::ArrayRef<uint8_t> source_data,
RegisterInfoInterface *target_reg_interface) {
Expand Down Expand Up @@ -105,11 +116,12 @@ lldb::DataBufferSP lldb_private::minidump::ConvertMinidumpContext_x86_64(
writeRegister(&context->r15, result_base, reg_info[lldb_r15_x86_64]);
}

// See comment on base regsiter
if ((context_flags & LLDBSpecificFlag) == LLDBSpecificFlag) {
writeRegister(&context->fs_base, result_base,
reg_info[x86_64_with_base::lldb_fs_base]);
writeRegister(&context->gs_base, result_base,
reg_info[x86_64_with_base::lldb_gs_base]);
writeBaseRegister(&context->fs_base, result_base,
reg_info[x86_64_with_base::lldb_fs_base]);
writeBaseRegister(&context->gs_base, result_base,
reg_info[x86_64_with_base::lldb_gs_base]);
}

// TODO parse the floating point registers
Expand Down
9 changes: 2 additions & 7 deletions lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,10 @@ void ScriptedProcess::DidResume() {
m_pid = GetInterface().GetProcessID();
}

Status ScriptedProcess::DoResume(RunDirection direction) {
Status ScriptedProcess::DoResume() {
LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s resuming process", __FUNCTION__);

if (direction == RunDirection::eRunForward) {
return GetInterface().Resume();
} else {
return Status::FromErrorStringWithFormatv(
"error: {0} does not support reverse execution of processes", GetPluginName());
}
return GetInterface().Resume();
}

Status ScriptedProcess::DoAttach(const ProcessAttachInfo &attach_info) {
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/Process/scripted/ScriptedProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ScriptedProcess : public Process {

void DidResume() override;

Status DoResume(lldb::RunDirection direction) override;
Status DoResume() override;

Status DoAttachToProcessWithID(lldb::pid_t pid,
const ProcessAttachInfo &attach_info) override;
Expand Down
65 changes: 42 additions & 23 deletions lldb/source/Target/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
m_memory_cache(*this), m_allocated_memory_cache(*this),
m_should_detach(false), m_next_event_action_up(), m_public_run_lock(),
m_private_run_lock(), m_currently_handling_do_on_removals(false),
m_resume_requested(false), m_last_run_direction(eRunForward),
m_interrupt_tid(LLDB_INVALID_THREAD_ID),
m_resume_requested(false), m_interrupt_tid(LLDB_INVALID_THREAD_ID),
m_finalizing(false), m_destructing(false),
m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
Expand Down Expand Up @@ -846,7 +845,6 @@ bool Process::HandleProcessStateChangedEvent(
switch (thread_stop_reason) {
case eStopReasonInvalid:
case eStopReasonNone:
case eStopReasonHistoryBoundary:
break;

case eStopReasonSignal: {
Expand Down Expand Up @@ -1354,7 +1352,7 @@ void Process::SetPublicState(StateType new_state, bool restarted) {
}
}

Status Process::Resume(RunDirection direction) {
Status Process::Resume() {
Log *log(GetLog(LLDBLog::State | LLDBLog::Process));
LLDB_LOGF(log, "(plugin = %s) -- locking run lock", GetPluginName().data());
if (!m_public_run_lock.TrySetRunning()) {
Expand All @@ -1363,15 +1361,15 @@ Status Process::Resume(RunDirection direction) {
return Status::FromErrorString(
"Resume request failed - process still running.");
}
Status error = PrivateResume(direction);
Status error = PrivateResume();
if (!error.Success()) {
// Undo running state change
m_public_run_lock.SetStopped();
}
return error;
}

Status Process::ResumeSynchronous(Stream *stream, RunDirection direction) {
Status Process::ResumeSynchronous(Stream *stream) {
Log *log(GetLog(LLDBLog::State | LLDBLog::Process));
LLDB_LOGF(log, "Process::ResumeSynchronous -- locking run lock");
if (!m_public_run_lock.TrySetRunning()) {
Expand All @@ -1384,7 +1382,7 @@ Status Process::ResumeSynchronous(Stream *stream, RunDirection direction) {
Listener::MakeListener(ResumeSynchronousHijackListenerName.data()));
HijackProcessEvents(listener_sp);

Status error = PrivateResume(direction);
Status error = PrivateResume();
if (error.Success()) {
StateType state =
WaitForProcessToStop(std::nullopt, nullptr, true, listener_sp, stream,
Expand Down Expand Up @@ -3241,7 +3239,7 @@ Status Process::ConnectRemote(llvm::StringRef remote_url) {
return error;
}

Status Process::PrivateResume(RunDirection direction) {
Status Process::PrivateResume() {
Log *log(GetLog(LLDBLog::Process | LLDBLog::Step));
LLDB_LOGF(log,
"Process::PrivateResume() m_stop_id = %u, public state: %s "
Expand All @@ -3257,15 +3255,6 @@ Status Process::PrivateResume(RunDirection direction) {
if (!GetModID().IsLastResumeForUserExpression())
ResetExtendedCrashInfoDict();

if (m_last_run_direction != direction) {
// In the future we might want to support mixed-direction plans,
// e.g. a forward step-over stops at a breakpoint, the user does
// a reverse-step, then disables the breakpoint and continues forward.
// This code will need to be changed to support that.
m_thread_list.DiscardThreadPlans();
m_last_run_direction = direction;
}

Status error(WillResume());
// Tell the process it is about to resume before the thread list
if (error.Success()) {
Expand All @@ -3283,7 +3272,7 @@ Status Process::PrivateResume(RunDirection direction) {
"Process::PrivateResume PreResumeActions failed, not resuming.");
} else {
m_mod_id.BumpResumeID();
error = DoResume(direction);
error = DoResume();
if (error.Success()) {
DidResume();
m_thread_list.DidResume();
Expand Down Expand Up @@ -3746,7 +3735,7 @@ bool Process::ShouldBroadcastEvent(Event *event_ptr) {
"from state: %s",
static_cast<void *>(event_ptr), StateAsCString(state));
ProcessEventData::SetRestartedInEvent(event_ptr, true);
PrivateResume(m_last_run_direction);
PrivateResume();
}
} else {
return_value = true;
Expand Down Expand Up @@ -4357,7 +4346,7 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) {
SetRestarted(true);
// Use the private resume method here, since we aren't changing the run
// lock state.
process_sp->PrivateResume(process_sp->m_last_run_direction);
process_sp->PrivateResume();
} else {
bool hijacked = process_sp->IsHijackedForEvent(eBroadcastBitStateChanged) &&
!process_sp->StateChangedIsHijackedForSynchronousResume();
Expand Down Expand Up @@ -6539,6 +6528,29 @@ static void AddRegion(const MemoryRegionInfo &region, bool try_dirty_pages,
CreateCoreFileMemoryRange(region));
}

static void SaveDynamicLoaderSections(Process &process,
const SaveCoreOptions &options,
CoreFileMemoryRanges &ranges,
std::set<addr_t> &stack_ends) {
DynamicLoader *dyld = process.GetDynamicLoader();
if (!dyld)
return;

std::vector<MemoryRegionInfo> dynamic_loader_mem_regions;
std::function<bool(const lldb_private::Thread &)> save_thread_predicate =
[&](const lldb_private::Thread &t) -> bool {
return options.ShouldThreadBeSaved(t.GetID());
};
dyld->CalculateDynamicSaveCoreRanges(process, dynamic_loader_mem_regions,
save_thread_predicate);
for (const auto &region : dynamic_loader_mem_regions) {
// The Dynamic Loader can give us regions that could include a truncated
// stack
if (stack_ends.count(region.GetRange().GetRangeEnd()) == 0)
AddRegion(region, true, ranges);
}
}

static void SaveOffRegionsWithStackPointers(Process &process,
const SaveCoreOptions &core_options,
const MemoryRegionInfos &regions,
Expand Down Expand Up @@ -6570,11 +6582,13 @@ static void SaveOffRegionsWithStackPointers(Process &process,
// off in other calls
sp_region.GetRange().SetRangeBase(stack_head);
sp_region.GetRange().SetByteSize(stack_size);
stack_ends.insert(sp_region.GetRange().GetRangeEnd());
const addr_t range_end = sp_region.GetRange().GetRangeEnd();
stack_ends.insert(range_end);
// This will return true if the threadlist the user specified is empty,
// or contains the thread id from thread_sp.
if (core_options.ShouldThreadBeSaved(thread_sp->GetID()))
if (core_options.ShouldThreadBeSaved(thread_sp->GetID())) {
AddRegion(sp_region, try_dirty_pages, ranges);
}
}
}
}
Expand Down Expand Up @@ -6683,9 +6697,14 @@ Status Process::CalculateCoreFileSaveRanges(const SaveCoreOptions &options,
std::set<addr_t> stack_ends;
// For fully custom set ups, we don't want to even look at threads if there
// are no threads specified.
if (core_style != lldb::eSaveCoreCustomOnly || options.HasSpecifiedThreads())
if (core_style != lldb::eSaveCoreCustomOnly ||
options.HasSpecifiedThreads()) {
SaveOffRegionsWithStackPointers(*this, options, regions, ranges,
stack_ends);
// Save off the dynamic loader sections, so if we are on an architecture
// that supports Thread Locals, that we include those as well.
SaveDynamicLoaderSections(*this, options, ranges, stack_ends);
}

switch (core_style) {
case eSaveCoreUnspecified:
Expand Down
29 changes: 0 additions & 29 deletions lldb/source/Target/StopInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1212,30 +1212,6 @@ class StopInfoProcessorTrace : public StopInfo {
}
};

// StopInfoHistoryBoundary

class StopInfoHistoryBoundary : public StopInfo {
public:
StopInfoHistoryBoundary(Thread &thread, const char *description)
: StopInfo(thread, LLDB_INVALID_UID) {
if (description)
SetDescription(description);
}

~StopInfoHistoryBoundary() override = default;

StopReason GetStopReason() const override {
return eStopReasonHistoryBoundary;
}

const char *GetDescription() override {
if (m_description.empty())
return "history boundary";
else
return m_description.c_str();
}
};

// StopInfoThreadPlan

class StopInfoThreadPlan : public StopInfo {
Expand Down Expand Up @@ -1463,11 +1439,6 @@ StopInfoSP StopInfo::CreateStopReasonProcessorTrace(Thread &thread,
return StopInfoSP(new StopInfoProcessorTrace(thread, description));
}

StopInfoSP StopInfo::CreateStopReasonHistoryBoundary(Thread &thread,
const char *description) {
return StopInfoSP(new StopInfoHistoryBoundary(thread, description));
}

StopInfoSP StopInfo::CreateStopReasonWithExec(Thread &thread) {
return StopInfoSP(new StopInfoExec(thread));
}
Expand Down
8 changes: 2 additions & 6 deletions lldb/source/Target/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,12 +624,10 @@ void Thread::SetupForResume() {
// what the current plan is.

lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
ProcessSP process_sp(GetProcess());
if (reg_ctx_sp && process_sp &&
process_sp->GetLastRunDirection() == eRunForward) {
if (reg_ctx_sp) {
const addr_t thread_pc = reg_ctx_sp->GetPC();
BreakpointSiteSP bp_site_sp =
process_sp->GetBreakpointSiteList().FindByAddress(thread_pc);
GetProcess()->GetBreakpointSiteList().FindByAddress(thread_pc);
if (bp_site_sp) {
// Note, don't assume there's a ThreadPlanStepOverBreakpoint, the
// target may not require anything special to step over a breakpoint.
Expand Down Expand Up @@ -1734,8 +1732,6 @@ std::string Thread::StopReasonAsString(lldb::StopReason reason) {
return "processor trace";
case eStopReasonInterrupt:
return "async interrupt";
case eStopReasonHistoryBoundary:
return "history boundary";
}

return "StopReason = " + std::to_string(reason);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,10 @@ def minidump_deleted_on_save_failure(self):
finally:
self.assertTrue(self.dbg.DeleteTarget(target))

def minidump_deterministic_difference(self):
"""Test that verifies that two minidumps produced are identical."""
@skipUnlessPlatform(["linux"])
@skipUnlessArch("x86_64")
def minidump_saves_fs_base_region(self):
"""Test that verifies the minidump file saves region for fs_base"""

self.build()
exe = self.getBuildArtifact("a.out")
Expand All @@ -534,6 +536,45 @@ def minidump_deterministic_difference(self):
None, None, self.get_process_working_directory()
)
self.assertState(process.GetState(), lldb.eStateStopped)
thread = process.GetThreadAtIndex(0)
custom_file = self.getBuildArtifact("core.reg_region.dmp")
options = lldb.SBSaveCoreOptions()
options.SetOutputFile(lldb.SBFileSpec(custom_file))
options.SetPluginName("minidump")
options.SetStyle(lldb.eSaveCoreCustomOnly)
options.AddThread(thread)
error = process.SaveCore(options)
self.assertTrue(error.Success())

registers = thread.GetFrameAtIndex(0).GetRegisters()
fs_base = registers.GetFirstValueByName("fs_base").GetValueAsUnsigned()
self.assertTrue(fs_base != 0)
core_target = self.dbg.CreateTarget(None)
core_proc = core_target.LoadCore(one_region_file)
core_region_list = core_proc.GetMemoryRegions()
live_region_list = process.GetMemoryRegions()
live_region = lldb.SBMemoryRegionInfo()
live_region_list.GetMemoryRegionForAddress(fs_base, live_region)
core_region = lldb.SBMemoryRegionInfo()
error = core_region_list.GetMemoryRegionForAddress(fs_base, core_region)
self.assertTrue(error.Success())
self.assertEqual(live_region, core_region)

finally:
self.assertTrue(self.dbg.DeleteTarget(target))
self.assertTrue(self.dbg.DeleteTarget(core_target))
if os.path.isfile(custom_file):
os.unlink(custom_file)

def minidump_deterministic_difference(self):
"""Test that verifies that two minidumps produced are identical."""
self.build()
exe = self.getBuildArtifact("a.out")
try:
target = self.dbg.CreateTarget(exe)
process = target.LaunchSimple(
None, None, self.get_process_working_directory()
)

core_styles = [
lldb.eSaveCoreStackOnly,
Expand Down Expand Up @@ -562,6 +603,36 @@ def minidump_deterministic_difference(self):
self.assertEqual(file_one, file_two)
self.assertTrue(os.unlink(spec_one.GetFileName()))
self.assertTrue(os.unlink(spec_two.GetFileName()))

finally:
self.assertTrue(self.dbg.DeleteTarget(target))

@skipUnlessPlatform(["linux"])
@skipUnlessArch("x86_64")
def minidump_saves_fs_base_region(self):
self.build()
exe = self.getBuildArtifact("a.out")
try:
target = self.dbg.CreateTarget(exe)
process = target.LaunchSimple(
None, None, self.get_process_working_directory()
)
self.assertState(process.GetState(), lldb.eStateStopped)
thread = process.GetThreadAtIndex(0)
tls_file = self.getBuildArtifact("core.tls.dmp")
options = lldb.SBSaveCoreOptions()
options.SetOutputFile(lldb.SBFileSpec(tls_file))
options.SetPluginName("minidump")
options.SetStyle(lldb.eSaveCoreCustomOnly)
options.AddThread(thread)
error = process.SaveCore(options)
self.assertTrue(error.Success())
core_target = self.dbg.CreateTarget(None)
core_proc = core_target.LoadCore(tls_file)
frame = core_proc.GetThreadAtIndex(0).GetFrameAtIndex(0)
tls_val = frame.FindValue("lf")
self.assertEqual(tls_val.GetValueAsUnsigned(), 42)

except:
self.assertTrue(self.dbg.DeleteTarget(target))
if os.path.isfile(tls_file):
os.unlink(tls_file)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cassert>
#include <iostream>
#include <thread>
thread_local size_t lf = 42;

void g() { assert(false); }

Expand Down
3 changes: 0 additions & 3 deletions lldb/test/API/functionalities/reverse-execution/Makefile

This file was deleted.

This file was deleted.

This file was deleted.

14 changes: 0 additions & 14 deletions lldb/test/API/functionalities/reverse-execution/main.c

This file was deleted.

3 changes: 0 additions & 3 deletions lldb/tools/lldb-dap/JSONUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1045,9 +1045,6 @@ llvm::json::Value CreateThreadStopped(lldb::SBThread &thread,
case lldb::eStopReasonProcessorTrace:
body.try_emplace("reason", "processor trace");
break;
case lldb::eStopReasonHistoryBoundary:
body.try_emplace("reason", "history boundary");
break;
case lldb::eStopReasonSignal:
case lldb::eStopReasonException:
body.try_emplace("reason", "exception");
Expand Down
1 change: 0 additions & 1 deletion lldb/tools/lldb-dap/LLDBUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ bool ThreadHasStopReason(lldb::SBThread &thread) {
case lldb::eStopReasonVFork:
case lldb::eStopReasonVForkDone:
case lldb::eStopReasonInterrupt:
case lldb::eStopReasonHistoryBoundary:
return true;
case lldb::eStopReasonThreadExiting:
case lldb::eStopReasonInvalid:
Expand Down
13 changes: 6 additions & 7 deletions llvm/include/llvm/ExecutionEngine/Orc/ELFNixPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,14 @@ class ELFNixPlatform : public Platform {
/// RuntimeAliases function, in which case the client is responsible for
/// setting up all aliases (including the required ones).
static Expected<std::unique_ptr<ELFNixPlatform>>
Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
JITDylib &PlatformJD, std::unique_ptr<DefinitionGenerator> OrcRuntime,
Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
std::unique_ptr<DefinitionGenerator> OrcRuntime,
std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);

/// Construct using a path to the ORC runtime.
static Expected<std::unique_ptr<ELFNixPlatform>>
Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
JITDylib &PlatformJD, const char *OrcRuntimePath,
Create(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
const char *OrcRuntimePath,
std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);

ExecutionSession &getExecutionSession() const { return ES; }
Expand Down Expand Up @@ -211,8 +211,7 @@ class ELFNixPlatform : public Platform {

static bool supportedTarget(const Triple &TT);

ELFNixPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
JITDylib &PlatformJD,
ELFNixPlatform(ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator,
Error &Err);

Expand Down Expand Up @@ -308,4 +307,4 @@ using SPSELFNixJITDylibDepInfoMap =
} // end namespace orc
} // end namespace llvm

#endif // LLVM_EXECUTIONENGINE_ORC_ELFNIXPLATFORM_H
#endif // LLVM_EXECUTIONENGINE_ORC_ELFNIXPLATFORM_H
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/IntrinsicsDirectX.td
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def int_dx_udot :
[IntrNoMem, Commutative] >;

def int_dx_frac : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;

def int_dx_isinf : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[llvm_anyfloat_ty], [IntrNoMem]>;
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/IntrinsicsSPIRV.td
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ let TargetPrefix = "spv" in {
def int_spv_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
def int_spv_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
def int_spv_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
def int_spv_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_spv_frac : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_spv_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
[IntrNoMem] >;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ class DGNode {
iterator preds_end(DependencyGraph &DAG) const {
return const_cast<DGNode *>(this)->preds_end(DAG);
}
/// \Returns a range of DAG predecessors nodes. If this is a MemDGNode then
/// this will also include the memory dependency predecessors.
/// Please note that this can include the same node more than once, if for
/// example it's both a use-def predecessor and a mem dep predecessor.
iterator_range<iterator> preds(DependencyGraph &DAG) const {
return make_range(preds_begin(DAG), preds_end(DAG));
}
Expand Down
24 changes: 13 additions & 11 deletions llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,13 @@ class DSOHandleMaterializationUnit : public MaterializationUnit {
namespace llvm {
namespace orc {

Expected<std::unique_ptr<ELFNixPlatform>> ELFNixPlatform::Create(
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
JITDylib &PlatformJD, std::unique_ptr<DefinitionGenerator> OrcRuntime,
std::optional<SymbolAliasMap> RuntimeAliases) {
Expected<std::unique_ptr<ELFNixPlatform>>
ELFNixPlatform::Create(ObjectLinkingLayer &ObjLinkingLayer,
JITDylib &PlatformJD,
std::unique_ptr<DefinitionGenerator> OrcRuntime,
std::optional<SymbolAliasMap> RuntimeAliases) {

auto &ES = ObjLinkingLayer.getExecutionSession();

// If the target is not supported then bail out immediately.
if (!supportedTarget(ES.getTargetTriple()))
Expand Down Expand Up @@ -271,15 +274,14 @@ Expected<std::unique_ptr<ELFNixPlatform>> ELFNixPlatform::Create(
// Create the instance.
Error Err = Error::success();
auto P = std::unique_ptr<ELFNixPlatform>(new ELFNixPlatform(
ES, ObjLinkingLayer, PlatformJD, std::move(OrcRuntime), Err));
ObjLinkingLayer, PlatformJD, std::move(OrcRuntime), Err));
if (Err)
return std::move(Err);
return std::move(P);
}

Expected<std::unique_ptr<ELFNixPlatform>>
ELFNixPlatform::Create(ExecutionSession &ES,
ObjectLinkingLayer &ObjLinkingLayer,
ELFNixPlatform::Create(ObjectLinkingLayer &ObjLinkingLayer,
JITDylib &PlatformJD, const char *OrcRuntimePath,
std::optional<SymbolAliasMap> RuntimeAliases) {

Expand All @@ -289,7 +291,7 @@ ELFNixPlatform::Create(ExecutionSession &ES,
if (!OrcRuntimeArchiveGenerator)
return OrcRuntimeArchiveGenerator.takeError();

return Create(ES, ObjLinkingLayer, PlatformJD,
return Create(ObjLinkingLayer, PlatformJD,
std::move(*OrcRuntimeArchiveGenerator),
std::move(RuntimeAliases));
}
Expand Down Expand Up @@ -392,10 +394,10 @@ bool ELFNixPlatform::supportedTarget(const Triple &TT) {
}

ELFNixPlatform::ELFNixPlatform(
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
JITDylib &PlatformJD,
ObjectLinkingLayer &ObjLinkingLayer, JITDylib &PlatformJD,
std::unique_ptr<DefinitionGenerator> OrcRuntimeGenerator, Error &Err)
: ES(ES), PlatformJD(PlatformJD), ObjLinkingLayer(ObjLinkingLayer),
: ES(ObjLinkingLayer.getExecutionSession()), PlatformJD(PlatformJD),
ObjLinkingLayer(ObjLinkingLayer),
DSOHandleSymbol(ES.intern("__dso_handle")) {
ErrorAsOutParameter _(&Err);
ObjLinkingLayer.addPlugin(std::make_unique<ELFNixPlatformPlugin>(*this));
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,8 +1185,8 @@ Expected<JITDylibSP> ExecutorNativePlatform::operator()(LLJIT &J) {
if (!G)
return G.takeError();

if (auto P = ELFNixPlatform::Create(ES, *ObjLinkingLayer, PlatformJD,
std::move(*G)))
if (auto P =
ELFNixPlatform::Create(*ObjLinkingLayer, PlatformJD, std::move(*G)))
J.getExecutionSession().setPlatform(std::move(*P));
else
return P.takeError();
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
ISD::FMAXNUM,
ISD::FMINIMUM,
ISD::FMAXIMUM,
ISD::FCANONICALIZE,
ISD::STRICT_FADD,
ISD::STRICT_FSUB,
ISD::STRICT_FMUL,
Expand Down Expand Up @@ -818,6 +819,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationPromotedToType(ISD::FROUNDEVEN, V4Narrow, MVT::v4f32);
setOperationPromotedToType(ISD::FRINT, V4Narrow, MVT::v4f32);
setOperationPromotedToType(ISD::FNEARBYINT, V4Narrow, MVT::v4f32);
setOperationPromotedToType(ISD::FCANONICALIZE, V4Narrow, MVT::v4f32);

setOperationAction(ISD::FABS, V4Narrow, Legal);
setOperationAction(ISD::FNEG, V4Narrow, Legal);
Expand Down Expand Up @@ -851,6 +853,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::SELECT, V8Narrow, Expand);
setOperationAction(ISD::SELECT_CC, V8Narrow, Expand);
setOperationAction(ISD::FP_EXTEND, V8Narrow, Expand);
setOperationPromotedToType(ISD::FCANONICALIZE, V8Narrow, MVT::v8f32);
};

if (!Subtarget->hasFullFP16()) {
Expand Down
53 changes: 38 additions & 15 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -5052,17 +5052,25 @@ def : Pat<(v1f64 (fminnum (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),

def : Pat<(fminnum_ieee (f64 FPR64:$a), (f64 FPR64:$b)),
(FMINNMDrr FPR64:$a, FPR64:$b)>;
def : Pat<(fminnum_ieee (f32 FPR32:$a), (f32 FPR32:$b)),
(FMINNMSrr FPR32:$a, FPR32:$b)>;
def : Pat<(fminnum_ieee (f16 FPR16:$a), (f16 FPR16:$b)),
(FMINNMHrr FPR16:$a, FPR16:$b)>;
def : Pat<(fmaxnum_ieee (f64 FPR64:$a), (f64 FPR64:$b)),
(FMAXNMDrr FPR64:$a, FPR64:$b)>;
def : Pat<(f64 (fcanonicalize f64:$a)),
(FMINNMDrr f64:$a, f64:$a)>;
def : Pat<(fminnum_ieee (f32 FPR32:$a), (f32 FPR32:$b)),
(FMINNMSrr FPR32:$a, FPR32:$b)>;
def : Pat<(fmaxnum_ieee (f32 FPR32:$a), (f32 FPR32:$b)),
(FMAXNMSrr FPR32:$a, FPR32:$b)>;
def : Pat<(f32 (fcanonicalize f32:$a)),
(FMINNMSrr f32:$a, f32:$a)>;

let Predicates = [HasFullFP16] in {
def : Pat<(fminnum_ieee (f16 FPR16:$a), (f16 FPR16:$b)),
(FMINNMHrr FPR16:$a, FPR16:$b)>;
def : Pat<(fmaxnum_ieee (f16 FPR16:$a), (f16 FPR16:$b)),
(FMAXNMHrr FPR16:$a, FPR16:$b)>;

def : Pat<(f16 (fcanonicalize f16:$a)),
(FMINNMHrr f16:$a, f16:$a)>;
}
//===----------------------------------------------------------------------===//
// Floating point three operand instructions.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -5567,26 +5575,41 @@ defm FMINNM : SIMDThreeSameVectorFP<0,1,0b000,"fminnm", any_fminnum>;
defm FMINP : SIMDThreeSameVectorFP<1,1,0b110,"fminp", int_aarch64_neon_fminp>;
defm FMIN : SIMDThreeSameVectorFP<0,1,0b110,"fmin", any_fminimum>;

let Predicates = [HasNEON] in {
def : Pat<(v2f64 (fminnum_ieee (v2f64 V128:$Rn), (v2f64 V128:$Rm))),
(v2f64 (FMINNMv2f64 (v2f64 V128:$Rn), (v2f64 V128:$Rm)))>;
def : Pat<(v4f32 (fminnum_ieee (v4f32 V128:$Rn), (v4f32 V128:$Rm))),
(v4f32 (FMINNMv4f32 (v4f32 V128:$Rn), (v4f32 V128:$Rm)))>;
def : Pat<(v8f16 (fminnum_ieee (v8f16 V128:$Rn), (v8f16 V128:$Rm))),
(v8f16 (FMINNMv8f16 (v8f16 V128:$Rn), (v8f16 V128:$Rm)))>;
def : Pat<(v2f32 (fminnum_ieee (v2f32 V64:$Rn), (v2f32 V64:$Rm))),
(v2f32 (FMINNMv2f32 (v2f32 V64:$Rn), (v2f32 V64:$Rm)))>;
def : Pat<(v4f16 (fminnum_ieee (v4f16 V64:$Rn), (v4f16 V64:$Rm))),
(v4f16 (FMINNMv4f16 (v4f16 V64:$Rn), (v4f16 V64:$Rm)))>;
def : Pat<(v2f64 (fmaxnum_ieee (v2f64 V128:$Rn), (v2f64 V128:$Rm))),
(v2f64 (FMAXNMv2f64 (v2f64 V128:$Rn), (v2f64 V128:$Rm)))>;
def : Pat<(v2f64 (fcanonicalize (v2f64 V128:$Rn))),
(v2f64 (FMINNMv2f64 (v2f64 V128:$Rn), (v2f64 V128:$Rn)))>;
def : Pat<(v4f32 (fminnum_ieee (v4f32 V128:$Rn), (v4f32 V128:$Rm))),
(v4f32 (FMINNMv4f32 (v4f32 V128:$Rn), (v4f32 V128:$Rm)))>;
def : Pat<(v4f32 (fmaxnum_ieee (v4f32 V128:$Rn), (v4f32 V128:$Rm))),
(v4f32 (FMAXNMv4f32 (v4f32 V128:$Rn), (v4f32 V128:$Rm)))>;
def : Pat<(v8f16 (fmaxnum_ieee (v8f16 V128:$Rn), (v8f16 V128:$Rm))),
(v8f16 (FMAXNMv8f16 (v8f16 V128:$Rn), (v8f16 V128:$Rm)))>;
def : Pat<(v4f32 (fcanonicalize (v4f32 V128:$Rn))),
(v4f32 (FMINNMv4f32 (v4f32 V128:$Rn), (v4f32 V128:$Rn)))>;
def : Pat<(v2f32 (fminnum_ieee (v2f32 V64:$Rn), (v2f32 V64:$Rm))),
(v2f32 (FMINNMv2f32 (v2f32 V64:$Rn), (v2f32 V64:$Rm)))>;
def : Pat<(v2f32 (fmaxnum_ieee (v2f32 V64:$Rn), (v2f32 V64:$Rm))),
(v2f32 (FMAXNMv2f32 (v2f32 V64:$Rn), (v2f32 V64:$Rm)))>;
def : Pat<(v2f32 (fcanonicalize (v2f32 V64:$Rn))),
(v2f32 (FMINNMv2f32 (v2f32 V64:$Rn), (v2f32 V64:$Rn)))>;
}

let Predicates = [HasNEON, HasFullFP16] in {
def : Pat<(v8f16 (fminnum_ieee (v8f16 V128:$Rn), (v8f16 V128:$Rm))),
(v8f16 (FMINNMv8f16 (v8f16 V128:$Rn), (v8f16 V128:$Rm)))>;
def : Pat<(v8f16 (fmaxnum_ieee (v8f16 V128:$Rn), (v8f16 V128:$Rm))),
(v8f16 (FMAXNMv8f16 (v8f16 V128:$Rn), (v8f16 V128:$Rm)))>;
def : Pat<(v8f16 (fcanonicalize (v8f16 V128:$Rn))),
(v8f16 (FMINNMv8f16 (v8f16 V128:$Rn), (v8f16 V128:$Rn)))>;
def : Pat<(v4f16 (fminnum_ieee (v4f16 V64:$Rn), (v4f16 V64:$Rm))),
(v4f16 (FMINNMv4f16 (v4f16 V64:$Rn), (v4f16 V64:$Rm)))>;
def : Pat<(v4f16 (fmaxnum_ieee (v4f16 V64:$Rn), (v4f16 V64:$Rm))),
(v4f16 (FMAXNMv4f16 (v4f16 V64:$Rn), (v4f16 V64:$Rm)))>;
def : Pat<(v4f16 (fcanonicalize (v4f16 V64:$Rn))),
(v4f16 (FMINNMv4f16 (v4f16 V64:$Rn), (v4f16 V64:$Rn)))>;
}

// NOTE: The operands of the PatFrag are reordered on FMLA/FMLS because the
// instruction expects the addend first, while the fma intrinsic puts it last.
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ static bool isIntrinsicExpansion(Function &F) {
case Intrinsic::dx_clamp:
case Intrinsic::dx_cross:
case Intrinsic::dx_uclamp:
case Intrinsic::dx_degrees:
case Intrinsic::dx_lerp:
case Intrinsic::dx_length:
case Intrinsic::dx_normalize:
Expand Down Expand Up @@ -490,6 +491,14 @@ static Value *expandClampIntrinsic(CallInst *Orig,
{MaxCall, Max}, nullptr, "dx.min");
}

static Value *expandDegreesIntrinsic(CallInst *Orig) {
Value *X = Orig->getOperand(0);
Type *Ty = X->getType();
IRBuilder<> Builder(Orig);
Value *DegreesRatio = ConstantFP::get(Ty, 180.0 * llvm::numbers::inv_pi);
return Builder.CreateFMul(X, DegreesRatio);
}

static Value *expandSignIntrinsic(CallInst *Orig) {
Value *X = Orig->getOperand(0);
Type *Ty = X->getType();
Expand Down Expand Up @@ -549,6 +558,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) {
case Intrinsic::dx_clamp:
Result = expandClampIntrinsic(Orig, IntrinsicId);
break;
case Intrinsic::dx_degrees:
Result = expandDegreesIntrinsic(Orig);
break;
case Intrinsic::dx_lerp:
Result = expandLerpIntrinsic(Orig);
break;
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2513,6 +2513,8 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
return selectExtInst(ResVReg, ResType, I, CL::mix, GL::FMix);
case Intrinsic::spv_length:
return selectExtInst(ResVReg, ResType, I, CL::length, GL::Length);
case Intrinsic::spv_degrees:
return selectExtInst(ResVReg, ResType, I, CL::degrees, GL::Degrees);
case Intrinsic::spv_frac:
return selectExtInst(ResVReg, ResType, I, CL::fract, GL::Fract);
case Intrinsic::spv_normalize:
Expand Down
587 changes: 587 additions & 0 deletions llvm/test/CodeGen/AArch64/fp-fcanonicalize.ll

Large diffs are not rendered by default.

560 changes: 560 additions & 0 deletions llvm/test/CodeGen/AArch64/fp-maximumnum-minimumnum.ll

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions llvm/test/CodeGen/DirectX/degrees.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
; RUN: opt -S -dxil-intrinsic-expansion -scalarizer -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s

; Make sure dxil op function calls for degrees are expanded and lowered as fmul for float and half.

define noundef half @degrees_half(half noundef %a) {
; CHECK-LABEL: define noundef half @degrees_half(
; CHECK-SAME: half noundef [[A:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[DX_DEGREES1:%.*]] = fmul half [[A]], 0xH5329
; CHECK-NEXT: ret half [[DX_DEGREES1]]
;
entry:
%dx.degrees = call half @llvm.dx.degrees.f16(half %a)
ret half %dx.degrees
}

define noundef float @degrees_float(float noundef %a) #0 {
; CHECK-LABEL: define noundef float @degrees_float(
; CHECK-SAME: float noundef [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[DEGREES:%.*]] = fmul float [[A]], 0x404CA5DC20000000
; CHECK-NEXT: ret float [[DEGREES]]
;
entry:
%dx.degrees = call float @llvm.dx.degrees.f32(float %a)
ret float %dx.degrees
}

define noundef <4 x float> @degrees_float4(<4 x float> noundef %a) #0 {
; CHECK-LABEL: define noundef <4 x float> @degrees_float4(
; CHECK-SAME: <4 x float> noundef [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A]], i64 0
; CHECK-NEXT: [[DEGREES_A0:%.*]] = fmul float [[A0]], 0x404CA5DC20000000
; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i64 1
; CHECK-NEXT: [[DEGREES_A1:%.*]] = fmul float [[A1]], 0x404CA5DC20000000
; CHECK-NEXT: [[A2:%.*]] = extractelement <4 x float> [[A]], i64 2
; CHECK-NEXT: [[DEGREES_A2:%.*]] = fmul float [[A2]], 0x404CA5DC20000000
; CHECK-NEXT: [[A3:%.*]] = extractelement <4 x float> [[A]], i64 3
; CHECK-NEXT: [[DEGREES_A3:%.*]] = fmul float [[A3]], 0x404CA5DC20000000
; CHECK-NEXT: [[INSERT_0:%.*]] = insertelement <4 x float> poison, float [[DEGREES_A0]], i64 0
; CHECK-NEXT: [[INSERT_1:%.*]] = insertelement <4 x float> [[INSERT_0]], float [[DEGREES_A1]], i64 1
; CHECK-NEXT: [[INSERT_2:%.*]] = insertelement <4 x float> [[INSERT_1]], float [[DEGREES_A2]], i64 2
; CHECK-NEXT: [[RES:%.*]] = insertelement <4 x float> [[INSERT_2]], float [[DEGREES_A3]], i64 3
; CHECK-NEXT: ret <4 x float> [[RES]]
;
entry:
%2 = call <4 x float> @llvm.dx.degrees.v4f32(<4 x float> %a)
ret <4 x float> %2
}

declare half @llvm.dx.degrees.f16(half)
declare float @llvm.dx.degrees.f32(float)
declare <4 x float> @llvm.dx.degrees.v4f32(<4 x float>)
52 changes: 52 additions & 0 deletions llvm/test/CodeGen/SPIRV/hlsl-intrinsics/degrees.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"

; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16

; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4

; CHECK-LABEL: Begin function degrees_float
define noundef float @degrees_float(float noundef %a) {
entry:
; CHECK: %[[#float_32_arg:]] = OpFunctionParameter %[[#float_32]]
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Degrees %[[#float_32_arg]]
%elt.degrees = call float @llvm.spv.degrees.f32(float %a)
ret float %elt.degrees
}

; CHECK-LABEL: Begin function degrees_half
define noundef half @degrees_half(half noundef %a) {
entry:
; CHECK: %[[#float_16_arg:]] = OpFunctionParameter %[[#float_16]]
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Degrees %[[#float_16_arg]]
%elt.degrees = call half @llvm.spv.degrees.f16(half %a)
ret half %elt.degrees
}

; CHECK-LABEL: Begin function degrees_float_vector
define noundef <4 x float> @degrees_float_vector(<4 x float> noundef %a) {
entry:
; CHECK: %[[#vec4_float_32_arg:]] = OpFunctionParameter %[[#vec4_float_32]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Degrees %[[#vec4_float_32_arg]]
%elt.degrees = call <4 x float> @llvm.spv.degrees.v4f32(<4 x float> %a)
ret <4 x float> %elt.degrees
}

; CHECK-LABEL: Begin function degrees_half_vector
define noundef <4 x half> @degrees_half_vector(<4 x half> noundef %a) {
entry:
; CHECK: %[[#vec4_float_16_arg:]] = OpFunctionParameter %[[#vec4_float_16]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Degrees %[[#vec4_float_16_arg]]
%elt.degrees = call <4 x half> @llvm.spv.degrees.v4f16(<4 x half> %a)
ret <4 x half> %elt.degrees
}

declare half @llvm.spv.degrees.f16(half)
declare float @llvm.spv.degrees.f32(float)

declare <4 x float> @llvm.spv.degrees.v4f32(<4 x float>)
declare <4 x half> @llvm.spv.degrees.v4f16(<4 x half>)
50 changes: 50 additions & 0 deletions llvm/test/CodeGen/SPIRV/opencl/degrees.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "OpenCL.std"

; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16

; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4

declare half @llvm.spv.degrees.f16(half)
declare float @llvm.spv.degrees.f32(float)

declare <4 x float> @llvm.spv.degrees.v4f32(<4 x float>)
declare <4 x half> @llvm.spv.degrees.v4f16(<4 x half>)

define noundef float @degrees_float(float noundef %a) {
entry:
; CHECK: %[[#float_32_arg:]] = OpFunctionParameter %[[#float_32]]
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] degrees %[[#float_32_arg]]
%elt.degrees = call float @llvm.spv.degrees.f32(float %a)
ret float %elt.degrees
}

define noundef half @degrees_half(half noundef %a) {
entry:
; CHECK: %[[#float_16_arg:]] = OpFunctionParameter %[[#float_16]]
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] degrees %[[#float_16_arg]]
%elt.degrees = call half @llvm.spv.degrees.f16(half %a)
ret half %elt.degrees
}

define noundef <4 x float> @degrees_float_vector(<4 x float> noundef %a) {
entry:
; CHECK: %[[#vec4_float_32_arg:]] = OpFunctionParameter %[[#vec4_float_32]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] degrees %[[#vec4_float_32_arg]]
%elt.degrees = call <4 x float> @llvm.spv.degrees.v4f32(<4 x float> %a)
ret <4 x float> %elt.degrees
}

define noundef <4 x half> @degrees_half_vector(<4 x half> noundef %a) {
entry:
; CHECK: %[[#vec4_float_16_arg:]] = OpFunctionParameter %[[#vec4_float_16]]
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] degrees %[[#vec4_float_16_arg]]
%elt.degrees = call <4 x half> @llvm.spv.degrees.v4f16(<4 x half> %a)
ret <4 x half> %elt.degrees
}
4 changes: 2 additions & 2 deletions llvm/tools/llvm-jitlink/llvm-jitlink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1041,8 +1041,8 @@ Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
return;
}
} else if (TT.isOSBinFormatELF()) {
if (auto P = ELFNixPlatform::Create(ES, ObjLayer, *PlatformJD,
OrcRuntime.c_str()))
if (auto P =
ELFNixPlatform::Create(ObjLayer, *PlatformJD, OrcRuntime.c_str()))
ES.setPlatform(std::move(*P));
else {
Err = P.takeError();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
load("//llvm:lit_test.bzl", "lit_test", "package_path")

package(
default_visibility = ["//visibility:public"],
Expand Down Expand Up @@ -61,3 +63,71 @@ cc_binary(
"//llvm:Support",
],
)

cc_test(
name = "unittests",
srcs = glob(["unittests/*.cpp"]),
deps = [
":include_cleaner",
":include_cleaner_internal",
"//clang:ast",
"//clang:basic",
"//clang:format",
"//clang:frontend",
"//clang:lex",
"//clang:serialization",
"//clang:testing",
"//clang:tooling",
"//clang:tooling_inclusions",
"//llvm:Support",
"//llvm:TestingAnnotations",
"//third-party/unittest:gmock",
"//third-party/unittest:gtest",
],
)

LLVM_LIT_PATH_FUNCTION = " " + \
"# Allow generated file to be relocatable.\n" + \
"from pathlib import Path\n" + \
"def path(p):\n" + \
" p = Path(p)\n" + \
" if p.exists: return str(p.resolve())\n" + \
" if not p: return ''\n" + \
" return str((Path(__file__).parent / p).resolve())\n"

LIT_SITE_CFG_IN_HEADER = "# Autogenerated, do not edit." + LLVM_LIT_PATH_FUNCTION

expand_template(
name = "lit_site_cfg_py",
testonly = True,
out = "test/lit.site.cfg.py",
substitutions = {
"@CMAKE_CURRENT_BINARY_DIR@": package_path("//clang-tools-extra/include-cleaner:BUILD") + "/test",
"@CMAKE_CURRENT_SOURCE_DIR@": package_path("//clang-tools-extra/include-cleaner:BUILD") + "/test",
"@CURRENT_TOOLS_DIR@": package_path("//clang-tools-extra/include-cleaner:BUILD"),
"@LIT_SITE_CFG_IN_HEADER@": LIT_SITE_CFG_IN_HEADER,
"@LLVM_LIBS_DIR@": package_path("//llvm:BUILD"),
"@LLVM_LIT_TOOLS_DIR@": package_path("//llvm:BUILD"),
"@LLVM_TOOLS_DIR@": package_path("//llvm:BUILD"),
"@TARGET_TRIPLE@": "",
'"@Python3_EXECUTABLE@"': "sys.executable",
},
template = "test/lit.site.cfg.py.in",
)

[
lit_test(
name = "%s.test" % src,
srcs = [src],
data = glob(["test/Inputs/**/*"]) + [
"test/lit.cfg.py",
"test/lit.site.cfg.py",
":clang-include-cleaner",
"//llvm:FileCheck",
"//llvm:count",
"//llvm:not",
],
args = ["-svv"],
)
for src in glob(["test/*.cpp"])
]
Original file line number Diff line number Diff line change
Expand Up @@ -2248,6 +2248,8 @@ cc_library(
hdrs = glob(["Process/minidump/*.h"]),
include_prefix = "Plugins",
deps = [
":PluginDynamicLoaderPosixDYLD",
":PluginDynamicLoaderPosixDYLDHeaders",
":PluginObjectFilePlaceholder",
":PluginProcessElfCore",
":PluginProcessUtility",
Expand Down