https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62191
Bug ID: 62191 Summary: extra shift generated for vector integer division by constant 2 Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: spatel at rotateright dot com Using gcc 4.9: $ cat sdiv.c typedef int vecint __attribute__((vector_size(16))); vecint f(vecint x) { return x/2; } $ gcc -O2 sdiv.c -S -o - ... movdqa %xmm0, %xmm1 psrad $31, %xmm1 <--- splat the sign bit psrld $31, %xmm1 <--- then shift sign bit down to LSB paddd %xmm1, %xmm0 <--- add sign bit to quotient psrad $1, %xmm0 <--- div via alg shift right ret -------------------------------------------------------------- I don't think the first shift right algebraic is necessary. We splat the sign bit and then shift that right logically, so the upper bits are all zero'd anyway. This is a special case for signed integer division by 2. You need that first 'psrad' for any other power of 2 because the subsequent logical shift would not also be a shift of 31.