Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   check integer overflow with GCC 4.5.2 (http://www.velocityreviews.com/forums/t806226-check-integer-overflow-with-gcc-4-5-2-a.html)

sailer 11-24-2011 04:38 AM

check integer overflow with GCC 4.5.2
 
Hi,

I have the following code which was used to check whether the result
of (a * b) is larger than the maximum integer value.

ovf(int a, int b, int *r, int *v)
{
*r = a * b;
if (b == 0 || a == *r / b)
*v = 0;
else
*v = 1;

}

int main()
{
int words;
int bytes;
int overflow;

//... whatever
ovf(words, sizeof(int), &bytes, &overflow);
if (overflow)
printf("overflow");

}

It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
generated by GCC is as follows, call to ovf is eliminated, seems
that
GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
to
revise ovf to let it satisfy GCC? thanks in advance.

main:
pushl %ebp #
xorl %eax, %eax #
movl %esp, %ebp #,
popl %ebp #
ret
.size main, .-main
.ident "GCC: (GNU) 4.5.2"
.section .note.GNU-stack,"",@progbits

Tobias Müller 11-24-2011 06:46 AM

Re: check integer overflow with GCC 4.5.2
 
sailer <xiangdong.ji@gmail.com> wrote:
> Hi,
>
> I have the following code which was used to check whether the result
> of (a * b) is larger than the maximum integer value.
>
> ovf(int a, int b, int *r, int *v)
> {
> *r = a * b;
> if (b == 0 || a == *r / b)
> *v = 0;
> else
> *v = 1;
>
> }
>
> int main()
> {
> int words;
> int bytes;
> int overflow;
>
> //... whatever
> ovf(words, sizeof(int), &bytes, &overflow);
> if (overflow)
> printf("overflow");
>
> }
>
> It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> generated by GCC is as follows, call to ovf is eliminated, seems
> that
> GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
> to
> revise ovf to let it satisfy GCC? thanks in advance.
>
> main:
> pushl %ebp #
> xorl %eax, %eax #
> movl %esp, %ebp #,
> popl %ebp #
> ret
> .size main, .-main
> .ident "GCC: (GNU) 4.5.2"
> .section .note.GNU-stack,"",@progbits


The possibility of such optimizations is one reasons, why int overflow is
undefined behaviour.

The correctly formulated question (compiler neutral) would then be how to
implement this test without relying on UB. (some people on this list are a
bit picky about that)

You could take unsigned int instead, where overflow is defined:

ovf(int a, int b, unsigned int *r, int *v)
{
*r = (unsigned int)a * b;
if (b == 0 || (a == *r / b && r <= INT_MAX))
*v = 0;
else
*v = 1;
}

This is just to illustrate, notice however that:
- this is really C rather than C++
- it does not work for underflows
- it probably leads to compiler warnings without some more casts
- I have not tested it.
- there are probably more efficient ways of achieving the same thing

Tobi

sailer 11-24-2011 08:38 AM

Re: check integer overflow with GCC 4.5.2
 
On Nov 24, 2:46*pm, Tobias Müller <trop...@bluewin.ch> wrote:
> sailer <xiangdong...@gmail.com> wrote:
> > Hi,

>
> > I have the following code which was used to check whether *the result
> > *of (a * b) *is larger than the maximum integer value.

>
> > ovf(int a, int b, int *r, int *v)
> > *{
> > * * * * **r = a * b;
> > * * * * *if (b == 0 || a == *r / b)
> > * * * * * * * * **v = 0;
> > * * * * *else
> > * * * * * * * * **v = 1;

>
> > }

>
> > int main()
> > *{
> > * * *int words;
> > * * *int bytes;
> > * * *int overflow;

>
> > * * //... whatever
> > * * *ovf(words, sizeof(int), &bytes, &overflow);
> > * * *if (overflow)
> > * * * * printf("overflow");

>
> > }

>
> > It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> > *generated by GCC is as follows, call to ovf is eliminated, seems
> > that
> > *GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
> > to
> > *revise ovf to let it satisfy GCC? thanks in advance.

>
> > main:
> > * * * * *pushl * %ebp * *#
> > * * * * *xorl * *%eax, %eax * * *#
> > * * * * *movl * *%esp, %ebp * * *#,
> > * * * * *popl * *%ebp * *#
> > * * * * *ret
> > * * * * *.size * main, .-main
> > * * * * *.ident *"GCC: (GNU) 4.5.2"
> > * * * * *.section * * * *.note.GNU-stack,"",@progbits

>
> The possibility of such optimizations is one reasons, why int overflow is
> undefined behaviour.
>
> The correctly formulated question (compiler neutral) would then be how to
> implement this test without relying on UB. (some people on this list are a
> bit picky about that)
>
> You could take unsigned int instead, where overflow is defined:
>
> ovf(int a, int b, unsigned int *r, int *v)
> {
> * * * * * *r = (unsigned int)a * b;
> * * * * * if (b == 0 || (a == *r / b && r <= INT_MAX))
> * * * * * * * * * *v = 0;
> * * * * * else
> * * * * * * * * * *v = 1;
>
> }
>
> This is just to illustrate, notice however that:
> - this is really C rather than C++
> - it does not work for underflows
> - it probably leads to compiler warnings without some more casts
> - I have not tested it.
> - there are probably more efficient ways of achieving the same thing
>
> Tobi



Tobi,

Really appreciate your replying, it helps much in understanding the
background of the problem.
I gave a try to use unsigned and INT_MAX but failed to address the
issue, happened to find
add "__attribute__ ((noinline))" before ovf solves it.

Jorgen Grahn 11-24-2011 12:16 PM

Re: check integer overflow with GCC 4.5.2
 
On Thu, 2011-11-24, sailer wrote:
> Hi,
>
> I have the following code which was used to check whether the result
> of (a * b) is larger than the maximum integer value.

....

You posted the same(?) question to comp.lang.c. Please don't do it that
way; it wastes people's time. Cross-post instead of multi-post.

regards,
/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Tobias Müller 11-24-2011 05:33 PM

Re: check integer overflow with GCC 4.5.2
 
sailer <xiangdong.ji@gmail.com> wrote:
> Tobi,
>
> Really appreciate your replying, it helps much in understanding the
> background of the problem.
> I gave a try to use unsigned and INT_MAX but failed to address the
> issue, happened to find
> add "__attribute__ ((noinline))" before ovf solves it.


It solves it for now, but compilers will become better and your problem
will reappear...

The optimization can also be applied without inlining, it's just that the
compiler missed that opportunity.

If you are interested, here is a link to a good article about UB on the
llvm/clang compiler Blog (actually a serie 3 articles). It also covers your
case (integer overflow).
http://blog.llvm.org/2011/05/what-ev...ould-know.html

Tobi

Fred Zwarts \(KVI\) 11-25-2011 08:35 AM

Re: check integer overflow with GCC 4.5.2
 
"sailer" wrote in message
news:c615334d-aa61-47c6-b149-d51951dfd1bb@da3g2000vbb.googlegroups.com...
>
>Hi,
>
>I have the following code which was used to check whether the result
> of (a * b) is larger than the maximum integer value.
>
>ovf(int a, int b, int *r, int *v)
> {
> *r = a * b;
> if (b == 0 || a == *r / b)
> *v = 0;
> else
> *v = 1;
>
>}
>
>int main()
> {
> int words;
> int bytes;
> int overflow;
>
> //... whatever
> ovf(words, sizeof(int), &bytes, &overflow);
> if (overflow)
> printf("overflow");
>
>}
>
>It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> generated by GCC is as follows, call to ovf is eliminated, seems
>that
> GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
>to
> revise ovf to let it satisfy GCC? thanks in advance.


May be it helps to store the result of the multiplication i n a volatile
variable and use that variable in the division? Wouldn't that inhibit the
optimization?


sailer 11-28-2011 05:36 AM

Re: check integer overflow with GCC 4.5.2
 
On Nov 24, 4:38*pm, sailer <xiangdong...@gmail.com> wrote:
> On Nov 24, 2:46*pm, Tobias Müller <trop...@bluewin.ch> wrote:
>
>
>
>
>
> > sailer <xiangdong...@gmail.com> wrote:
> > > Hi,

>
> > > I have the following code which was used tocheckwhether *the result
> > > *of (a * b) *is larger than the maximumintegervalue.

>
> > > ovf(int a, int b, int *r, int *v)
> > > *{
> > > * * * * **r = a * b;
> > > * * * * *if (b == 0 || a == *r / b)
> > > * * * * * * * * **v = 0;
> > > * * * * *else
> > > * * * * * * * * **v = 1;

>
> > > }

>
> > > int main()
> > > *{
> > > * * *int words;
> > > * * *int bytes;
> > > * * *intoverflow;

>
> > > * * //... whatever
> > > * * *ovf(words, sizeof(int), &bytes, &overflow);
> > > * * *if (overflow)
> > > * * * * printf("overflow");

>
> > > }

>
> > > It doesn't work with GCC 4.5.2 if enabling -O2 or -O3, asm code
> > > *generated by GCC is as follows, call to ovf is eliminated, seems
> > > that
> > > *GCC evaluates (a == *r/b) to TRUE at compile time, is there anyway
> > > to
> > > *revise ovf to let it satisfy GCC? thanks in advance.

>
> > > main:
> > > * * * * *pushl * %ebp * *#
> > > * * * * *xorl * *%eax, %eax * * *#
> > > * * * * *movl * *%esp, %ebp * * *#,
> > > * * * * *popl * *%ebp * *#
> > > * * * * *ret
> > > * * * * *.size * main, .-main
> > > * * * * *.ident *"GCC: (GNU) 4.5.2"
> > > * * * * *.section * * * *.note.GNU-stack,"",@progbits

>
> > The possibility of such optimizations is one reasons, why intoverflowis
> > undefined behaviour.

>
> > The correctly formulated question (compiler neutral) would then be how to
> > implement this test without relying on UB. (some people on this list are a
> > bit picky about that)

>
> > You could take unsigned int instead, whereoverflowis defined:

>
> > ovf(int a, int b, unsigned int *r, int *v)
> > {
> > * * * * * *r = (unsigned int)a * b;
> > * * * * * if (b == 0 || (a == *r / b && r <= INT_MAX))
> > * * * * * * * * * *v = 0;
> > * * * * * else
> > * * * * * * * * * *v = 1;

>
> > }

>
> > This is just to illustrate, notice however that:
> > - this is really C rather than C++
> > - it does not work for underflows
> > - it probably leads to compiler warnings without some more casts
> > - I have not tested it.
> > - there are probably more efficient ways of achieving the same thing

>
> > Tobi

>
> Tobi,
>
> Really appreciate your replying, it helps much in understanding the
> background of the problem.
> I gave a try to use unsigned and INT_MAX but failed to address the
> issue, happened to find
> add "__attribute__ ((noinline))" before ovf solves it.


My mistake here, adding the attribute could force compiler to generate
call to 'ovf' but
the if-else code is still optimized out.


All times are GMT. The time now is 08:36 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.