http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51408
Bug #: 51408 Summary: Miscompilation in arm.md:*minmax_arithsi Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: k...@gcc.gnu.org The following testcase, reduced from efgcvt_r.c:fcvt_r in glibc, gets miscompiled: extern void abort (void); int __attribute__((noinline)) foo (int a, int b) { int max = (b > 0) ? b : 0; return max - a; } int main (void) { if (foo (3, -1) != -3) abort (); return 0; } arm-none-eabi-gcc -O1 generates: foo: @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. cmp r1, #0 rsbge r0, r0, r1 bx lr This would be equivalent to: return b >= 0 ? b - a : a; which is different from: return b >= 0 ? b - a : -a; That is, in assembly code, we should have an "else" clause like so: cmp r1, #0 rsbge r0, r0, r1 <- then clause rsblt r0, r0, #0 <- else clause bx lr This bug comes from gcc/config/arm/arm.md:*minmax_arithsi, not outputting an else clause on the MINUS case. I've tested a patch and will post it shortly.