[PATCH] Index expmed.c's shift_cost by machine mode

Eric Botcazou ebotcazou@libertysurf.fr
Sun Jun 13 19:47:00 GMT 2004


> 2004-06-12  Roger Sayle  <roger@eyesopen.com>
>
> 	* expmed.c (shift_cost, shiftadd_cost, shiftsub_cost): Additionally
> 	index by machine mode.
> 	(init_expmed): Initialize shift_cost, shiftadd_cost and shiftsub_cost
> 	tables inside the loop over machine modes.
> 	(synth_mult, expand_mult_highpart_optab, expand_mult_highpart,
> 	expand_divmod): Index shift*_cost by the appropriate machine mode.

Broke bootstrap on SPARC 64-bit: lshift_significand is miscompiled.

It's specifically these lines:

> ! 	n = MIN (MAX_BITS_PER_WORD, GET_MODE_BITSIZE (mode));
> 	for (m = 1; m < n; m++)

This means that, on 64-bit targets, shifts by 32 in SImode have zero cost.  
So they are chosen in synt_mult when multiplying by -1 because the clamp is 
on BITS_PER_WORD, not GET_MODE_BITSIZE (mode):

      if (t % d == 0 && t > d && m < BITS_PER_WORD)

Then expand_shift enters the game and returns its unmodified argument.  So we 
end up with this RTL in 09.loop at -O2:

(insn 176 165 177 (set (reg:SI 169 [ ofs ])
        (reg/v:SI 113 [ ofs ])) -1 (nil)
    (nil))

(insn 177 176 178 (set (reg:SI 170)
        (minus:SI (reg:SI 169 [ ofs ])
            (reg/v:SI 113 [ ofs ]))) -1 (nil)
    (expr_list:REG_EQUAL (mult:SI (reg/v:SI 113 [ ofs ])
            (const_int 4294967295 [0xffffffff]))
        (nil)))

(insn 178 177 179 (set (reg:SI 171)
        (plus:SI (reg:SI 170)
            (reg:SI 170))) -1 (nil)
    (expr_list:REG_EQUAL (mult:SI (reg/v:SI 113 [ ofs ])
            (const_int -1 [0xffffffffffffffff]))
        (nil)))

(insn 179 178 181 (set (reg:SI 168)
        (plus:SI (reg:SI 171)
            (const_int 1 [0x1]))) -1 (nil)
    (nil))

(insn 181 179 183 (set (reg:SI 172)
        (neg:SI (reg/v:SI 113 [ ofs ]))) -1 (nil)
    (nil))

(insn 183 181 184 (set (reg:SI 174 [ ofs ])
        (reg/v:SI 113 [ ofs ])) -1 (nil)
    (nil))

(insn 184 183 185 (set (reg:SI 175)
        (minus:SI (reg:SI 174 [ ofs ])
            (reg/v:SI 113 [ ofs ]))) -1 (nil)
    (expr_list:REG_EQUAL (mult:SI (reg/v:SI 113 [ ofs ])
            (const_int 4294967295 [0xffffffff]))
        (nil)))

(insn 185 184 186 (set (reg:SI 176)
        (plus:SI (reg:SI 175)
            (reg:SI 175))) -1 (nil)
    (expr_list:REG_EQUAL (mult:SI (reg/v:SI 113 [ ofs ])
            (const_int -1 [0xffffffffffffffff]))
        (nil)))

for

  (mult:SI (reg/v:SI 113 [ ofs ]) (const_int -1))


Testcase attached, miscompiled by cross to sparc64-sun-solaris2.9 at -O2.


Restoring the original line

	for (m = 1; m < MAX_BITS_PER_WORD; m++)

fixes the problem.


Do you want to try anything else or can I commit the fix after testing?

-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: real_bug.c
Type: text/x-csrc
Size: 1582 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20040613/2e33ddd7/attachment.bin>


More information about the Gcc-patches mailing list