Message ID | 704e01715eeb6663365be6b169d6792b4622b1bb.1419439883.git.segher@kernel.crashing.org |
---|---|
State | New |
Headers | show |
On Mon, Dec 29, 2014 at 12:14:31PM +0000, Alan Lawrence wrote: > Just a quick thought: will this catch e.g. (and (not X) (ior X Y))? It doesn't (and nothing else does, either; I checked). > That's > equivalent to (and (not X) (ior (not (not X)) Y)), i.e. (and X' (ior (not > X') Y)) with X'=(not X), under the assumption that (not (not X)) is > equivalent to X. However I suspect for cases of this form, GET_CODE (XEXP > (op1, <n>)) != NOT...? Right. We'd have to check that in (and A (ior B C)) A is equal to the NOT of B or C. Or, we could transform it to (ior (and A B) (and A C)) and see if that simplifies to something simpler. Also for IOR and AND swapped. Dunno what other cases we miss. I'm a bit worried about the cost of a more general test, and how do you determine "what is simpler" anyway, in not-so-simple cases. Either way, my patch fixes a testsuite fail ;-) Segher
On 12/24/14 10:05, Segher Boessenkool wrote: > The existing transform > > (and X (ior (not X) Y) -> (and X Y) > > has two shortcomings: it only handles identical RTX for X, i.e. registers, > not e.g. subregs of registers; and it only handles the case where the NOT > is the first arm of the IOR (it can be the second arm e.g. if the first > arm is a NOT as well). Fix both. This fixes gcc.dg/and-1.c on powerpc64. > > Bootstrapped and tested on powerpc64-linux; okay for mainline? > > > Segher > > > 2014-12-24 Segher Boessenkool <segher@kernel.crashing.org> > > gcc/ > * simplify-rtx.c (simplify_binary_operation_1): Handle more cases > for the "(and X (ior (not X) Y) -> (and X Y)" transform. OK. jeff
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 277288a..ae0b49d 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2933,15 +2933,27 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, /* (and X (ior (not X) Y) -> (and X Y) */ if (GET_CODE (op1) == IOR && GET_CODE (XEXP (op1, 0)) == NOT - && op0 == XEXP (XEXP (op1, 0), 0)) + && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0))) return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1)); /* (and (ior (not X) Y) X) -> (and X Y) */ if (GET_CODE (op0) == IOR && GET_CODE (XEXP (op0, 0)) == NOT - && op1 == XEXP (XEXP (op0, 0), 0)) + && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0))) return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1)); + /* (and X (ior Y (not X)) -> (and X Y) */ + if (GET_CODE (op1) == IOR + && GET_CODE (XEXP (op1, 1)) == NOT + && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0))) + return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0)); + + /* (and (ior Y (not X)) X) -> (and X Y) */ + if (GET_CODE (op0) == IOR + && GET_CODE (XEXP (op0, 1)) == NOT + && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0))) + return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0)); + tem = simplify_byte_swapping_operation (code, mode, op0, op1); if (tem) return tem;