Re: Optimisations and undefined behaviour

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 08/11/15 18:17, Vincent Lefevre wrote:
On 2015-11-08 16:14:56 +0100, David Brown wrote:
I got close with a dont_care() :

static inline int dont_care(void) {
     int x;
     asm ("" : "=r" (x) : );
     return x;
}

This lets gcc "generate" an int without any instructions.  But the compiler
doesn't know that you don't care what value it has, so this won't let the
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
compiler eliminate the conditional in :

int foo(int x) {
	if (x < 1000) {
		return x * x * x;
	} else {
		return dont_care();
	}
}

I don't think that this is the problem here. First, the conditional
could be eliminated only if the code is in the x < 1000 case does not
have side effects (such as traps in case of overflow). Moreover, even
if the compiler knows that it is safe to do the transformation, would
it know that doing it would yield faster code? This is not obvious.


The compiler knows that the code in the "x * x * x" branch is without side-effects or traps. It also knows that omitting the conditional leads to smaller and faster code. But what it does not know, is if the /asm/ instruction has side effects or not. That, I think, is why the comparison is kept.

IMHO, the right thing to do is to have a way to instruct the compiler
that the multiplication has some defined behavior even in case of
overflow. Something like -fwrapv. However, the problems with -fwrapv
is that it is not part of the semantic of the code and that it is
global.

That would not help, as it is not the behaviour of the integer multiplication that matters. (Changing to unsigned int, which has no undefined behaviour on overflow, does not make a difference.)


Another option is:

static inline int dont_care2(void) {
	int x = x;
	return x;
}

But that sometimes ends up with an unnecessary setting of x to 0.

And this is also undefined behavior.


You are correct as far as I can see. gcc (and many other compilers) can accept this syntax as a way of avoiding warnings about data that might be used uninitialised, but actually /using/ the self-initialised variable is undefined behaviour, I think.

So I am still searching for an unspecified, but not undefined, int generator.




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux