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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr18041-1.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr18041-2.c | 14 |
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 } } } } */ |