@@ -4195,9 +4195,11 @@ (define_insn "*p8v_popcount<mode>2"
[(set_attr "type" "vecsimple")])
;; Vector parity
-(define_insn "*p9v_parity<mode>2"
- [(set (match_operand:VParity 0 "register_operand" "=v")
- (parity:VParity (match_operand:VParity 1 "register_operand" "v")))]
+(define_insn "parityb<mode>2"
+ [(set (match_operand:VEC_IP 0 "register_operand" "=v")
+ (unspec:VEC_IP
+ [(match_operand:VEC_IP 1 "register_operand" "v")]
+ UNSPEC_PARITY))]
"TARGET_P9_VECTOR"
"vprtyb<wd> %0,%1"
[(set_attr "type" "vecsimple")])
@@ -2666,13 +2666,13 @@
VMSUMUDM altivec_vmsumudm {}
const vsll __builtin_altivec_vprtybd (vsll);
- VPRTYBD parityv2di2 {}
+ VPRTYBD paritybv2di2 {}
const vsq __builtin_altivec_vprtybq (vsq);
- VPRTYBQ parityv1ti2 {}
+ VPRTYBQ paritybv1ti2 {}
const vsi __builtin_altivec_vprtybw (vsi);
- VPRTYBW parityv4si2 {}
+ VPRTYBW paritybv4si2 {}
const vsll __builtin_altivec_vrldmi (vsll, vsll, vsll);
VRLDMI altivec_vrldmi {}
@@ -1226,7 +1226,16 @@ (define_expand "popcount<mode>2"
(define_expand "parity<mode>2"
[(set (match_operand:VEC_IP 0 "register_operand")
(parity:VEC_IP (match_operand:VEC_IP 1 "register_operand")))]
- "TARGET_P9_VECTOR")
+ "TARGET_P9_VECTOR"
+{
+ rtx op1 = gen_lowpart (V16QImode, operands[1]);
+ rtx res = gen_reg_rtx (V16QImode);
+ emit_insn (gen_popcountv16qi2 (res, op1));
+ emit_insn (gen_parityb<mode>2 (operands[0],
+ gen_lowpart (<MODE>mode, res)));
+
+ DONE;
+})
;; Same size conversions
@@ -105,3 +105,4 @@ parity_ti_4u (__uint128_t a)
/* { dg-final { scan-assembler "vprtybd" } } */
/* { dg-final { scan-assembler "vprtybq" } } */
/* { dg-final { scan-assembler "vprtybw" } } */
+/* { dg-final { scan-assembler-not "vpopcntb" } } */
new file mode 100644
@@ -0,0 +1,42 @@
+/* { dg-run } */
+/* { dg-options "-O2 -ftree-vectorize -fno-vect-cost-model" } */
+
+#define N 16
+
+unsigned long long vals[N];
+unsigned int res[N];
+unsigned int expects[N] = {0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+unsigned long long inputs[N]
+ = {0x0000000000000000ULL, 0x0000000000000001ULL, 0x8000000000000000ULL,
+ 0x0000000000000002ULL, 0x4000000000000000ULL, 0x0000000100000000ULL,
+ 0x0000000080000000ULL, 0xa5a5a5a5a5a5a5a5ULL, 0x5a5a5a5a5a5a5a5aULL,
+ 0xcafecafe00000000ULL, 0x0000cafecafe0000ULL, 0x00000000cafecafeULL,
+ 0x8070600000000000ULL, 0xffffffffffffffffULL};
+
+__attribute__ ((noipa)) void
+init ()
+{
+ for (int i = 0; i < N; i++)
+ vals[i] = inputs[i];
+}
+
+__attribute__ ((noipa)) void
+do_parity ()
+{
+ for (int i = 0; i < N; i++)
+ res[i] = __builtin_parityll (vals[i]);
+}
+
+int
+main (void)
+{
+ init ();
+ do_parity ();
+ for (int i = 0; i < N; i++)
+ if (res[i] != expects[i])
+ __builtin_abort();
+
+ return 0;
+}
+