https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119040
Bug ID: 119040 Summary: [PPC/Altivec] Missing bit-level optimization (select) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: wojciech_mula at poczta dot onet.pl Target Milestone: --- This come from real-world usage. Suppose we have a vector of words, we want to move around some bit-fields of that words. We isolate the bit-fields with `and` then shift the bit-fields to the desired positions in the final word. But we never end up with overlapping bit-fields. Below is a sample code that merges two 6-bit fields into 12-bit one in 32-bit elements: ---test.cpp--- #include <stdint.h> #include <altivec.h> using vec_u32_t = __vector uint32_t; vec_u32_t merge_2x6_bits(const vec_u32_t a, const vec_u32_t b) { vec_u32_t t0 = vec_and(a, vec_splats(uint32_t(0x003f))); vec_u32_t t1 = vec_and(b, vec_splats(uint32_t(0x3f00))); vec_u32_t t2 = vec_sr(t1, vec_splats(uint32_t(2))); return vec_or(t2, t0); } ---eof--- GCC 14.2.0 with flags `-O3 -maltivec` produces the following code (I omitted the constants .LC0 & .LC1): lis 10,.LC0@ha lis 9,.LC1@ha la 10,.LC0@l(10) la 9,.LC1@l(9) lvx 13,0,10 vspltisw 0,2 lvx 1,0,9 vand 3,3,13 vsrw 3,3,0 vand 2,2,1 vor 2,3,2 Since the bit-fields do not overlap, the last sequence of `vand` and `vor` can be replace with `vsel`. Instead of `((a & mask1) >> 2) | (b & mask2)` we may have `select(mask1 >> 2, a >> 2, b & mask2)` [providing the prototype of `select` is select(condition, true, false)].