Commit a62436c0 by Segher Boessenkool Committed by Segher Boessenkool

simplify-rtx: Transform (xor (and (xor A B) C) B) with C const

match.pd transforms (A&C)|(B&~C) to ((A^B)&C)^B, which is fewer
operations if C is not const (and it is not on simple tests at least,
this transform is done very early already).

Various processors have "insert" instructions that can do this, but
combine cannot build those from the xor-and-xor, especially it has no
chance at all to do that if A or B or multiple instructions as well
(on PowerPC, the rl[wd]imi instructions can do this with together with
a rotate, or a simple shift with appropriate C; other ISAs have similar
insns).

This patch makes RTL simplify transform (xor (and (xor A B) C) B) back
to (ior (and A C) (and B ~C)) for constant C (and similar with A instead
of B for that last term).


	* simplify-rtx.c (simplify_binary_operation_1): Simplify
	(xor (and (xor A B) C) B) to (ior (and A C) (and B ~C)) and
	(xor (and (xor A B) C) A) to (ior (and A ~C) (and B C)) if C
	is a const_int.

From-SVN: r242031
parent a84a4f0b
2016-11-09 Segher Boessenkool <segher@kernel.crashing.org>
* simplify-rtx.c (simplify_binary_operation_1): Simplify
(xor (and (xor A B) C) B) to (ior (and A C) (and B ~C)) and
(xor (and (xor A B) C) A) to (ior (and A ~C) (and B C)) if C
is a const_int.
2016-11-09 David Malcolm <dmalcolm@redhat.com>
* print-rtl-function.c: Include varasm.h.
......@@ -2886,6 +2886,37 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
}
}
/* If we have (xor (and (xor A B) C) A) with C a constant we can instead
do (ior (and A ~C) (and B C)) which is a machine instruction on some
machines, and also has shorter instruction path length. */
if (GET_CODE (op0) == AND
&& GET_CODE (XEXP (op0, 0)) == XOR
&& CONST_INT_P (XEXP (op0, 1))
&& rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
{
rtx a = trueop1;
rtx b = XEXP (XEXP (op0, 0), 1);
rtx c = XEXP (op0, 1);
rtx nc = simplify_gen_unary (NOT, mode, c, mode);
rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
rtx bc = simplify_gen_binary (AND, mode, b, c);
return simplify_gen_binary (IOR, mode, a_nc, bc);
}
/* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
else if (GET_CODE (op0) == AND
&& GET_CODE (XEXP (op0, 0)) == XOR
&& CONST_INT_P (XEXP (op0, 1))
&& rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
{
rtx a = XEXP (XEXP (op0, 0), 0);
rtx b = trueop1;
rtx c = XEXP (op0, 1);
rtx nc = simplify_gen_unary (NOT, mode, c, mode);
rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
rtx ac = simplify_gen_binary (AND, mode, a, c);
return simplify_gen_binary (IOR, mode, ac, b_nc);
}
/* (xor (comparison foo bar) (const_int 1)) can become the reversed
comparison if STORE_FLAG_VALUE is 1. */
if (STORE_FLAG_VALUE == 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment