diff options
author | Richard Biener <rguenther@suse.de> | 2018-11-06 08:09:03 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-11-06 08:09:03 +0000 |
commit | ffe5a586ccb5805010b933d4be1d238c895c3409 (patch) | |
tree | c7361fff915eabf1e47c6c247112fc676ed665ae /gcc/simplify-rtx.c | |
parent | 91c03124fcd1e652e225e16dde954efbb994543c (diff) | |
download | gcc-ffe5a586ccb5805010b933d4be1d238c895c3409.zip gcc-ffe5a586ccb5805010b933d4be1d238c895c3409.tar.gz gcc-ffe5a586ccb5805010b933d4be1d238c895c3409.tar.bz2 |
re PR middle-end/18041 (OR of two single-bit bitfields is inefficient)
2018-11-06 Richard Biener <rguenther@suse.de>
PR middle-end/18041
* simplify-rtx.c (simplify_binary_operation_1): Add pattern
matching bitfield insertion.
* gcc.target/i386/pr18041-1.c: New testcase.
* gcc.target/i386/pr18041-2.c: Likewise.
From-SVN: r265829
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 2ff68ce..0d53135 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2857,6 +2857,38 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, XEXP (op0, 1)); } + /* The following happens with bitfield merging. + (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */ + if (GET_CODE (op0) == AND + && GET_CODE (op1) == AND + && CONST_INT_P (XEXP (op0, 1)) + && CONST_INT_P (XEXP (op1, 1)) + && (INTVAL (XEXP (op0, 1)) + == ~INTVAL (XEXP (op1, 1)))) + { + /* The IOR may be on both sides. */ + rtx top0 = NULL_RTX, top1 = NULL_RTX; + if (GET_CODE (XEXP (op1, 0)) == IOR) + top0 = op0, top1 = op1; + else if (GET_CODE (XEXP (op0, 0)) == IOR) + top0 = op1, top1 = op0; + if (top0 && top1) + { + /* X may be on either side of the inner IOR. */ + rtx tem = NULL_RTX; + if (rtx_equal_p (XEXP (top0, 0), + XEXP (XEXP (top1, 0), 0))) + tem = XEXP (XEXP (top1, 0), 1); + else if (rtx_equal_p (XEXP (top0, 0), + XEXP (XEXP (top1, 0), 1))) + tem = XEXP (XEXP (top1, 0), 0); + if (tem) + return simplify_gen_binary (IOR, mode, XEXP (top0, 0), + simplify_gen_binary + (AND, mode, tem, XEXP (top1, 1))); + } + } + tem = simplify_byte_swapping_operation (code, mode, op0, op1); if (tem) return tem; |