https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112626
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- For non wrapping case: #define func(opname,op) int abs##opname (int a) { return __builtin_abs(a) op a; } func(le,<=) // a >= 0 func(lt,<) // false func(ge,>=) // true func(gt,>) // a < 0 func(eq,==) // a >= 0 func(ne,!=) // a < 0 For wrapping case: func(le_wrap,<=) // a <u -__INT_MAX__ func(lt_wrap,<) // false func(ge_wrap,>=) // true func(gt_wrap,>) // a >u -__INT_MAX__ func(eq_wrap,==) // a <u -__INT_MAX__ func(ne_wrap,!=) // a >u -__INT_MAX__ For ((unsigned)abs(a)) CMP ((unsigned)a) non-wrapping: ``` #define func1(opname,op) int abs##opname (int a) { return ((unsigned)__builtin_abs(a)) op (unsigned)a; } func1(le_u,<=) // true func1(lt_u,<) // a < 0 func1(ge_u,>=) // a >= 0 func1(gt_u,>) // false func1(eq,==) // a >= 0 func1(ne,!=) // a < 0 ``` wrapping case: true and false still are true and false.