This is reduced from a bug our kernel people hit. The problem is the use of asm volatile gotos inside a conditional, when the outgoing blocks of the asm-goto are itself both empty. Ala: ------------------------- snip --------------------------------------- /* { dg-do compile } */ /* { dg-final { scan-assembler-times "XXX" 2 } } */ static inline __attribute__((always_inline)) int dec_and_test (int *i) { asm volatile goto ("XXX %0, %l[cc_label]" : : "m" (*i) : "memory" : cc_label); return 0; cc_label: return 1; } extern int getit (int *); int f (int *i, int cond) { if (cond) { getit (0); if (dec_and_test (i)) getit (i); return 42; } if (dec_and_test (i)) (void)1; return getit (i); } ------------------ snap ---------------------------------------------- This should have two "XXX" in the resulting assembler, but will have only one with any optimization level. It's the RTL if conversion that removes the seemingly empty second dec_and_test(), because the then-block is empty and because it doesn't check that the removed jump really is only a jump without side effects. I don't know if it's a regression (it probably isn't as I don't see that ifcvt.c was touched with the introduction of asm gotos), but it at least affects trunk and 4.8.
Created attachment 33102 [details] Patch Possible patch for the problem. There are many predicates for testing various forms of jump, after pondering and reading the comments about various of them being deprecated, or leaving through only very specific forms of jumps I think that onlyjump_p is the best one (it only rejects jumps with additional non-dead side-effects).
Author: matz Date: Tue Jul 15 14:11:06 2014 New Revision: 212563 URL: https://gcc.gnu.org/viewcvs?rev=212563&root=gcc&view=rev Log: PR rtl-optimization/61772 * ifcvt.c (dead_or_predicable): Check jump to be free of side effects. testsuite/ * gcc.dg/torture/pr61772.c: New test. Added: trunk/gcc/testsuite/gcc.dg/torture/pr61772.c Modified: trunk/gcc/ChangeLog trunk/gcc/ifcvt.c trunk/gcc/testsuite/ChangeLog
Fixed.