-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[lldb][NFC] Architecture plugins should report the vector element order #157198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[lldb][NFC] Architecture plugins should report the vector element order #157198
Conversation
Some targets like PowerPC store their - PowerPC little endian: little endian elements ordered 0, 1, 2, ... - PowerPC big endian: big endian elements ordered n-1, n-2, n-3, ... - ARM/MIPS little endian: little endian elements ordered 0, 1, 2, ... - ARM/MIPS big endian: big endian elements ordered 0, 1, 2, ... This matters when LLVM-IR values are transferred to/from target memory since LLVM-IR orders elements 0, 1, 2, ... regardless of endianness. This will be used in llvm#155000 by changes to the IRInterpreter to allow it to evaluate some vectors without executing on the target
@llvm/pr-subscribers-lldb Author: Daniel Sanders (dsandersllvm) ChangesSome targets like PowerPC store their
This matters when LLVM-IR values are transferred to/from target memory since LLVM-IR orders elements 0, 1, 2, ... regardless of endianness. This will be used in #155000 by changes to the IRInterpreter to allow it to evaluate some vectors without executing on the target Full diff: https://github.com/llvm/llvm-project/pull/157198.diff 3 Files Affected:
diff --git a/lldb/include/lldb/Core/Architecture.h b/lldb/include/lldb/Core/Architecture.h
index b6fc1a20e1e69..f039d05fe00fa 100644
--- a/lldb/include/lldb/Core/Architecture.h
+++ b/lldb/include/lldb/Core/Architecture.h
@@ -129,6 +129,17 @@ class Architecture : public PluginInterface {
RegisterContext ®_context) const {
return false;
}
+
+ /// Get the vector element order for this architecture. This determines how
+ /// vector elements are indexed. This matters in a few places such as reading/
+ /// writing LLVM-IR values to/from target memory. Some architectures use
+ /// little-endian element ordering where element 0 is at the lowest address
+ /// even when the architecture is otherwise big-endian (e.g. MIPS MSA, ARM
+ /// NEON), but some architectures like PowerPC may use big-endian element
+ /// ordering where element 0 is at the highest address.
+ virtual lldb::ByteOrder GetVectorElementOrder() const {
+ return lldb::eByteOrderLittle;
+ }
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
index b8fac55e41da7..a4690cc561a28 100644
--- a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
+++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp
@@ -35,7 +35,8 @@ void ArchitecturePPC64::Terminate() {
std::unique_ptr<Architecture> ArchitecturePPC64::Create(const ArchSpec &arch) {
if (arch.GetTriple().isPPC64() &&
arch.GetTriple().getObjectFormat() == llvm::Triple::ObjectFormatType::ELF)
- return std::unique_ptr<Architecture>(new ArchitecturePPC64());
+ return std::unique_ptr<Architecture>(
+ new ArchitecturePPC64(arch.GetByteOrder()));
return nullptr;
}
@@ -60,3 +61,7 @@ void ArchitecturePPC64::AdjustBreakpointAddress(const Symbol &func,
addr.SetOffset(addr.GetOffset() + loffs);
}
+
+lldb::ByteOrder ArchitecturePPC64::GetVectorElementOrder() const {
+ return m_vector_element_order;
+}
diff --git a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
index 80f7f27b54cce..9a0edf371d539 100644
--- a/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
+++ b/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
@@ -30,9 +30,14 @@ class ArchitecturePPC64 : public Architecture {
void AdjustBreakpointAddress(const Symbol &func,
Address &addr) const override;
+ lldb::ByteOrder GetVectorElementOrder() const override;
+
private:
static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
- ArchitecturePPC64() = default;
+ ArchitecturePPC64(lldb::ByteOrder vector_element_order)
+ : m_vector_element_order(vector_element_order) {}
+
+ lldb::ByteOrder m_vector_element_order;
};
} // namespace lldb_private
|
Is there some text missing here? |
I can confirm that AArch64 Neon and SVE work as stated:
Do we know what vector extension s390x/SystemZ has and what order it uses? |
Oops, fixed it.
I don't know but I've found bytecodealliance/wasmtime#4566 so @uweigand might be able to confirm. The first section seems to be describing the ARM/MIPS behaviour where the element order in the ISA remains the same regardless of the endianness of the elements themselves . I don't see any of the required shuffling bitcasts in lib/Target/SystemZ for that behaviour though. That thread goes on to mention implementing all four combinations so it might be configurable |
As I described in the wasmtime issue linked above, there is both an ISA and an ABI issue here. From an ISA perspective, SystemZ has vector registers, and instructions that operate on numbered lanes of the vector register if interpreted in a particular type (like Now, the default vector load/store instructions on SystemZ operate in a fashion where those lane numbers correspond to array indices in memory. That is, if you load an array However, given the big-endian nature of the platform, the behavior is still different from Intel or ARM if you then re-interpret that same vector register in a different type. In the example above, if you were to re-interpret this register loaded from an array of four For wasmtime, this was a problem as this violates an assumption of WebAssembly semantics, where the little-endian behavior is required. In order to support this on SystemZ, we use the trick of loading vector values from memory in reverse element order, so that in the above example, you would find In effect, this creates a variant ABI where vectors are always held in reverse order in vector registers. However, this is not used by LLVM at all - only WebAssembly requires this variant ABI. So in a nutshell, as far as LLVM is concerned, SystemZ behaves the same as Intel or ARM w.r.t. lane numbers. |
Thanks. I think the overall conclusion w.r.t this PR is that the default element-order value is ok for SystemZ for both Webassembly and C++. For C++: In the case where the user types something like For Webassembly we get the right outcome for different reasons. I'd expect the language plugin to correctly use the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is required for the parent PR and that PR is eventually approved, this LGTM.
Please add System Z to the listed systems in the PR description. That detail may come in handy one day.
Some targets like PowerPC store their vector elements in an endian-dependent order while others use the same order regardless of endianness:
This matters when LLVM-IR values are transferred to/from target memory since LLVM-IR orders elements 0, 1, 2, ... regardless of endianness.
This will be used in #155000 by changes to the IRInterpreter to allow it to evaluate some vectors without executing on the target