https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103855
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- unsigned int optimized(unsigned int a, unsigned int b) { return (unsigned long long)a / b; } unsigned int unoptimized(unsigned int a, unsigned int b) { unsigned long long all = a; return all / b; } unsigned long long unoptimized1(unsigned int a, unsigned int b) { unsigned long long all = a; return all / b; } unsigned long long unoptimized2(unsigned long a, unsigned long b) { if (((unsigned int)a) != a) __builtin_unreachable(); if (((unsigned int)b) != b) __builtin_unreachable(); return a / b; } Is the full testcase, clang is able to handle all of them. GCC only handles the first one. If you just do the match.pd patch, unoptimized2 would be not handled. expmed.c (expand_divmod) is where the expansion happens from gimple to rtl.