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))])

Reply via email to