https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114041
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Ah, but unsigned a[24], b[24]; enum E { E0 = 0, E1 = 1, E42 = 42, E56 = 56 }; __attribute__((noipa)) unsigned foo (enum E x) { for (int i = 0; i < 24; ++i) a[i] = i; unsigned e; if (x >= E42) e = __builtin_clz ((unsigned) x); else e = 42; for (int i = 0; i < 24; ++i) b[i] = i; return e; } int main () { if (foo (E1) != 42 || foo (E56) != __SIZEOF_INT__ * __CHAR_BIT__ - 6) __builtin_abort (); } fails as well. So, dunno if it shouldn't be testing for INTEGRAL_TYPE_P, or be dropped altogether (when the check was added in r6-2239-g4bc4dd11ec8c7be528abcb75a1af715d715b4835, parameter_index_in_region punted on anything but INTEGER_TYPE, but that is gone from there for years). What about floating point compares, vector compares, etc.? Although unsigned a[24], b[24]; __attribute__((noipa)) unsigned foo (float x) { for (int i = 0; i < 24; ++i) a[i] = i; unsigned e; if (x >= 42.0) e = x; else e = 15; for (int i = 0; i < 24; ++i) b[i] = i; return e; } int main () { if (foo (1.0f) != 15 || foo (45.0f) != 45) __builtin_abort (); } doesn't fail.