This is the mail archive of the gcc-patches@gcc.gnu.org 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: Simple bitop reassoc in match.pd (was: Canonicalize X u< X to UNORDERED_EXPR)


On Wed, 11 May 2016, H.J. Lu wrote:

        * fold-const.c (fold_binary_loc) [(X ^ Y) & Y]: Remove and merge with...
        * match.pd ((X & Y) ^ Y): ... this.

It caused:

FAIL: gcc.dg/tree-ssa/vrp47.c scan-tree-dump-times vrp2 " & 1;" 0

on x86.

Ah, yes, logical_op_short_circuit so I didn't test it. Hmm, doesn't seem so easy. We want to compute (int)(x==0) in a branch where x is known to be in [0, 1]. VRP1 gives (int)(_Bool)(x^1). forwprop3 handles the double conversion, which gives (x^1)&1. Here the new transform applies and gives (~x)&1. VRP2 comes, and with (x^1)&1 it used to notice that this is just x^1 (remember that x is in [0, 1] in this branch), while it doesn't know what to do with (~x)&1. In the end, we get
	notl	%eax
	andl	$1, %eax
instead of
	xorl	$1, %eax

(andn doesn't seem to have a version with an immediate)

The transformation seems right to me, but we are then missing another transformation like ~X & Y -> X ^ Y when we know that X & ~Y is 0 (the 1 bits of X are included in those of Y). That may not be easy with the limited bit tracking we have. A version limited to constant Y of the form 2^n-1 (i.e. 0...01...1) where X has a range included in [0, Y] may be simpler.

We could also simplify (int)(_Bool)x to x using VRP information that x is in [0, 1], but apparently when VRP replaces x==0 with y=x^1,(_Bool)y, it does not compute a range for the new variable y, and by the time the next VRP pass comes, it is too late.

In the mean time, I propose xfailing this test...

--
Marc Glisse


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