aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/simplify-rtx.c32
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr18041-1.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr18041-2.c14
5 files changed, 71 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2c5abd3..b4b36e0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-11-06 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/18041
+ * simplify-rtx.c (simplify_binary_operation_1): Add pattern
+ matching bitfield insertion.
+
2018-11-06 Alexandre Oliva <aoliva@redhat.com>
* auto-inc-dec.c: Include valtrack.h. Improve comments.
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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 061fa46..0bfb80f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-11-06 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/18041
+ * gcc.target/i386/pr18041-1.c: New testcase.
+ * gcc.target/i386/pr18041-2.c: Likewise.
+
2018-11-06 Wei Xiao <wei3.xiao@intel.com>
* gcc.target/i386/avx-1.c: Update tests for VFIXUPIMM* intrinsics.
diff --git a/gcc/testsuite/gcc.target/i386/pr18041-1.c b/gcc/testsuite/gcc.target/i386/pr18041-1.c
new file mode 100644
index 0000000..24da41a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr18041-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct B { unsigned bit0 : 1; unsigned bit1 : 1; };
+
+void
+foo (struct B *b)
+{
+ b->bit0 = b->bit0 | b->bit1;
+}
+
+/* { dg-final { scan-assembler-times "and" 1 } } */
+/* { dg-final { scan-assembler-times "or" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr18041-2.c b/gcc/testsuite/gcc.target/i386/pr18041-2.c
new file mode 100644
index 0000000..00ebd2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr18041-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct B { unsigned bit0 : 1; unsigned bit1 : 1; };
+
+void
+bar (struct B *b, int x)
+{
+ b->bit0 |= x;
+}
+
+/* This fails to combine in 32bit mode but not for x32. */
+/* { dg-final { scan-assembler-times "and" 1 { xfail { { ! x32 } && ilp32 } } } } */
+/* { dg-final { scan-assembler-times "or" 1 { xfail { { ! x32 } && ilp32 } } } } */