aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-11-06 08:09:03 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-11-06 08:09:03 +0000
commitffe5a586ccb5805010b933d4be1d238c895c3409 (patch)
treec7361fff915eabf1e47c6c247112fc676ed665ae /gcc/simplify-rtx.c
parent91c03124fcd1e652e225e16dde954efbb994543c (diff)
downloadgcc-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.c32
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;