--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+unsigned short test_bswap16(unsigned short x)
+{
+ return x ? __builtin_bswap16(x) : 0;
+}
+
+unsigned int test_bswap32(unsigned int x)
+{
+ return x ? __builtin_bswap32(x) : 0;
+}
+
+unsigned long long test_bswap64(unsigned long long x)
+{
+ return x ? __builtin_bswap64(x) : 0;
+}
+
+int test_clrsb(int x)
+{
+ return x ? __builtin_clrsb(x) : (__SIZEOF_INT__*8-1);
+}
+
+int test_clrsbl(long x)
+{
+ return x ? __builtin_clrsbl(x) : (__SIZEOF_LONG__*8-1);
+}
+
+int test_clrsbll(long long x)
+{
+ return x ? __builtin_clrsbll(x) : (__SIZEOF_LONG_LONG__*8-1);
+}
+
+#if 0
+/* BUILT_IN_FFS is transformed by match.pd */
+int test_ffs(unsigned int x)
+{
+ return x ? __builtin_ffs(x) : 0;
+}
+
+int test_ffsl(unsigned long x)
+{
+ return x ? __builtin_ffsl(x) : 0;
+}
+
+int test_ffsll(unsigned long long x)
+{
+ return x ? __builtin_ffsll(x) : 0;
+}
+#endif
+
+int test_parity(int x)
+{
+ return x ? __builtin_parity(x) : 0;
+}
+
+int test_parityl(long x)
+{
+ return x ? __builtin_parityl(x) : 0;
+}
+
+int test_parityll(long long x)
+{
+ return x ? __builtin_parityll(x) : 0;
+}
+
+int test_popcount(int x)
+{
+ return x ? __builtin_popcount(x) : 0;
+}
+
+int test_popcountl(long x)
+{
+ return x ? __builtin_popcountl(x) : 0;
+}
+
+int test_popcountll(long long x)
+{
+ return x ? __builtin_popcountll(x) : 0;
+}
+
+/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */
+
edge, edge, gphi *, tree, tree);
static bool spaceship_replacement (basic_block, basic_block,
edge, edge, gphi *, tree, tree);
-static bool cond_removal_in_popcount_clz_ctz_pattern (basic_block, basic_block,
- edge, edge, gphi *,
- tree, tree);
+static bool cond_removal_in_builtin_zero_pattern (basic_block, basic_block,
+ edge, edge, gphi *,
+ tree, tree);
static bool cond_store_replacement (basic_block, basic_block, edge, edge,
hash_set<tree> *);
static bool cond_if_else_store_replacement (basic_block, basic_block, basic_block);
early_p))
cfgchanged = true;
else if (!early_p
- && cond_removal_in_popcount_clz_ctz_pattern (bb, bb1, e1,
- e2, phi, arg0,
- arg1))
+ && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2,
+ phi, arg0, arg1))
cfgchanged = true;
else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
cfgchanged = true;
return true;
}
-/* Convert
+/* Optimize x ? __builtin_fun (x) : C, where C is __builtin_fun (0).
+ Convert
<bb 2>
if (b_4(D) != 0)
instead of 0 above it uses the value from that macro. */
static bool
-cond_removal_in_popcount_clz_ctz_pattern (basic_block cond_bb,
- basic_block middle_bb,
- edge e1, edge e2, gphi *phi,
- tree arg0, tree arg1)
+cond_removal_in_builtin_zero_pattern (basic_block cond_bb,
+ basic_block middle_bb,
+ edge e1, edge e2, gphi *phi,
+ tree arg0, tree arg1)
{
gimple *cond;
gimple_stmt_iterator gsi, gsi_from;
int val = 0;
switch (cfn)
{
+ case CFN_BUILT_IN_BSWAP16:
+ case CFN_BUILT_IN_BSWAP32:
+ case CFN_BUILT_IN_BSWAP64:
+ case CFN_BUILT_IN_BSWAP128:
+ CASE_CFN_FFS:
+ CASE_CFN_PARITY:
CASE_CFN_POPCOUNT:
break;
CASE_CFN_CLZ:
}
}
return false;
+ case BUILT_IN_CLRSB:
+ val = TYPE_PRECISION (integer_type_node) - 1;
+ break;
+ case BUILT_IN_CLRSBL:
+ val = TYPE_PRECISION (long_integer_type_node) - 1;
+ break;
+ case BUILT_IN_CLRSBLL:
+ val = TYPE_PRECISION (long_long_integer_type_node) - 1;
+ break;
default:
return false;
}