Hi all, The following rtx pattern will be transformed into the second one,which makes the compiler unable to remove the redundant zero_extend operation.
(set (zero_extract:SI (reg/i:SI 0 x0) (const_int 8 [0x8]) (const_int 0 [0])) (and:SI (reg:SI 1 x1 [ y ]) (const_int 255 [0xff]))) ------------------->>>>>>>>>>>>>>>> (set (zero_extract:SI (reg/i:SI 0 x0) (const_int 8 [0x8]) (const_int 0 [0])) (zero_extend:SI (reg:QI 1 x1 [ y ]))) This patch add the code to handle the second case as well. for example, for the following short code excerpt int f5(int x, int y) { return (x & ~0xff) | (y & 0xff); } original code-gen is: uxtb w1, w1 bfi w0, w1, 0, 8 ret new code-gen is: bfi w0, w1, 0, 8 ret x86-64 bootstraps Okay, aarch64-none-elf regression test Okay. Okay for trunk? Regards, Renlin Li gcc/ChangeLog: 2015-02-13 Renlin Li <renlin...@arm.com> * combine.c (make_field_assignment): Add code to remove redundant ZERO_EXTEND operation.
diff --git a/gcc/combine.c b/gcc/combine.c index f779117..759e07c 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -9311,6 +9311,31 @@ make_field_assignment (rtx x) } } + /* If DEST is already a field assignment, i.e. ZERO_EXTRACT, and the + SRC is an ZERO_EXTEND with all bits of that field set, then we can discard + the ZERO_EXTEND. */ + if (GET_CODE (dest) == ZERO_EXTRACT + && CONST_INT_P (XEXP (dest, 1)) + && CONST_INT_P (XEXP (dest, 2)) + && GET_CODE (src) == ZERO_EXTEND + && REG_P (XEXP (src, 0))) + { + unsigned int regno = REGNO (XEXP (src, 0)); + unsigned int inner_size = GET_MODE_BITSIZE (GET_MODE (XEXP (src, 0))); + mode = GET_MODE (src); + + HOST_WIDE_INT width = INTVAL (XEXP (dest, 1)); + HOST_WIDE_INT lsb = INTVAL (XEXP (dest, 2)); + /* Complete overlap. We can remove the source ZERO_EXTEND. */ + if (width == inner_size + && (regno < FIRST_PSEUDO_REGISTER) + && HARD_REGNO_MODE_OK (regno, mode)) + { + rtx reg = gen_rtx_REG (mode, regno); + return gen_rtx_SET (VOIDmode, dest, reg); + } + } + /* The other case we handle is assignments into a constant-position field. They look like (ior/xor (and DEST C1) OTHER). If C1 represents a mask that has all one bits except for a group of zero bits and