https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93418
Bug ID: 93418 Summary: GCC incorrectly constant propagates _mm_sllv/srlv/srav Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: regression Assignee: unassigned at gcc dot gnu.org Reporter: husseydevin at gmail dot com Target Milestone: --- Regression starting in GCC 9 Currently, GCC constant propagates the AVX2 _mm_sllv family with constant amounts to only shift by the first element instead of all elements individually. #include <immintrin.h> #include <stdio.h> // force -O0 __attribute__((__optimize__("-O0"))) void unoptimized() { __m128i vals = _mm_set1_epi32(0xffffffff); __m128i shifts = _mm_setr_epi32(16, 31, -34, 3); __m128i shifted = _mm_sllv_epi32(vals, shifts); printf("%08x %08x %08x %08x\n", _mm_extract_epi32(shifted, 0), _mm_extract_epi32(shifted, 1), _mm_extract_epi32(shifted, 2), _mm_extract_epi32(shifted, 3)); } // force -O3 __attribute__((__optimize__("-O3"))) void optimized() { __m128i vals = _mm_set1_epi32(0xffffffff); __m128i shifts = _mm_setr_epi32(16, 31, -34, 3); __m128i shifted = _mm_sllv_epi32(vals, shifts); printf("%08x %08x %08x %08x\n", _mm_extract_epi32(shifted, 0), _mm_extract_epi32(shifted, 1), _mm_extract_epi32(shifted, 2), _mm_extract_epi32(shifted, 3)); } int main() { printf("Without optimizations (correct result):\t"); unoptimized(); printf("With optimizations (incorrect result):\t"); optimized(); } I would expect this code to emit the following: Without optimizations (correct result): ffff0000 80000000 00000000 fffffff8 With optimizations (incorrect result): ffff0000 80000000 00000000 fffffff8 Clang and GCC < 9 exhibit the first output, but 9.1 and later However, I get this output on GCC 9 and later: Without optimizations (correct result): ffff0000 80000000 00000000 fffffff8 With optimizations (incorrect result): ffff0000 ffff0000 ffff0000 ffff0000 Godbolt link: https://gcc.godbolt.org/z/oC3Psp