https://llvm.org/bugs/show_bug.cgi?id=27320
Bug ID: 27320 Summary: [AVX2] vpermd + vpshufb intrinsics merged into wrong code at -O1 and higher Product: new-bugs Version: 3.8 Hardware: PC OS: Linux Status: NEW Severity: normal Priority: P Component: new bugs Assignee: unassignedb...@nondot.org Reporter: pe...@cordes.ca CC: llvm-bugs@lists.llvm.org Classification: Unclassified clang 3.8 (but not clang 3.7.1) mis-compiles a sequence of two shuffles. (Background: http://stackoverflow.com/questions/36327100/complex-data-reorganization-with-vector-instructions) __m256i doubleshuff(__m256i in) { const __m256i byteshuf = ...; const __m256i lane_adjust_shuf = ...; in = _mm256_permutevar8x32_epi32(in, lane_adjust_shuf); return _mm256_shuffle_epi8(in, byteshuf); } clang 3.8.1-svn265380-1~exp1 (from llvm repo for Ubuntu 15.10) compiles that to (with -O3 -march=haswell): vmovdqa ymm0, ymmword ptr [rip + .LCPI3_0] # ymm0 = [0,1,2,2,3,4,5,5] vpshufb ymm0, ymm0, ymmword ptr [rip + .LCPI3_1] # ymm0 = ymm0[0,1,1,2,3,4,4,5,6,7,7,8,9,10,10,11,28,29,29,30,31,16,16,17,18,19,19,20,21,22,22,23] ret which is obviously wrong because it doesn't depend on the input. It's shuffling the vpermd shuffle mask instead of shuffling the input. gcc 5.2 emits: vmovdqa ymm1, YMMWORD PTR .LC7[rip] vpermd ymm0, ymm1, ymm0 vpshufb ymm0, ymm0, YMMWORD PTR .LC8[rip] ret I created a test-case that exits with true or false status, suitable for testing with git bisect. (I don't have a checkout of the clang tree myself, or a fast machine). test-case: #include <immintrin.h> #include <assert.h> #include <string.h> __m256i doubleshuff(__m256i in) { const __m256i byteshuf = _mm256_setr_epi8(0,1,1,2, 3,4,4,5, 6,7,7,8, 9,10,10,11, 0,1,1,2, 3,4,4,5, 6,7,7,8, 9,10,10,11); // or broadcast128 const __m256i lane_adjust_shuf = _mm256_setr_epi32(0,1,2,2, 3,4,5,5); // const __m256i lane_adjust_shuf = _mm256_cvtepu8_epi32(_mm_setr_epi8(0,1,2,2, 3,4,5,5, // /* unused padding that isn't optimized away :( */ 0,0,0,0, 0,0,0,0)); in = _mm256_permutevar8x32_epi32(in, lane_adjust_shuf); return _mm256_shuffle_epi8(in, byteshuf); } static unsigned char dst[33]; static const unsigned char src[33] = "ABCDEFGHIJKL" "abcdefghijkl" "XXXXXXXX"; static const unsigned char good_output[33] = "ABBCDEEFGHHIJKKL" "abbcdeefghhijkkl"; // return false if result doesn't match int shuffle_test(void) { __m256i srcv = _mm256_loadu_si256((const __m256i*)src); __m256i expanded = doubleshuff(srcv); _mm256_storeu_si256((__m256i*)dst, expanded); return !memcmp(dst, good_output, 32); } int main(int argc, char**argv) { int test_passed = shuffle_test(); // assert(test_passed); return !test_passed; } See also this code and a bigger loop using it on godbolt: https://godbolt.org/g/nJqyJc -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs