This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: how to check if target supports andnot instruction ?

On Thu, 13 Oct 2016, Prathamesh Kulkarni wrote:

On 12 October 2016 at 14:43, Richard Biener <> wrote:
On Wed, 12 Oct 2016, Marc Glisse wrote:

On Wed, 12 Oct 2016, Prathamesh Kulkarni wrote:

I was having a look at PR71636 and added the following pattern to match.pd:
x & ((1U << b) - 1) -> x & ~(~0U << b)
However the transform is useful only if the target supports "andnot"

rth was selling the transformation as a canonicalization, which is beneficial
when there is an andnot instruction, and neutral otherwise, so it could be
done always.

Well, its three instructions to three instructions and a more expensive
constant(?).  ~0U might not be available as immediate for the shift
instruction and 1U << b might be available as a bit-set instruction ...
(vs. the andnot).

True, I hadn't thought of bit-set.

So yes, we might decide to canonicalize to andnot (and decide that
three binary to two binary and one unary op is "better").

So no excuse to explore the target specific .pd fragment idea ... :/
I have attached patch that adds the transform.
Does that look OK ?

Why bit_not of build_zero_cst instead of build_all_ones_cst, as suggested in the PR? If we only do the transformation when (1<<b)-1 is fed to a bit_and, then we probably want to require that it has a single use (maybe even the shift).

I am not sure how to write test-cases for it though.
For the test-case:
unsigned f(unsigned x, unsigned b)
 unsigned t1 = 1U << b;
 unsigned t2 = t1 - 1;
 unsigned t3 = x & t2;
 return t3;

forwprop dump shows:
Applying pattern match.pd:523, gimple-match.c:47419
gimple_simplified to _6 = 4294967295 << b_1(D);
_8 = ~_6;
t3_5 = x_4(D) & _8;

I could scan for "_6 = 4294967295 << b_1(D);"  however I suppose
~0 would depend on width of int and not always be 4294967295 ?
Or should I scan for "_6 = 4294967295 << b_1(D);"
and add /* { dg-require-effective int32 } */  to the test-case ?

You could check that you have ~, or that you don't have " 1 << ".

Marc Glisse

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]