Skip to content

Conversation

dsandersllvm
Copy link
Collaborator

@dsandersllvm dsandersllvm commented Sep 5, 2025

Some targets like PowerPC store their vector elements in an endian-dependent order while others use the same order regardless of endianness:

  • 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 #155000 by changes to the IRInterpreter to allow it to evaluate some vectors without executing on the target

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
@llvmbot
Copy link
Member

llvmbot commented Sep 5, 2025

@llvm/pr-subscribers-lldb

Author: Daniel Sanders (dsandersllvm)

Changes

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 #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:

  • (modified) lldb/include/lldb/Core/Architecture.h (+11)
  • (modified) lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp (+6-1)
  • (modified) lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h (+6-1)
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 &reg_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

@Michael137 Michael137 changed the title [lldb] Architecture plugins should report the vector element order. NFC [lldb][NFC] Architecture plugins should report the vector element order Sep 7, 2025
@Michael137
Copy link
Member

Some targets like PowerPC store their

Is there some text missing here?

@DavidSpickett
Copy link
Collaborator

DavidSpickett commented Sep 8, 2025

I can confirm that AArch64 Neon and SVE work as stated:

B2.9.3.2 Endianness in SIMD operations

...The four elements appear in the register in array order, with the
lowest indexed element fetched from the lowest address. The order of bytes in the elements depends on the endianness
configuration, as shown in Figure B2-3. Therefore, the order of the elements in the registers is the same regardless of the
endianness configuration
.

B2.9.3.3 Endianness in SVE operations

Rules on byte and element order of SIMD load and store instructions apply to SVE load and store instructions.

Do we know what vector extension s390x/SystemZ has and what order it uses?

@dsandersllvm
Copy link
Collaborator Author

Some targets like PowerPC store their

Is there some text missing here?

Oops, fixed it.

Do we know what vector extension s390x/SystemZ has and what order it uses?

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants