This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR rtl-optimization/46490


This is a regression with -O2 -mtune=i386 present on the mainline.

The combiner turns:

(insn 9 8 10 2 (set (reg:QI 68)
        (sign_extract:QI (reg:HI 70)
            (const_int 8 [0x8])
            (const_int 8 [0x8]))) p.adb:9 64 {*movqi_extv_1}
     (expr_list:REG_EQUAL (mod:QI (reg:QI 66 [ q__fix_half ])
            (const_int 16 [0x10]))
        (nil)))

(insn 11 10 12 2 (set (reg:QI 72)
        (reg:QI 68)) p.adb:9 52 {*movqi_internal}
     (expr_list:REG_DEAD (reg:QI 68)
        (nil)))

into:

(insn 11 10 12 2 (parallel [
            (set (reg:QI 72)
                (ashift:QI (subreg:QI (reg:HI 70) 0)
                    (const_int -8 [0xfffffff8])))
            (clobber (reg:CC 17 flags))
        ]) p.adb:9 391 {*ashlqi3_1_lea}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (expr_list:REG_DEAD (reg:HI 70)
            (nil))))

Note the bogus (const_int -8).  Yet the combiner specifically checks for that:

  /* If we reach here, we want to return a pair of shifts.  The inner
     shift is a left shift of BITSIZE - POS - LEN bits.  The outer
     shift is a right shift of BITSIZE - LEN bits.  It is arithmetic or
     logical depending on the value of UNSIGNEDP.

     If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be
     converted into an AND of a shift.

     We must check for the case where the left shift would have a negative
     count.  This can happen in a case like (x >> 31) & 255 on machines
     that can't shift by a constant.  On those machines, we would first
     combine the shift with the AND to produce a variable-position
     extraction.  Then the constant of 31 would be substituted in to produce
     a such a position.  */

but there has been a thinko in the check since the first revision (r357).

This had apparently stayed latent until after H.J. added the 8-bit divmov
support to the x86 port in June, with the unusual sign_extract pattern.

Tested on i586-suse-linux, applied on the mainline 


2010-11-16  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/46490
	* combine.c (expand_compound_operation): Fix thinko.


2010-11-16  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/opt12.adb: New test.
	* gnat.dg/opt12_pkg.ad[sb]: New helper.


-- 
Eric Botcazou
Index: combine.c
===================================================================
--- combine.c	(revision 166792)
+++ combine.c	(working copy)
@@ -6761,11 +6761,11 @@ expand_compound_operation (rtx x)
      count.  This can happen in a case like (x >> 31) & 255 on machines
      that can't shift by a constant.  On those machines, we would first
      combine the shift with the AND to produce a variable-position
-     extraction.  Then the constant of 31 would be substituted in to produce
-     a such a position.  */
+     extraction.  Then the constant of 31 would be substituted in
+     to produce such a position.  */
 
   modewidth = GET_MODE_BITSIZE (GET_MODE (x));
-  if (modewidth + len >= pos)
+  if (modewidth >= pos + len)
     {
       enum machine_mode mode = GET_MODE (x);
       tem = gen_lowpart (mode, XEXP (x, 0));
-- { dg-do run }
-- { dg-options "-O2" }

with Opt12_Pkg; use Opt12_Pkg;

procedure Opt12 is

   Static_Target : Static_Integer_Subtype;

begin

   Static_Target := Static_Integer_Subtype(Fix_Half);

   if not Equal(Static_Target, 1) then
     raise Program_Error;
   end if;

end Opt12;
package body Opt12_Pkg is

   function Equal (L, R: Static_Integer_Subtype) return Boolean is
   begin
      return (L = R);
   end;

end Opt12_Pkg;
package Opt12_Pkg is

   type Static_Integer_Subtype is range -32_000 .. 32_000;

   function Equal (L, R: Static_Integer_Subtype) return Boolean;

   type My_Fixed is delta 0.1 range -5.0 .. 5.0;

   Fix_Half : My_Fixed := 0.5;

end Opt12_Pkg;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]