https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97734
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Severity|normal |enhancement Status|UNCONFIRMED |NEW Last reconfirmed| |2021-12-15 Ever confirmed|0 |1 --- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Note ICX produces a branch too just like LLVM. MSVC produces: $LL2@branchfree: ; Line 12 mov eax, DWORD PTR [r8+r10*4] xor r9d, r9d cmp rcx, rax seta r9b inc r9 lea r10, QWORD PTR [r9+r10*2] cmp r10, rbx jb SHORT $LL2@branchfree The reason why GCC does not produce the cmov is because gimple produces: if (x_20(D) <= _27) goto <bb 4>; [50.00%] else goto <bb 5>; [50.00%] <bb 4> [local count: 477815112]: _23 = i_31 * 2; iftmp.0_17 = _23 + 1; goto <bb 6>; [100.00%] <bb 5> [local count: 477815112]: _25 = i_31 + 1; iftmp.0_24 = _25 * 2; <bb 6> [local count: 955630224]: # i_11 = PHI <iftmp.0_24(5), iftmp.0_17(4)> If we write the code like: uint64_t t22 = 2*i + 1; i = (x <= a[i]) ? t22 : t22+1; Then GCC will produce what MSVC produces (MSVC will still produce it too). If we add unused variable like: uint64_t t22 = 2*i + 1; GCC will produce the conditional move. I can't get LLVM to produce either the setb/seta nor conditional move either.