https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106617
--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> ---
Btw, just for reference the original looks like
fc_cpu_order = ( __builtin_constant_p(( __builtin_constant_p(nr_cpu_ids) ? (
((nr_cpu_ids) == 1) ? 1 : (1UL << (( __builtin_constant_p((nr_cpu_ids) - 1) ? (
__builtin_constant_p((nr_cpu_ids) - 1) ? ( ((nr_cpu_ids) - 1) < 2 ? 0 :
((nr_cpu_ids) - 1) & (1ULL << 63) ? 63 : ((nr_cpu_ids) - 1) & (1ULL << 62) ? 62
: ((nr_cpu_ids) - 1) & (1ULL << 61) ? 61 : ((nr_cpu_ids) - 1) & (1ULL << 60) ?
60 : ((nr_cpu_ids) - 1) & (1ULL << 59) ? 59 : ((nr_cpu_ids) - 1) & (1ULL << 58)
? 58 : ((nr_cpu_ids) - 1) & (1ULL << 57) ? ...
so some fancy ceil_log2.
If you take a simplified
unsigned long fc_setup_exch_mgr(int nr_cpu_ids_m1)
{
return ((((nr_cpu_ids_m1)) & (1<<21) ? 21
: ((nr_cpu_ids_m1)) & (1<<20) ? 20
: ((nr_cpu_ids_m1)) & (1<<19) ? 19
: ((nr_cpu_ids_m1)) & (1<<18) ? 18
: ((nr_cpu_ids_m1)) & (1<<17) ? 17
: ((nr_cpu_ids_m1)) & (1<<16) ? 16
: ((nr_cpu_ids_m1)) & (1<<15) ? 15
: ((nr_cpu_ids_m1)) & (1<<14) ? 14
: ((nr_cpu_ids_m1)) & (1<<13) ? 13
: ((nr_cpu_ids_m1)) & (1<<12) ? 12
: ((nr_cpu_ids_m1)) & (1<<11) ? 11 /* THIS */
: ((nr_cpu_ids_m1)) & (1<<9) ? 9
: ((nr_cpu_ids_m1)) & (1<<8) ? 8
: ((nr_cpu_ids_m1)) & (1<<7) ? 7
: ((nr_cpu_ids_m1)) & (1<<6) ? 6
: ((nr_cpu_ids_m1)) & (1<<5) ? 5
: ((nr_cpu_ids_m1)) & (1<<4) ? 4
: ((nr_cpu_ids_m1)) & (1<<3) ? 3
: 0)) != 11;
}
I see
./cc1 -quiet t2.c -fdump-tree-original-folding; grep 'Applying'
t2.c.005t.original | sort -u ; grep 'Applying' t2.c.005t.original | wc -l
Applying pattern match.pd:4778, generic-match.cc:95676
Applying pattern match.pd:5809, generic-match.cc:24025
16383
but when I just remove the marked line it becomes
./cc1 -quiet t2.c -fdump-tree-original-folding; grep 'Applying'
t2.c.005t.original | sort -u ; grep 'Applying' t2.c.005t.original | wc -l
Applying pattern match.pd:4778, generic-match.cc:95676
Applying pattern match.pd:5809, generic-match.cc:24025
34
hmm, and the issue is probably that we have this pattern both in
fold-const.cc and match.pd and thus when the pattern applies recursively,
like for
(a ? (b ? d : e) : f) > g
and the original fold implementation would simplify because one of the
braches simplifes:
/* Check that we have simplified at least one of the branches. */
if (!TREE_CONSTANT (arg) && !TREE_CONSTANT (lhs) && !TREE_CONSTANT (rhs))
return NULL_TREE;
so it goes all the way, recursively to "simple". But then the match.pd
variant rejects the result because it is EXPR_P for the lhs (but not
for the rhs). We always first try the match.pd path but then will
try fold_binary_op_with_conditional_arg anyway which makes this effectively
at least quadratic.
This was all done to avoid regressing the COND_EXPR gimple IL refactoring.
One possibility to avoid the recursion with fold-const is to disable the
match.pd pattern for GENERIC.