<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/86793>86793</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            llvm::byteswap ignores alignment requirements
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          rorth
      </td>
    </tr>
</table>

<pre>
    The `MachOTest.UnalignedLC` test (`LLVM-Unit :: BinaryFormat/./BinaryFormatTests/11/193`) has been failing on and off in the past on Solaris/sparcv9.  However, since LLVM 18 the failure has become consistent, as I've just re-discovered:

* In a 1-stage build with `clang-17` as build compiler, the test `PASS`es.
* However, when switching the build compiler to `clang-18`, the test consistently `FAIL`s as I found when trying that `clang-17` to `clang-18` switch on the Solaris/sparcv9 buildbot.
* In a 2-stage build, the failure is consistent irrespective of build compiler.

The failure is like this:
```
GTEST_OUTPUT=json:/var/llvm/local-sparcv9-release-stage2-A-flang-clang18/tools/clang/stage2-bins/unittests/BinaryFormat/./BinaryFormatTests-LLVM-Unit-25980-11-193.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=193 GTEST_SHARD_INDEX=11 /var/llvm/local-sparcv9-release-stage2-A-flang-clang18/tools/clang/stage2-bins/unittests/BinaryFormat/./BinaryFormatTests
--

Note: This is test shard 12 of 193.
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MachOTest
[ RUN      ] MachOTest.UnalignedLC
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 BinaryFormatTests 0x0000000100180b4c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 36
1 BinaryFormatTests 0x00000001001814f4 SignalHandler(int) + 896
2  libc.so.1 0x00007fffff0c6410 __sighndlr + 12
3  libc.so.1 0x00007fffff0b8cb8 call_user_handler + 1024
4  libc.so.1 0x00007fffff0b9078 sigacthandler + 160
5  BinaryFormatTests 0x00000001000d1e00 MachOTest_UnalignedLC_Test::TestBody() + 48
6 BinaryFormatTests 0x00000001002383f8 testing::Test::Run() + 432
7 BinaryFormatTests 0x0000000100239ba4 testing::TestInfo::Run() + 484
8 BinaryFormatTests 0x000000010023abe4 testing::TestSuite::Run() + 1244
9 BinaryFormatTests 0x000000010024c778 testing::internal::UnitTestImpl::RunAllTests() + 2788
10 BinaryFormatTests 0x000000010024bb0c testing::UnitTest::Run() + 128
11 BinaryFormatTests 0x00000001002196dc main + 168
12 BinaryFormatTests 0x00000001000c82a4 _start + 100

--
exit: -10
```
With more debug info from a past build, there's
```
FAIL: LLVM-Unit :: BinaryFormat/./BinaryFormatTests/MachOTest.UnalignedLC (1755 of 68187)
******************** TEST 'LLVM-Unit :: BinaryFormat/./BinaryFormatTests/MachOTest.UnalignedLC' FAILED ********************
Note: Google Test filter = MachOTest.UnalignedLC
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MachOTest
[ RUN      ] MachOTest.UnalignedLC
0  BinaryFormatTests 0x0000000100269930 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 44
1 BinaryFormatTests 0x0000000100269d14 PrintStackTraceSignalHandler(void*) + 12
2  BinaryFormatTests 0x0000000100268bb4 llvm::sys::RunSignalHandlers() + 132
3  BinaryFormatTests 0x000000010026aa80 SignalHandler(int) + 216
4  libc.so.1         0xffffffff7eedc840 __sighndlr + 12
5 libc.so.1         0xffffffff7eecf27c call_user_handler + 852
6  libc.so.1 0xffffffff7eecf5d4 sigacthandler + 84
7  BinaryFormatTests 0x00000001001e228c void llvm::sys::swapByteOrder<unsigned int>(unsigned int&) + 8
8  BinaryFormatTests 0x00000001001dfdc4 llvm::MachO::swapStruct(llvm::MachO::mach_header&) + 4
9 BinaryFormatTests 0x00000001001dfc04 MachOTest_UnalignedLC_Test::TestBody() + 48
10 BinaryFormatTests 0x00000001002eeeb8 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) + 40
11 BinaryFormatTests 0x00000001002d8974 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) + 44
12 BinaryFormatTests 0x00000001002d8904 testing::Test::Run() + 164
13 BinaryFormatTests 0x00000001002d9204 testing::TestInfo::Run() + 212
14 BinaryFormatTests 0x00000001002d9a00 testing::TestCase::Run() + 216
15 BinaryFormatTests 0x00000001002de948 testing::internal::UnitTestImpl::RunAllTests() + 684
16 BinaryFormatTests 0x00000001002f0c64 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) + 40
17 BinaryFormatTests 0x00000001002de654 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) + 44
18 BinaryFormatTests 0x00000001002de58c testing::UnitTest::Run() + 148
19 BinaryFormatTests 0x00000001002d0ac4 RUN_ALL_TESTS() + 12
20 BinaryFormatTests 0x00000001002d0aa8 main + 136
21 BinaryFormatTests 0x00000001001d5fa4 _start + 100
```
The program dies with `SIGBUS` like so:
```
    Incurred fault #5, FLTACCESS  %pc = 0x1001E228C
 siginfo: SIGBUS BUS_ADRALN addr=0xFFFFFFFF7FFFE263
    Received signal #10, SIGBUS [default]
      siginfo: SIGBUS BUS_ADRALN addr=0xFFFFFFFF7FFFE263
```
i.e. the input operand isn't properly aligned:
```
Thread 2 received signal SIGBUS, Bus error.
[Switching to Thread 1 (LWP 1)]
0x00000001001e228c in void llvm::sys::swapByteOrder<unsigned int>(unsigned int&) ()
1: x/i $pc
=> 0x1001e228c <_ZN4llvm3sys13swapByteOrderIjEEvRT_+8>:        ld  [ %i0 ], %o0
(gdb) p/x $i0
$1 = 0xffffffff7fffe123
(gdb) where
#0 0x00000001001e228c in void llvm::sys::swapByteOrder<unsigned int>(unsigned int&) ()
#1  0x00000001001dfdcc in llvm::MachO::swapStruct(llvm::MachO::mach_header&) ()
#2 0x00000001001dfc0c in MachOTest_UnalignedLC_Test::TestBody() ()
```
SPARC being a strict-alignment target, natural alignment is required for all operands, so e.g. an `unsigned int` must be at least 2-byte aligned, which isn't the case here.

I think I ultimately traced this to `llvm::byteswap` being ignorant of this requirement.  Considering the call chain
```
  llvm/unittests/BinaryFormat/MachOTest.cpp (TEST(MachOTest, UnalignedLC))
  -> llvm/include/llvm/BinaryFormat/MachO.h (swapStruct)
 -> llvm/include/llvm/Support/SwapByteOrder.h (sys::swapByteOrder)
  -> llvm/include/llvm/Support/SwapByteOrder.h (sys::getSwappedBytes)
  -> llvm/include/llvm/ADT/bit.h (llvm::byteswap)
```
`llvm::byteswap` does nothing to deal with unaligned input.

While one could force the alignment in the testcase, its name (`UnalignedLC`) strongly suggests that it's exactly about the unaligned case, so that seems wrong.  Besides, `llvm::byteswap` needs to be robust irrespective of input IMO.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcWt1v4joW_2vSlyNQ4iQQHvpAocwgdT5U6N7d-4Kc5EA8N9is7bRl__rVcRIILS29d2alq42qTpr4_M73h-PhxoiNRLz24hsvnl7xyhZKX2ulbXGVqnx_vSwQvIH_hWfFtyUa23-QvCSa_G7iDXywaCx4LPEG_t3dP770HqSw4IVjLxzDjZBc72dKb7n12KzvsVn3EcEZj82CgH6NQm_ge2wEBTeQIkpYc1EKuQElgcsc1HoNQoItEHbcWHq8UCXXgjDMjuvscdQH-Kye8BG1xyZghMwQSCwIEkdIkJXGhkemtgiZkkYYi9ISCTcw99jwEeFHZSxo7OXCZOoRNeaklT_1_PY3G8NcAoegZyzfIKSVKHN4ErYgi2Ull5teMCQjETf3MlPbnShr6Uie2noD__t4sfAGPpr-EbujyFOBEsyTsFlBBiHKUzywqsMzcZbscDjqWO5p3Ww8v_MGvnHqwlpVMq95WL2vGXD7UodXHBqByA_E6JUvahFTZfsv7MW69mrlbD0jTEdaEFqj2WFmxSOCWr_Qut91x_IUpBR_INhCmKPXBn7z4_78tLxdLFffHpbfH5ZeOP1hlKSlbPbItcdmZfm4pX9Uxsteo1FPY4ncYC0_6417a2cOZ5Qg8djMKlWSCdwTMkW9MBWSnlZSWNsE_Udyo3fIqB6LR4nfC4JeMAr7JCvU8i8-P8xmd7deOPWbJ8tvy_HdavF5fD9deOE0GIWHpeP76Wr-dXr7T3oewN9K19opvV7XpV-VRaojy0IY8qmLZVNwnUPAKBzIGA1BfOOF0_d-4incV1JSeAc10lqrbXtvKmHxiNU7XET3qVQpL-uFKB-FVnJL0WnQ9qrdW1RdLofyeVgL9w9fwV209nx5dWsXlmd_QF5td660qMqC2W9TVYLkWzRUe1Eaivq9qqDgjwjkz169SPwHNVXNvao0fB8vP4PSJLfLua4uj1xDU8NXi399ufl2N__99n5FJE3275SQlm6E9djokFY-vPIl-M9-fQW-HyR-GmVOprotmL2pb75rIa1Tb6l5hh5Ljos0f1opYzXyrccGVCQEFegReOwGwkHNOrjIOojWESzERvLyM5e5q7xJBykZNVAMoBRp1jeqHzQYwzVdfjaIAh9WKyM2hcxL7egCVpOFb5KlSZYmkPGyXFUG9aqo2dfUPotq-uht-pE_TMCIDc_sCW1bv2K4oL2fB-j7x9BadUJr5WLRWZrublS-px7eWCVKahaDCxxYmITrxIW5kJsjXH13X8kuZtiYbHgRdJTy6DXoXK7VWeCksWVyEZineAZ4Qal_DjlgUQM9ugQdZcPhC0MIaVFLXtZ_URF3Wmx35YHXuCybGejAkw2TxvjBpcRiUZr62SnTls15dVrkS3nDgtEgz2DLhWxirqVkl2IuSxiPYGUs17aJdb9b0tsCj8-ChIRe4J_tzr_RFLVVGiHHtNqAkGtVl1JeT3_d4UGjx4bmLI6bdMIx_NXZ9GxhppobDOOYWtAgCZIh1cN2xvnLP0BdGjw2_KWyemwIZITbKfyMcKcN-ZNSmxJh6fqbKC3VpvDdLvaz_Tnj5u_Znv1LZZgNRqPQ_9n-19S66GONjw1GeRDBCwYv--CjErnz7uikp7HLGiVpGp3T6L6SJ0y6lS0Ijz3zEj7nif9e22bB4Ez_bC__ed1cQ8Q8S6I323d8iTpbs2H2RhdPYta2yZMmfkIe59GZJt62rOElUwTIWJIBeeqcvc0T393sLX7TOWovnFTSbedzNyyFtx5LTp4cAylpW-Yl_vk6z7qudplwZL6wusrsSeR2Vmx5VqwK5CRcJ4g_1lODfJ350c-ML5c7KCKmSW3dd3p3HYILLG6fM9xZoaSZyy9oC5XP14tqt1PaYu6Fk9eDEJs49NoXZ16P2xVw9r27q1O01o-WZwXXbo9sO8kb-R_t7XkyGkYf1PnvrHD0wZGEFPbPjH1nR6RBixpeRB2xc6hvTamsLTlBdBmZ-_5r5Ak3Z6fUQy0M4ovIOIp-yZQ6aAtYcHGL4DZQkCpV_voUe0d4NnE8z8The0Tjlu5VdF6y059L0ot7oBwH8Uet9v9tsjbQLu7ucoyTP7MbOnSJi5u73OdZRAPhanx3t6IpfXGyrWrGpovdJvc5Tzq7qvYzBrv4HSOP12_tqk63O8sCYafVRvMt5ALN4Wv0Yv7p5mHhDfz6w6hRb30WpRFoLrNKa8xhzauSGIYxOWh2txxPJreLBYDH4l3mZn7_mQS8ZSxpBmIad0RdBaHmCjcPi9V4ej---wo8z7UXTv3nWXMNZ7PZLRuER-73mKF4xJyAJKe4CgP3ObtB8-KbHJ1kXjw9ksFPMX5hBdHHvvtEJuSusqB2qLnMQRjpsaElE-9Ql3toJpK3jLksNPIcGOgXOjXuYBO4qQyg1kof9ymL44d-BQ1EQOl199t3CChbWr3PjIpC_uppMTnsbgMy7bPHZgI8Fu2yRmLav902gVAL4YWT1e9fI5IhNHsThCes5z9ubx_vlyuP3STEl4w3KnPaat1QZAmfNl1kHI_Fqg10lmzylCTaeWz2TAKIw6soaGLxMHuv12sMWPiS9sl9LGgehv65Wft_aUAKZXg9YDumv3DGPmHIXk_Vjt-fHqw7qKdRvvg-vp9AihSxHIzVIrM9B-m24ZbrDbrJUHJbaV7C8Z0woPHflXDFRmngZdkmm3EneAqwv-kDl1TETqw78GFbGQspArdQIjcWWC_dWzxkpTs5E1lxyFvK6IwbBAqDk9OjOdhCyD9gDlVpxZZbLPdgadecu1Ok5vjr6AJiRN4hOWrVxUYqzaUFta5JGs1I0T7AREkjctTtAR5tKqnnCflGHW5OZd45SDl-lsh2O_IQ9SaPJcfPGWwCJ9-CRgcfAvQoaxsmQmZllePxLOgcp35BPLoh2WK9C9XMInTXzZ8G7XxufVDKj0Fv0NLrHea0wnwUfDxdemyWClvDnXH9G_nwZpzkCg1IZdvaniMv6w5dtU6qG85JaP5WiBJBSYRMVaXLkwxdCHXySB4Oeym-3XmJNe6EqDmcPz22p4w2Viu5Kfdgqs3GzRzu2FdYjw0N4DPPLHW4VFV14hxlbFkYVZMYxK2BJ4LrA9wgxblL3zctIRFzl1MpglYp5fHLo966886_fOtf5ddhPgpH_Aqvg2EQxFEQDIOr4nrE4tgfrONglCVBEPIoDHEYh0E8ZHnMuX8lrpnPIj9kw4D5g8Dv48Bfr8MoDWIe5mEaepGPWy7KPonZV3pzJYyp8DoZDEfhVclTLI37vxGMSXwC99JjzIunV_raHbOl1cZ4kV8KY80RxQpb4vVr3esigabjuk6VMFeVLq8La3emPor22GwjbFGl_UxtOwe1xHin1Q-kJJw5qag8OKn_GwAA__9fvjZ4">