On Fri, Jun 10, 2016 at 01:14:16PM -0600, Jeff Law wrote: > The change itself is fine, and it's approved with a testcase or at least > an explanation of why you can't turn either of the tests from the BZ > into a testcase in our framework.
This is what I committed: 2016-06-11 Segher Boessenkool <seg...@kernel.crashing.org> PR middle-end/71310 * fold-const.c (optimize_bit_field_compare): Don't try to use word_mode unconditionally for reading the bit field, look at DECL_BIT_FIELD_REPRESENTATIVE instead. gcc/testsuite/ PR middle-end/71310 * gcc.target/powerpc/pr71310.c: New testcase. --- gcc/fold-const.c | 13 ++++++++++++- gcc/testsuite/gcc.target/powerpc/pr71310.c | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr71310.c diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5058746..f067001 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3903,13 +3903,24 @@ optimize_bit_field_compare (location_t loc, enum tree_code code, return 0; } + /* Don't use a larger mode for reading the bit field than we will + use in other places accessing the bit field. */ + machine_mode largest_mode = word_mode; + if (TREE_CODE (lhs) == COMPONENT_REF) + { + tree field = TREE_OPERAND (lhs, 1); + tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field); + if (repr) + largest_mode = DECL_MODE (repr); + } + /* See if we can find a mode to refer to this field. We should be able to, but fail if we can't. */ nmode = get_best_mode (lbitsize, lbitpos, 0, 0, const_p ? TYPE_ALIGN (TREE_TYPE (linner)) : MIN (TYPE_ALIGN (TREE_TYPE (linner)), TYPE_ALIGN (TREE_TYPE (rinner))), - word_mode, false); + largest_mode, false); if (nmode == VOIDmode) return 0; diff --git a/gcc/testsuite/gcc.target/powerpc/pr71310.c b/gcc/testsuite/gcc.target/powerpc/pr71310.c new file mode 100644 index 0000000..6869a50 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr71310.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2" } */ + +/* { dg-final { scan-assembler-not {\mld} } } */ +/* { dg-final { scan-assembler-not {\mlwz} } } */ +/* { dg-final { scan-assembler-times {\mlbz} 2 } } */ + +struct mmu_gather { + long end; + int fullmm : 1; +}; + +void __tlb_reset_range(struct mmu_gather *p1) +{ + if (p1->fullmm) + p1->end = 0; +} + +void tlb_gather_mmu(struct mmu_gather *p1) +{ + p1->fullmm = 1; + __tlb_reset_range(p1); +} -- 1.9.3