https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86731
Bug ID: 86731 Summary: [8 Regression] Miscompiles vec_sl at -O3 with -fwrapv on ppc64el Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: jcowgill+gcc at jcowgill dot uk Target Milestone: --- FFmpeg was hit by a bug which causes strange results when the optimized altivec routines are compiled with -O3 and -fwrapv (which is used when FFmpeg is configured with --toolchain=hardened). This bug only occurs with GCC 8. Simplified extract which shows the bug: #include <altivec.h> vector unsigned int splat(void) { vector unsigned int mzero = vec_splat_u32(-1); return (vector unsigned int) vec_sl(mzero, mzero); } The goal is to create a constant vector with each element containing 0x80000000 (== -0.0f). If I am reading the altivec manual correctly, the above code is valid because the second argument to vec_sl should interpreted modulo 32 (ie as 31 in this case). With gcc-7 this generates this correct code: 0000000000000000 <splat>: 0: 8c 03 5f 10 vspltisw v2,-1 4: 84 11 42 10 vslw v2,v2,v2 8: 20 00 80 4e blr When compiled with "gcc-8 -O3 -fwrapv -c altivectest.c" this wrong code is produced: 0000000000000000 <splat>: 0: 8c 03 5f 10 vspltisw v2,-1 4: 20 00 80 4e blr ==== If I pass -fdump-tree-all, I can see that the vec_sl gets transformed into a normal left shift. My guess (which may be wrong) is that gcc is treating this shift as UB because it is trying to shift > 32 bits.