[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