On 06/18/2010 10:11 AM, Georg Lay wrote: > Andrew Haley schrieb: >> On 06/18/2010 08:56 AM, Georg Lay wrote: >>> Hi, I have a question on gcc's signed overflow optimisation in the >>> following C function: >>> >>> int abssat2 (int x) >>> { >>> unsigned int y = x; >>> >>> if (x < 0) >>> y = -y; >>> >>> if (y >= 0x80000000) >>> y--; >>> >>> return y; >>> } >>> >>> gcc optimises the second comparison and throws it away, and that's the >>> part I do not understand because all computations are performed on >>> unsigned int which has no undefined behaviour on overflow. >>> >>> For the unary - the standard says in 6.5.3.3.3: >>> The result of the unary - operator is the negative of its (promoted) >>> operand. The integer promotions are performed on the operand, and >>> the result has the promoted type. >>> >>> And the promotion rules in 6.3.1.1.2: >>> If an int can represent all values of the original type, the value >>> is converted to an int; otherwise, it is converted to an unsigned int. >>> These are called the integer promotions. All other types are unchanged >>> by the integer promotions. >>> >>> As an int cannot represent all values that can be represented by an >>> unsigned int, there is no signed int in the line y = -y. >>> >>> Could anyone explain this? I see this on gcc 4.4.3. >> >> Works for me on gcc 4.4.3: >> >> movl %edi, %eax >> sarl $31, %eax >> xorl %eax, %edi >> subl %eax, %edi >> movl %edi, %eax >> shrl $31, %eax >> subl %eax, %edi >> movl %edi, %eax > > Ok. Is your code as it should be on any machine or is it just a "missed > optimisation"? Your problem sounds to me like incorrect code, not missed optimization. > I observe it on a non-standard embedded target that has an abs > instruction, i.e. there is an abssi2 insn that leads to abs:SI rtx. > Maybe there is some standard target that also has native support of abs > to see what happens there? Perhaps. I think the problem may be that abs is being generated incorrectly. What does -fdump-tree-optimized look like? > Or is my confusion based on some misunderstandings of the language > standard? Your code is correct as far as I can see. I don't get any warnings with -Wstrict-overflow. Andrew. ;; Function abssat2 (abssat2) Analyzing Edge Insertions. abssat2 (int x) { int prephitmp.15; unsigned int y; <bb 2>: y = (unsigned int) x; if (x < 0) goto <bb 3>; else goto <bb 4>; <bb 3>: y = -y; <bb 4>: prephitmp.15 = (int) y; if (prephitmp.15 < 0) goto <bb 5>; else goto <bb 6>; <bb 5>: prephitmp.15 = (int) (y + 4294967295); <bb 6>: return prephitmp.15; }