tree_pair types = direct_internal_fn_types (fn, res_op->type,
res_op->ops);
if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
- return NULL;
+ {
+ switch (fn)
+ {
+ case IFN_CLZ:
+ case IFN_CTZ:
+ case IFN_CLRSB:
+ case IFN_FFS:
+ case IFN_POPCOUNT:
+ case IFN_PARITY:
+ /* For these 6 builtins large/huge _BitInt operand is ok
+ before bitint lowering pass. */
+ if (res_op->num_ops >= 1
+ && TREE_CODE (TREE_TYPE (res_op->ops[0])) == BITINT_TYPE
+ && (TYPE_PRECISION (TREE_TYPE (res_op->ops[0]))
+ > MAX_FIXED_MODE_SIZE)
+ && cfun
+ && (cfun->curr_properties & PROP_gimple_lbitint) == 0)
+ break;
+ return NULL;
+
+ default:
+ return NULL;
+ }
+ }
}
return gimple_build_call_internal (fn, res_op->num_ops,
res_op->op_or_null (0),
/* parity(X)^parity(Y) is parity(X^Y). */
(simplify
(bit_xor (PARITY:s @0) (PARITY:s @1))
- (PARITY (bit_xor @0 @1)))
+ (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1)))
+ (PARITY (bit_xor @0 @1))
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ (with { tree utype = TREE_TYPE (@0);
+ if (TYPE_PRECISION (utype) < TYPE_PRECISION (TREE_TYPE (@1)))
+ utype = TREE_TYPE (@1); }
+ (PARITY (bit_xor (convert:utype @0) (convert:utype @1)))))))
#if GIMPLE
/* parity(zext(X)) == parity(X). */
--- /dev/null
+/* PR tree-optimization/112719 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O2" } */
+
+#if __BITINT_MAXWIDTH__ >= 252
+int
+foo (unsigned _BitInt(239) x, unsigned _BitInt(252) y)
+{
+ x &= 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauwb;
+ y &= 0x555555555555555555555555555555555555555555555555555555555555555uwb;
+ return __builtin_popcountg (x) + __builtin_popcountg (y);
+}
+
+int
+bar (unsigned _BitInt(239) x, unsigned _BitInt(252) y)
+{
+ return __builtin_parityg (x) ^ __builtin_parityg (y);
+}
+#endif