Is it possible to access internal values in a __m128 variable as attribute in a C++ class?

__has_attribute
gcc neon intrinsics example
gcc sse2
clang vector
c++ sse2
vectorizing code using simd intrinsics
gcc simd example
gnu __extension__

I would like to have a Vector class (which represents vector of 3 floats) implemented with SSE intrinsics (so I will not use the 4th elements of the __m128 type). But I would like to be able to access them easily like attributes : so myVector.x will access the 0-31 bits in vec, myVector.y will access the 32-63 bits in vec, but without having to call some getX() method. The 'x' attribute would be a sort of alias for the 0-31 bits of 'vec'. Is it possible ?

class Vector {  
public:  
  float x;  
  float y;  
  float z;  
private:  
  __m128 vec;  
}

No, because this violates the strong aliasing rule.

Sure you can use casts or unions to pretend the __m128 is an array of floats, but the optimizer will not maintain coherency for you, because you're breaking the language's rules.

See What is the strict aliasing rule?

(According to the rule, access using a union is safe, but that only applies when you are naming the union. Taking a pointer or reference to a union member and then using the pointer or reference directly later is not safe.)

Frequent 'attributes' Questions - Page 20, Is it possible to access internal values in a __m128 variable as attribute in a C++ class? c++ arrays attributes � Mar 29 '19 at 15:26 chtz. 3. 1� When you create an attribute class, by default, C# will allow you to use that attribute on any of the possible attribute targets. If you want to restrict your attribute to certain targets, you can do so by using the AttributeUsageAttribute on your attribute class. That's right, an attribute on an attribute!

You could perhaps use a union, something like

union data
{
    float[4] xyz;
    __m128 vec;
} aVec;

Then the floats would be aVec.xyz[0], aVec.xyz[1], and aVec.xyz[2] and the __m128 would be aVec.vec. The float array has four elements here, but nothing says you have to use the fourth one.

Vector Extensions (Using the GNU Compiler Collection (GCC)), For example, if you specify a variable of type V4SI and your architecture does not allow for typedef int v4si __attribute__ ((vector_size (16))); v4si a, b, c; c = a + b ; are the negative or complemented values of the corresponding elements in the operand. It is possible to use shifting operators << , >> on integer-type vectors . A variable is nothing but a name given to a storage area that our programs can manipulate. Each variable in C has a specific type, which determines the size and layout of the variable's memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.

You can write a struct which automatically converts to and from __m128:

struct alignas(16) Vec4f
{
    float x, y, z, w;
    operator __m128() const { return _mm_load_ps(&x);}
    Vec4f(__m128 const v) { _mm_store_ps(&x, v);}
};

This has the disadvantage that Vec4f would be passed via two SSE registers instead of one (when passed by value: https://godbolt.org/z/sutmuM).

Overall, I'd suggest to rather make a struct which just contains an __m128 and overload x(), y(), etc methods. Element-wise operations on SSE registers should be avoided anyway if possible (except using the zeroth element).

N.B.: alignas(16) requires C++11, there are compiler-specific alternatives for most compilers. Alternatively, you can use _mm_loadu_ps and _mm_storeu_ps instead.

[PDF] Vector Intrinsics, and change the source) to POWER using C language vector typedef float __ m128 __attribute__ ((__vector_size__ (16), __may_alias__)); GCC will compile code with other __vector_size__ values, but the resulting types are treated Internal data types for implementing the AVX in PowerISA intrinsics. In this case, the modifier is an access modifier. The “variable Modifiers” section will discuss class member access modifiers. The data type refers to the type of value a variable can store. The identifier is the name of variable.

[PDF] Vectorization with Expression Templates, possible waste of longer registers typedef int v4si __attribute__ ((vector_size ( 16))); c = a + b;. // load from unaligned array float x[4] = {1.0, 2.0, 3.0, 4.0};. __ m128 b well suited for vectorization especially if you often access we can replace the internal variables into a SIMD register, and then reading its value . Variables represent storage locations. Every variable has a type that determines what values can be stored in the variable. C# is a type-safe language, and the C# compiler guarantees that values stored in variables are always of the appropriate type. The value of a variable can be changed through assignment or through use of the ++ and --operators.

Index: lib/Headers/pmmintrin.h , \param __p /// A pointer to a 128-bit integer vector containing integer values. __ inline__ __m128 __DEFAULT_FN_ATTRS _mm_addsub_ps(__m128 __a, __ m128 attributes only apply to instance // variables or properties of Objective-C classes. attributes are the only attributes allowed after an access // specifier. bool� Function attributes are introduced by the __attribute__ keyword in the declaration of a function, followed by an attribute specification enclosed in double parentheses. You can specify multiple attributes in a declaration by separating them by commas within the double parentheses or by immediately following one attribute specification with another.

Cannot access __m128 union members, error generated � Issue , Cannot access __m128 union members, error generated #4279 its member, for example qs4.m128_f32[1] , where qs4 is __m128 variable, I get The internal structure of __m128 is implementation-specific and there's no� The xsl:variable instruction creates a variable. Its name attribute identifies the variable's name, and the value can be specified either as the xsl:variable element's contents (like the "10pt" in the example) or as the value of an optional select attribute in the xsl:variable element's start-tag.

Comments
  • It may be using union :)
  • Be careful with unions in this case: Microsoft says, you should not access __m128 variables directly: msdn.microsoft.com/ru-ru/library/ayeb3ayc.aspx
  • How the __m128 and the associated SSE instructions can be useful if you can't access the values of the floats contained in it ?
  • @Guillaume: SSE provides store instructions that extract the data to an array of float. See msdn.microsoft.com/en-US/library/ybhzf6dk.aspx You should use these store instructions to access components of the __m128 value, and not try to access its memory directly.
  • Won't this destroy the efficiency gained by the use of the SSE instructions ?
  • @Guillaume: Design things so you don't convert to and from SSE more often than necessary. And actually the SSE load/store instructions are about the most efficient memory access method available. Still, SSE register access is faster, so try to keep things inside SSE as long as possible.
  • Shouldn't the answer be something like: "Yes, you can but you shouldn't because this would violate strong aliasing rule" ?
  • @VJovic Are unions an exception to the strict aliasing rule? I'm using unions each time i need to access the same memory with different interpretation and its working fine with GCC.
  • @VJovic Also i found this in the working draft of the c++ standard: If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them.
  • Is the union construction something that should be avoided, but which in fact works with GCC, or bugs can really happen when the program is compiled with full optimization ?
  • @Gigi: I elaborated on that at the end of my answer.
  • Using g++, you can simply add --fno-strict-aliasing and this would work just fine. Given that __m128 isn't exactly part of the standard, maybe platform- and tool-specific answers are just fine here.