Skip to content

Misaligned member variables of templated SIMD types (like __m128) when using /Zp flag with clang-cl #134694

Open
@januszn

Description

@januszn

Given the following source:

#include <cstddef>
#include <type_traits>
#include <xmmintrin.h>

// __m128 is defined as the following in clang's xmmintrin.h:
// typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));

template<typename T>
using MyVectorRegisterType = std::conditional_t<std::is_same_v<T, float>, __m128, void >;

struct STemplated
{
    int I;
    MyVectorRegisterType<float> V;

    size_t M()
    {
        static_assert(offsetof(STemplated, V) % alignof(decltype(V)) == 0, "STemplated::V is misaligned");
        return offsetof(STemplated, V);
    }
};

struct SDirect
{
    int I;
    __m128 V;

    size_t M()
    {
        static_assert(offsetof(SDirect, V) % alignof(decltype(V)) == 0, "SDirect::V is misaligned");
        return offsetof(SDirect, V);
    }
};

int main()
{
    STemplated ST;
    SDirect SD;
    return (int)ST.M() + (int)SD.M();
}

...clang-cl misaligns the STemplated::V member variable when using /Zp8:

D:\work>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34809 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

D:\work>clang-cl --version
clang version 19.1.1
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\Llvm\x64\bin

D:\work>cl test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34809 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
Microsoft (R) Incremental Linker Version 14.43.34809.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test.exe
test.obj

D:\work>clang-cl test.cpp

D:\work>cl /Zp8 test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34809 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
Microsoft (R) Incremental Linker Version 14.43.34809.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test.exe
test.obj

D:\work>clang-cl /Zp8 test.cpp
test.cpp(19,17): error: static assertion failed due to requirement '__builtin_offsetof(STemplated, V) % alignof(__attribute__((__vector_size__(4 * sizeof(float)))) float) == 0': STemplated::V is misaligned
   19 |                 static_assert(offsetof(STemplated, V) % alignof(decltype(V)) == 0, "STemplated::V is misaligned");
      |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\Llvm\x64\lib\clang\19\include\__stddef_offsetof.h(16,24): note: expanded from macro 'offsetof'
   16 | #define offsetof(t, d) __builtin_offsetof(t, d)
      |                        ^
test.cpp(19,64): note: expression evaluates to '8 == 0'
   19 |                 static_assert(offsetof(STemplated, V) % alignof(decltype(V)) == 0, "STemplated::V is misaligned");
      |                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
1 error generated.

A similar issue was previously reported in #44765 , with a fix for the SDirect case above committed, but it seems the fix does not work if the type with alignment requirements is wrapped in a template. I tested the issue on Clang versions 16, 18, 19 and 20. The minimal example is adapted from code in a popular AAA game engine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang-cl`clang-cl` driver. Don't use for other compiler parts

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions