* On -ftrapv vs. libcalls...
@ 2004-08-31 13:50 Steven Bosscher
2004-08-31 14:48 ` Zdenek Dvorak
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Steven Bosscher @ 2004-08-31 13:50 UTC (permalink / raw)
To: gcc
Hi,
Could anyone please help me get some insight into the following
problem.
Consider,
int
mulv(int a, int b)
{
return a * b;
}
compiled with -ftrapv. This gives the following code in the .rtl dump
on ia64.
(insn 18 17 19 1 (set (reg:DI 120 out0)
(reg:DI 345)) -1 (nil)
(insn_list:REG_LIBCALL 21 (nil)))
(insn 19 18 20 1 (set (reg:DI 121 out1)
(reg:DI 347)) -1 (nil)
(nil))
(call_insn/u 20 19 21 1 (parallel [
(set (reg:DI 8 r8)
(call (mem:DI (symbol_ref:DI ("__mulvdi3") [flags 0x41]) [0 S8 A64])
(const_int 1 [0x1])))
(clobber (reg:DI 320 b0))
(clobber (scratch:DI))
(clobber (scratch:DI))
]) -1 (nil)
(expr_list:REG_EH_REGION (const_int -1 [0xffffffffffffffff])
(nil))
(expr_list (use (reg:DI 1 r1))
(expr_list (use (reg:DI 121 out1))
(expr_list (use (reg:DI 120 out0))
(nil)))))
(insn 21 20 22 1 (set (reg:DI 349)
(reg:DI 8 r8)) -1 (nil)
(insn_list:REG_RETVAL 18 (expr_list:REG_EQUAL (mult:DI (reg:DI 345)
(reg:DI 347))
(nil))))
Note the __mulvdi3 libcall. At the first opportunity to do so, the
first jump pass, we collapse it to a normal MULT insn:
(insn 16 15 17 0 (set (reg:SI 348 [ b ])
(mem/i:SI (reg/f:DI 344) [0 b+0 S4 A32])) -1 (nil)
(nil))
(insn 17 16 21 0 (set (reg:DI 347 [ b ])
(sign_extend:DI (reg:SI 348 [ b ]))) -1 (nil)
(nil))
(insn 21 17 22 0 (set (reg:DI 349)
(mult:DI (reg:DI 345 [ a ])
(reg:DI 347 [ b ]))) 105 {muldi3} (nil)
(nil))
(insn 22 21 23 0 (set (reg:SI 339 [ T.0 ])
(subreg:SI (reg:DI 349) 0)) -1 (nil)
(nil))
[ this also happens on x86 and amd64, but there the problem is not
as obvious - apparently ia64 doesn't even have that function in
libgcc so it causes a link failure without libcall notes. ]
Without -ftrapv we never emit it, we just always generate a normal
MULT insn, never the libcall:
(insn 14 13 15 1 (set (reg:SI 345)
(mem/i:SI (reg/f:DI 335 virtual-stack-vars) [0 a+0 S4 A32])) -1 (nil)
(nil))
(insn 15 14 16 1 (set (reg:SI 346)
(mem/i:SI (reg/f:DI 344) [0 b+0 S4 A32])) -1 (nil)
(nil))
(insn 16 15 17 1 (set (reg:SI 339 [ T.0 ])
(mult:SI (reg:SI 345)
(reg:SI 346))) -1 (nil)
(nil))
I'm trying to get rid of libcall notes, so I would really like to know
and understand why we emit a libcall with -ftrapv. With my patch, we
cannot fold the libcall anymore, so it's a show stopper for removing
libcalls that we emit the (apparently?) unnecessary libcall.
Is there a way to avoid emiting a libcall in this case?
Not emitting the libcall would be good in any case since it would
improve the initially generated RTL with -ftrapv...
Gr.
Steven
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: On -ftrapv vs. libcalls...
2004-08-31 13:50 On -ftrapv vs. libcalls Steven Bosscher
@ 2004-08-31 14:48 ` Zdenek Dvorak
2004-08-31 19:18 ` James E Wilson
2004-08-31 18:28 ` Joern Rennecke
2004-08-31 20:21 ` Richard Henderson
2 siblings, 1 reply; 6+ messages in thread
From: Zdenek Dvorak @ 2004-08-31 14:48 UTC (permalink / raw)
To: Steven Bosscher; +Cc: gcc
Hello,
> Could anyone please help me get some insight into the following
> problem.
>
> Consider,
>
> int
> mulv(int a, int b)
> {
> return a * b;
> }
>
> compiled with -ftrapv. This gives the following code in the .rtl dump
> on ia64.
>
> (insn 18 17 19 1 (set (reg:DI 120 out0)
> (reg:DI 345)) -1 (nil)
> (insn_list:REG_LIBCALL 21 (nil)))
>
> (insn 19 18 20 1 (set (reg:DI 121 out1)
> (reg:DI 347)) -1 (nil)
> (nil))
>
> (call_insn/u 20 19 21 1 (parallel [
> (set (reg:DI 8 r8)
> (call (mem:DI (symbol_ref:DI ("__mulvdi3") [flags 0x41]) [0 S8 A64])
> (const_int 1 [0x1])))
> (clobber (reg:DI 320 b0))
> (clobber (scratch:DI))
> (clobber (scratch:DI))
> ]) -1 (nil)
> (expr_list:REG_EH_REGION (const_int -1 [0xffffffffffffffff])
> (nil))
> (expr_list (use (reg:DI 1 r1))
> (expr_list (use (reg:DI 121 out1))
> (expr_list (use (reg:DI 120 out0))
> (nil)))))
>
> (insn 21 20 22 1 (set (reg:DI 349)
> (reg:DI 8 r8)) -1 (nil)
> (insn_list:REG_RETVAL 18 (expr_list:REG_EQUAL (mult:DI (reg:DI 345)
> (reg:DI 347))
> (nil))))
>
>
> Note the __mulvdi3 libcall. At the first opportunity to do so, the
> first jump pass, we collapse it to a normal MULT insn:
>
> (insn 16 15 17 0 (set (reg:SI 348 [ b ])
> (mem/i:SI (reg/f:DI 344) [0 b+0 S4 A32])) -1 (nil)
> (nil))
>
> (insn 17 16 21 0 (set (reg:DI 347 [ b ])
> (sign_extend:DI (reg:SI 348 [ b ]))) -1 (nil)
> (nil))
>
> (insn 21 17 22 0 (set (reg:DI 349)
> (mult:DI (reg:DI 345 [ a ])
> (reg:DI 347 [ b ]))) 105 {muldi3} (nil)
> (nil))
> (insn 22 21 23 0 (set (reg:SI 339 [ T.0 ])
> (subreg:SI (reg:DI 349) 0)) -1 (nil)
> (nil))
>
> [ this also happens on x86 and amd64, but there the problem is not
> as obvious - apparently ia64 doesn't even have that function in
> libgcc so it causes a link failure without libcall notes. ]
>
> Without -ftrapv we never emit it, we just always generate a normal
> MULT insn, never the libcall:
>
> (insn 14 13 15 1 (set (reg:SI 345)
> (mem/i:SI (reg/f:DI 335 virtual-stack-vars) [0 a+0 S4 A32])) -1 (nil)
> (nil))
>
> (insn 15 14 16 1 (set (reg:SI 346)
> (mem/i:SI (reg/f:DI 344) [0 b+0 S4 A32])) -1 (nil)
> (nil))
>
> (insn 16 15 17 1 (set (reg:SI 339 [ T.0 ])
> (mult:SI (reg:SI 345)
> (reg:SI 346))) -1 (nil)
> (nil))
>
> I'm trying to get rid of libcall notes, so I would really like to know
> and understand why we emit a libcall with -ftrapv. With my patch, we
> cannot fold the libcall anymore, so it's a show stopper for removing
> libcalls that we emit the (apparently?) unnecessary libcall.
>
> Is there a way to avoid emiting a libcall in this case?
>
> Not emitting the libcall would be good in any case since it would
> improve the initially generated RTL with -ftrapv...
my understanding is that with -ftrapv we call the library function that
causes trap on overflow -- on rtl we no longer know whether the operands
of multiplication are unsigned or not, so we cannot emit MULT for it.
What I do not understand is why it is legal to turn the libcall back
into MULT.
Zdenek
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: On -ftrapv vs. libcalls...
2004-08-31 13:50 On -ftrapv vs. libcalls Steven Bosscher
2004-08-31 14:48 ` Zdenek Dvorak
@ 2004-08-31 18:28 ` Joern Rennecke
2004-08-31 20:21 ` Richard Henderson
2 siblings, 0 replies; 6+ messages in thread
From: Joern Rennecke @ 2004-08-31 18:28 UTC (permalink / raw)
To: Steven Bosscher; +Cc: gcc
> Note the __mulvdi3 libcall. At the first opportunity to do so, the
> first jump pass, we collapse it to a normal MULT insn:
Which is actually a bug. basic arithmetic traps on signed overflow with
-ftrapv. There is no place for the trap_if side effect in the REG_EQUAL
note, hence these operations are unsuitable to wrap then with
REG_LIBCALL / REG_RETVAL / REG_EQUAL (at least in their current form).
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: On -ftrapv vs. libcalls...
2004-08-31 14:48 ` Zdenek Dvorak
@ 2004-08-31 19:18 ` James E Wilson
2004-09-01 12:12 ` Joern Rennecke
0 siblings, 1 reply; 6+ messages in thread
From: James E Wilson @ 2004-08-31 19:18 UTC (permalink / raw)
To: Zdenek Dvorak; +Cc: gcc
Zdenek Dvorak wrote:
> What I do not understand is why it is legal to turn the libcall back
> into MULT.
Because there is a REG_EQUAL note that claims the mulvdi3 result is
exactly equivalent to an ordinary multiply. If it isn't exactly the
same as an ordinary multiply, then the REG_EQUAL note should not be
there. Or else the REG_EQUAL note should be changed to be accurate, but
that would probably require creating a new RTL operator, e.g. multv.
--
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: On -ftrapv vs. libcalls...
2004-08-31 13:50 On -ftrapv vs. libcalls Steven Bosscher
2004-08-31 14:48 ` Zdenek Dvorak
2004-08-31 18:28 ` Joern Rennecke
@ 2004-08-31 20:21 ` Richard Henderson
2 siblings, 0 replies; 6+ messages in thread
From: Richard Henderson @ 2004-08-31 20:21 UTC (permalink / raw)
To: Steven Bosscher; +Cc: gcc
On Tue, Aug 31, 2004 at 03:22:49PM +0200, Steven Bosscher wrote:
> Note the __mulvdi3 libcall. At the first opportunity to do so, the
> first jump pass, we collapse it to a normal MULT insn:
That is a bug.
> Is there a way to avoid emiting a libcall in this case?
If the target doesn't have a mulv pattern, then it could be
emulated with a widening multiply, compare, branch, and trap.
Targets like x86 could define a mulv expander to use a trap
on overflow instruction.
r~
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: On -ftrapv vs. libcalls...
2004-08-31 19:18 ` James E Wilson
@ 2004-09-01 12:12 ` Joern Rennecke
0 siblings, 0 replies; 6+ messages in thread
From: Joern Rennecke @ 2004-09-01 12:12 UTC (permalink / raw)
To: James E Wilson; +Cc: Zdenek Dvorak, gcc
> there. Or else the REG_EQUAL note should be changed to be accurate, but
> that would probably require creating a new RTL operator, e.g. multv.
No, that wouldn't work, because REG_EQUAL describes a value, but never
a side effect.
In general, a mulv can't be hoisted out of a loop that might have zero
iterations, but that is not apparent when you have a LIBCALL / RETVAL
sequence with only a REG_EQUAL note to describe the computation.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-09-01 12:12 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-31 13:50 On -ftrapv vs. libcalls Steven Bosscher
2004-08-31 14:48 ` Zdenek Dvorak
2004-08-31 19:18 ` James E Wilson
2004-09-01 12:12 ` Joern Rennecke
2004-08-31 18:28 ` Joern Rennecke
2004-08-31 20:21 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).