Fix PR rtl-optimization/28386

Eric Botcazou ebotcazou@libertysurf.fr
Fri Aug 11 21:23:00 GMT 2006


This is a regression present on 4.1 branch at -Os and marked "blocker" so...

Tree-ivopts generates an unsigned iv that wraps around:

unsigned int ivtmp.34;

<bb 0>:
  a = g;
  j = 0;
  ivtmp.34 = 0ffffff81;

<L3>:;
  if (ivtmp.34 <= 127) goto <L4>; else goto <L5>;

<L4>:;
  D.1323 = (int) ivtmp.34;
  D.1324 = s[D.1323][0];
  a = (char) (int) D.1324;
  j = j + 1;

and thus fools the old RTL loop optimizer:

(insn 13 12 65 0 (set (reg:SI 59 [ ivtmp.34 ])
        (const_int -127 [0xffffff81])) 34 {*movsi_1} (nil)
    (nil))
;; End of basic block 0, registers live:
 (nil)

(note 65 13 14 1 NOTE_INSN_LOOP_BEG)

;; Start of basic block 1, registers live: (nil)
(code_label 14 65 15 1 2 "" [1 uses])

(note 15 14 17 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn 17 15 18 1 (set (reg:CC 17 flags)
        (compare:CC (reg:SI 59 [ ivtmp.34 ])
            (const_int 127 [0x7f]))) 2 {*cmpsi_1_insn} (nil)
    (nil))

(jump_insn 18 17 20 1 (set (pc)
        (if_then_else (gtu (reg:CC 17 flags)
                (const_int 0 [0x0]))
            (label_ref 30)
            (pc))) 350 {*jcc_1} (nil)
    (expr_list:REG_BR_PROB (const_int 4949 [0x1355])
        (nil)))
;; End of basic block 1, registers live:
 (nil)

;; Start of basic block 2, registers live: (nil)
(note 20 18 24 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn 24 20 25 2 (parallel [
            (set (reg:SI 66)
                (mult:SI (reg:SI 59 [ ivtmp.34 ])
                    (const_int 3 [0x3])))
            (clobber (reg:CC 17 flags))
        ]) 182 {*mulsi3_1} (nil)
    (nil))

(insn 25 24 26 2 (set (reg:QI 61 [ D.1324 ])
        (mem/s/v:QI (plus:SI (reg:SI 66)
                (symbol_ref:SI ("s") <var_decl 0x556e30b0 s>)) [0 s S1 A8])) 
43 {*movqi_1} (nil)
    (nil))

Loop from 65 to 66: 10 real insns.
Biv 59: insn 32 const (1)
Biv 59: verified
Biv 59: initialized at insn 13: initial value (-127)
Giv 66: insn 24 src reg 59 benefit 12 lifetime 1 replaceable ncav
 mult (3)
 add  (0)
Dest address: insn 25 src reg 59 benefit 11 lifetime 1 replaceable
 mult (3)
 add  (symbol_ref ("s") <var_decl 0x556e30b0 s>)
biv 59 can be eliminated.

because biv 59 is eliminated to giv 66:

(insn 71 12 72 0 (set (reg/f:SI 71)
        (symbol_ref:SI ("s") <var_decl 0x556e30b0 s>)) -1 (nil)
    (nil))

(insn 72 71 75 0 (parallel [
            (set (reg/f:SI 70)
                (plus:SI (reg/f:SI 71)
                    (const_int -381 [0xfffffe83])))
            (clobber (reg:CC 17 flags))
        ]) -1 (nil)
    (nil))

(insn 75 72 76 0 (set (reg/f:SI 74)
        (symbol_ref:SI ("s") <var_decl 0x556e30b0 s>)) -1 (nil)
    (nil))

(insn 76 75 77 0 (parallel [
            (set (reg/f:SI 73)
                (plus:SI (reg/f:SI 74)
                    (const_int 381 [0x17d])))
            (clobber (reg:CC 17 flags))
        ]) -1 (nil)
    (nil))

(note 65 78 14 NOTE_INSN_LOOP_BEG)

;; Start of basic block 1, registers live: (nil)
(code_label 14 65 15 1 2 "" [1 uses])

(note 15 14 17 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn 17 15 18 1 (set (reg:CC 17 flags)
        (compare:CC (reg/f:SI 70)
            (reg/f:SI 73))) -1 (nil)
    (nil))

(jump_insn 18 17 20 1 (set (pc)
        (if_then_else (gtu (reg:CC 17 flags)
                (const_int 0 [0x0]))
            (label_ref 30)
            (pc))) -1 (nil)
    (expr_list:REG_BR_PROB (const_int 4949 [0x1355])
        (nil)))
;; End of basic block 1, registers live:
 (nil)

but of course the unsigned comparison s-381 < s+381 for s a global symbol is 
generically true so the giv doesn't wrap around anymore.


It's a refinement of PR rtl-optimization/23560 fixed by:
  http://gcc.gnu.org/ml/gcc-patches/2005-08/msg01550.html
but I think the fix is slightly incorrect as explained in:
  http://gcc.gnu.org/ml/gcc-patches/2006-08/msg00365.html

Hence the attached patch.  Bootstrapped/regtested on x86_64-suse-linux (4.1 
branch), not yet applied (waiting for RTH's reply to above message).


2006-08-11  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR rtl-optimization/28386
	* loop.c (biased_biv_may_wrap_p): Rename to biv_may_wrap_p and
	remove 'bias' parameter.
	(maybe_eliminate_biv_1): Adjust for above change.


2006-08-11  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* gcc.c-torture/execute/20060811-1.c: New test


-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr28386.diff
Type: text/x-diff
Size: 1938 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060811/90934063/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr28386.c
Type: text/x-csrc
Size: 411 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060811/90934063/attachment-0001.bin>


More information about the Gcc-patches mailing list