On 12/08/15 18:32, Jeff Law wrote:
On 08/12/2015 10:18 AM, Kyrill Tkachov wrote:
Hi all,
This patch is a sequel to:
https://gcc.gnu.org/ml/gcc-patches/2015-07/msg02567.html
It allows if-conversion of expressions of the form:
if (test) x := y + c1; else x := y + c2
where c1 and c2 are a pair constants that can be optimised using the
existing rules in noce_try_store_flag_constants.
The resulting sequence looks something like:
x := (test [!=,==] 0) + y;
x := x + [c1,c2];
This patch reuses the logic for the combinations of diff and STORE_FLAG
signs that
is hammered out in
https://gcc.gnu.org/ml/gcc-patches/2015-07/msg02567.html.
That means we just extract the constants c1 and c2 from the PLUS rtx
and use their diff as the driver for the logic in that function.
Currently, this patch allows only the case where
diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE
as it is the most beneficial case (from looking at SPEC2006 on aarch64)
and also the least tricky to get right.
In the future I suppose that restriction can be relaxed if needed, but
in any case
this should be an improvement over the existing situation.
On aarch64 this allows us for code:
int
barsi (int x)
{
return x > 100 ? x + 4 : x + 3;
}
to generate:
barsi:
cmp w0, 101
cinc w0, w0, ge
add w0, w0, 3
ret
instead of the current:
barsi:
add w1, w0, 4
add w2, w0, 3
cmp w0, 101
csel w0, w2, w1, lt
ret
thus saving one instruction and using two fewer registers.
Bootstrapped and tested on arm, aarch64, x86_64.
Ok for trunk?
Thanks,
Kyrill
2015-08-12 Kyrylo Tkachov <kyrylo.tkac...@arm.com>
* ifcvt.c (noce_try_store_flag_constants): Handle PLUS-immediate
expressions in A and B.
2015-08-12 Kyrylo Tkachov <kyrylo.tkac...@arm.com>
* gcc.target/aarch64/cinc_common_1.c: New test.
The function comment for noce_try_store_flag_constants needs to be updated.
OK with that fix.
Thanks, I'll update the comment and commit.
Presumably there's some obvious extensions here for operators other than
PLUS, the question in my mind is whether or not they matter in practice.
Curious to hear your thoughts about handling other operators and
whether or not you think it's worth it as a follow-up.
I did consider it. I am most interested in the case that I enabled
in this patch because this can enable targets that have conditional
increment instructions, like aarch64. In that case, if-conversion
opens the way for combine to utilise that naturally.
The other two transformations in that function are:
/* if (test) x = 8; else x = 0;
=> x = (test != 0) << 3; */
and
/* if (test) x = -1; else x = b;
=> x = -(test != 0) | b; */
So they either shift the stored flag, or do other bitwise ops on it.
By adding an extra addition (for the common part) I don't think there's
much to gain against the alternative, which will be to do two parallel
additions and a conditional select.
Thanks,
Kyrill
Jeff