[PATCH] Missing TRULY_NOOP_TRUNCATION after restored optimize_bit_field_compare

Richard Guenther richard.guenther@gmail.com
Mon Dec 29 15:53:00 GMT 2008


On Fri, Dec 12, 2008 at 7:30 PM, Adam Nemet <anemet@caviumnetworks.com> wrote:
> Now that optimize_bit_field_compare is back we're more likely to read
> bit-inserted fields *without* bit-extraction.  This means that on MIPS64 if
> the top bits of a 32-bit bitfield are manipulated wrong code is generated
> unless the top field is properly sign-extended (because for example in
> pr33887-1.C, the constant we're comparing against is 64-bit sign-extended.)
>
> This happens because for the testcase below store_bit_field_1 generates this:
>
> (set (zero_extract:DI (subreg:DI (reg:SI 193) 0)
>            (const_int 3)
>            (const_int 29))
>        (subreg:DI (reg:SI 194) 0))
>
> With the patch we now add a truncation of the result:
>
> (set (reg:SI 193)
>     (truncate:SI (subreg:DI (reg:SI 193) 0)))
>
> This is very similar to my recent fix to extract_bit_field_1
> (http://gcc.gnu.org/ml/gcc-patches/2008-10/msg01072.html) and I had on my list
> to look at stores as well but apparently I wasn't quick enough.
>
> Bootstrapped and regtested on mips64octeon-linux-gnu with {,-mabi=64}.  These
> are the tests that regressed after optimize_bit_field_compare but are
> recovered now:
>
> gcc:
>
>  FAIL->PASS (total: 9)
>    gcc.c-torture/execute/bf-sign-1.c execution,  -O1
>    gcc.c-torture/execute/bf-sign-1.c execution,  -O2
>    gcc.c-torture/execute/bf-sign-1.c execution,  -O3 -fomit-frame-pointer
>    gcc.c-torture/execute/bf-sign-1.c execution,  -O3 -g
>    gcc.c-torture/execute/bf-sign-1.c execution,  -Os
>    gcc.c-torture/execute/pr19689.c execution,  -O2
>    gcc.c-torture/execute/pr19689.c execution,  -O3 -fomit-frame-pointer
>    gcc.c-torture/execute/pr19689.c execution,  -O3 -g
>    gcc.c-torture/execute/pr19689.c execution,  -Os
>
> g++:
>
>  FAIL->PASS (total: 4)
>    g++.dg/torture/pr33887-1.C  -O2  execution test
>    g++.dg/torture/pr33887-1.C  -O3 -fomit-frame-pointer  execution test
>    g++.dg/torture/pr33887-1.C  -O3 -g  execution test
>    g++.dg/torture/pr33887-1.C  -Os  execution test
>
> OK to install?

Ok.

Thanks,
Richard.

> Adam
>
>        * expmed.c (store_bit_field_1): Properly truncate the paradoxical
>        subreg of op0 to the original op0.
>
> testsuite/
>        * gcc.target/mips/ins-2.c: New test.
>
> Index: expmed.c
> ===================================================================
> --- expmed.c    (revision 142638)
> +++ expmed.c    (working copy)
> @@ -748,6 +748,16 @@ store_bit_field_1 (rtx str_rtx, unsigned
>       if (pat)
>        {
>          emit_insn (pat);
> +
> +         /* If the mode of insertion operation is wider than the mode
> +            of the target register we created a paradoxical subreg for
> +            the target.  Truncate the paradoxical subreg of the
> +            target to itself properly.  */
> +         if (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (op0)),
> +                                     GET_MODE_BITSIZE (op_mode))
> +             && (REG_P (xop0)
> +                 || GET_CODE (xop0) == SUBREG))
> +             convert_move (op0, xop0, true);
>          return true;
>        }
>       delete_insns_since (last);
> Index: testsuite/gcc.target/mips/ins-2.c
> ===================================================================
> --- testsuite/gcc.target/mips/ins-2.c   (revision 0)
> +++ testsuite/gcc.target/mips/ins-2.c   (revision 0)
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +/* { dg-mips-options "-O -meb -mips64r2 -mgp64" } */
> +/* { dg-final { scan-assembler-times "\tins\t|\tdins\t" 1 } } */
> +/* { dg-final { scan-assembler-times "\tsll\t|\tins\t" 1 } } */
> +
> +struct s
> +{
> +  int a:3;
> +  int b:29;
> +};
> +
> +NOMIPS16 void
> +f (int a)
> +{
> +  struct s s;
> +  asm volatile ("" : "=r"(s));
> +  s.a = a;
> +  asm volatile ("" :: "r"(s));
> +}
>



More information about the Gcc-patches mailing list