As discussed in http://gcc.gnu.org/ml/gcc-help/2010-06/msg00191.html I am filing a PR for the following piece of C: int abssat2 (int x) { unsigned int y = x; if (x < 0) y = -y; if (y >= 0x80000000) y--; return y; } Code looks fine until pass CE1 which introduces ABS rtx for the first comparison (ifcvt.c:noce_try_abs). Pass insn combine then calls combine.c:combine_simplify_rtx() which calls simplify_rtx.c:simplify_relational_operation (code=LT, mode=SImode, cmp_mode=SImode, op0=(abs:SI (reg:SI)), op1=(const_int 0)) and the latter removes the second comparison against 0x80000000. As this problem occurs on a non-standard target, let me know if I con you provide with any additional information.
Created attachment 20955 [details] Dump for .c.123t.optimized Dump for .c.123t.optimized
Created attachment 20956 [details] Dump for .c.128r.expand Dump for .c.128r.expand
Created attachment 20957 [details] Dump for .c.141r.ce1 Dump for .c.141r.ce1
Created attachment 20958 [details] Dump for .c.159r.combine Dump for .c.159r.combine
It is folding from the frontend that changes if (y >= 0x80000000) to if ((int) y < 0) (see code == LT instead of code == GEU) But the main issue is that y = -y to abs is bogus (but we can't easily tell that as on RTL operands do not have a signedness).
int __attribute__((noinline)) abssat2 (int x) { unsigned int y = x; if (x < 0) y = -y; if (y >= 0x80000000) y--; return y; } extern void abort (void); int main() { if (abssat2 (0x80000000) != 0x7fffffff) abort (); return 0; } does not fail on x86_64 or i?86.
(In reply to comment #5) > It is folding from the frontend that changes > > if (y >= 0x80000000) > > to > > if ((int) y < 0) > > (see code == LT instead of code == GEU) > > But the main issue is that y = -y to abs is bogus (but we can't easily tell > that as on RTL operands do not have a signedness). Both transformation are ok from the target's point of view. The bad thing is that undefinedness is propagated to RTL which is supposed to be an algebraic formulation of the target's instruction set. But in this case RTL is treated like a low level representation of C (or any other language gcc supports). To reproduce the problem it seems essential that there is an abssi2 insn in the md.
For some reason rs6000 has an abssi pattern but it is not produced by ce1.
This has been fixed since GCC 7.2 in the end. This is a dup of bug 75964. *** This bug has been marked as a duplicate of bug 75964 ***