public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* signed int performance question
@ 2017-02-28  6:38 Eyal Itkin
  2017-02-28  9:36 ` Liu Hao
  2017-02-28  9:43 ` Andrew Haley
  0 siblings, 2 replies; 3+ messages in thread
From: Eyal Itkin @ 2017-02-28  6:38 UTC (permalink / raw)
  To: gcc

Hello,

I wanted to ask a question regarding the compilation of code samples
like the following:
"
int a = fetch_value();
int b = fetch_value();
int c = SOME_BIG_CONSTANT;

if ( c - b < a)
{
    ... <error case>
}

pass_value(a + b);
return a + b;
"
The value "a + b" is used 3 times in this snippet, while the first use
is hidden in the if check. It seems that changing the if check to "if
( c < a + b ) " will allow the compiler to generate a more efficient
assembly code: 1 addition, used 3 times. However in all of my checks,
all GCC versions will prefer to calculate both the subtraction and the
addition, and to only use the addition's result 2 times.

I know that the case with unsigned integers is that all operations are
done in a modulu 2 ^ 32, and so changing the condition will change the
logical meaning of the check.
However, in signed integers, the logical meaning of any relation check
is only the theoretical meaning of the order relation between the
numbers in the group Z. Meaning that in a purely theoretical manner "a
+ b < c" is a relation order that is equivalent to "a < c - b" or even
" 0 < c - b - a". The only exception here is about any possible
integer overflow (above MAX_INT) or underflow (below MIN_INT), however
such cases are specified to be undefined in the C standard, and should
not harm the possible efficiency of the code generation.

Since a C programmer that follows the standard, and writes such a code
check, means only to check relations between 3 signed numbers in the
group Z, is there a reason why not to update the if check and to
generate a more efficient code? In addition, is there a way to
optionally raise warning in similar cases, so to warn against possible
signed integer overflows, in case the programmer is not aware of the
dangers in his code.

Thanks for your time,
Eyal.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: signed int performance question
  2017-02-28  6:38 signed int performance question Eyal Itkin
@ 2017-02-28  9:36 ` Liu Hao
  2017-02-28  9:43 ` Andrew Haley
  1 sibling, 0 replies; 3+ messages in thread
From: Liu Hao @ 2017-02-28  9:36 UTC (permalink / raw)
  To: Eyal Itkin, gcc

On 2017/2/28 14:38, Eyal Itkin wrote:
> Hello,
>
> I wanted to ask a question regarding the compilation of code samples
> like the following:
> "
> int a = fetch_value();
> int b = fetch_value();
> int c = SOME_BIG_CONSTANT;
>
> if ( c - b < a)
> {
>     ... <error case>
> }
>
> pass_value(a + b);
> return a + b;
> "
> The value "a + b" is used 3 times in this snippet, while the first use
> is hidden in the if check. It seems that changing the if check to "if
> ( c < a + b ) " will allow the compiler to generate a more efficient
> assembly code: 1 addition, used 3 times. However in all of my checks,
> all GCC versions will prefer to calculate both the subtraction and the
> addition, and to only use the addition's result 2 times.
I am not sure but I believe that on some targets if (a + b) does 
overflow you get an interrupt/exception. So these two expressions aren't 
equivalent.

> I know that the case with unsigned integers is that all operations are
> done in a modulu 2 ^ 32, and so changing the condition will change the
> logical meaning of the check.
> However, in signed integers, the logical meaning of any relation check
> is only the theoretical meaning of the order relation between the
> numbers in the group Z. Meaning that in a purely theoretical manner "a
> + b < c" is a relation order that is equivalent to "a < c - b" or even
> " 0 < c - b - a".
What does 'in a purely theoretical manner' mean? In purely mathematical 
manner it may make sense, but in purely C programmatical manner it 
doesn't make any sense at all.

> The only exception here is about any possible
> integer overflow (above MAX_INT) or underflow (below MIN_INT), however
> such cases are specified to be undefined in the C standard, and should
> not harm the possible efficiency of the code generation.
The original code doesn't contain any UB given (c - b) does not 
underflow. You are no willing to transform code that doesn't contain UB 
into code that contains UB, are you?

> Since a C programmer that follows the standard, and writes such a code
> check, means only to check relations between 3 signed numbers in the
> group Z, is there a reason why not to update the if check and to
> generate a more efficient code?
Just because we might be more efficient doesn't mean we should introduce UB.

> In addition, is there a way to
> optionally raise warning in similar cases, so to warn against possible
> signed integer overflows, in case the programmer is not aware of the
> dangers in his code.
I am not sure what you want but there is an option `-Wstrict-overflow` 
that you may be interested in. Care must be taken that 
`-Wstrict-overflow=3` or above generates a lot of false warnings.

-- 
Best regards,
LH_Mouse

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: signed int performance question
  2017-02-28  6:38 signed int performance question Eyal Itkin
  2017-02-28  9:36 ` Liu Hao
@ 2017-02-28  9:43 ` Andrew Haley
  1 sibling, 0 replies; 3+ messages in thread
From: Andrew Haley @ 2017-02-28  9:43 UTC (permalink / raw)
  To: Eyal Itkin, gcc

On 28/02/17 06:38, Eyal Itkin wrote:
> However, in signed integers, the logical meaning of any relation check
> is only the theoretical meaning of the order relation between the
> numbers in the group Z. Meaning that in a purely theoretical manner "a
> + b < c" is a relation order that is equivalent to "a < c - b" or even
> " 0 < c - b - a". The only exception here is about any possible
> integer overflow (above MAX_INT) or underflow (below MIN_INT), however
> such cases are specified to be undefined in the C standard, and should
> not harm the possible efficiency of the code generation.

We can't change arithmetic which does not overflow into arithmetic
which might.  We re-order operations where we know that it's safe
to do so, but this one does not look safe to me.

Andrew.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-02-28  9:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-28  6:38 signed int performance question Eyal Itkin
2017-02-28  9:36 ` Liu Hao
2017-02-28  9:43 ` Andrew Haley

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).