https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118480
--- Comment #6 from Jeevitha <jeevitha at gcc dot gnu.org> --- For the following case: vui8_t test_splat7_char_18 () { return vec_splats((unsigned char)18); } Assembly output: test_splat7_char_18: xxspltib 34,9 vaddubm 2,2,2 blr The compiler generates xxspltib, but it does not believe that the immediate value 18 fits directly into the instruction's immediate field. This is true for the vspltisb instruction, but not for xxspltib. What’s happening in the above scenario is that the value gets split using the following split pattern, which is valid for vspltis* but not for xxsplti*. This happens because the macro easy_vector_constant_add_self returns true. For vspltis*, only immediates in the range [-16, 15] are directly supported. For a value like 18 (which lies outside this range), the compiler transforms it using the expression n/2 = 9, and then adds the result to itself—thus generating the constant indirectly. However, xxspltib can handle the value 18 directly. So, for the Power9 target, we should avoid entering this split path. When the instruction is not split, we correctly see: xxspltib 34,18 split pattern: "altivec.md" (define_split [(set (match_operand:VM 0 "altivec_register_operand") (match_operand:VM 1 "easy_vector_constant_add_self"))] "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed" [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))])