If you try casting your pointer to (__m128i *) and dereferencing, sometimes the compiler will optimize it correctly (to PMOVSXBD with a memory operand, which really only loads 4 bytes), and sometimes (for example, when optimizations are disabled) it will emit MOVDQA, which does a 16-byte aligned load. Tools like UBSan will also (correctly) complain about it.
Eventually __mm_loadu_epi32() was added, but it was released in a broken state in the initial gcc implementation: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99754 so you can't rely on it. There is __mm_load_ss(), but gcc's implementation derefs a (float *), so it still requires 4-byte alignment: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84508
The workarounds described in the article (combined with _mm_cvtsi32_si128()) are the only reliable solution I have found. Various compilers still generate an extra MOVD instruction instead of using a memory operand, and reportedly ICC will even do an extra load into a general-purpose register before moving the value to a SIMD register: https://stackoverflow.com/questions/72837929/mm-loadu-si32-n...
Those extra moves are cheap on x86, so it is not the end of the world, but the whole situation is less than ideal.