File tree Expand file tree Collapse file tree 2 files changed +46
-26
lines changed
Expand file tree Collapse file tree 2 files changed +46
-26
lines changed Original file line number Diff line number Diff line change 1+ ---
2+ ' openzeppelin-solidity ' : patch
3+ ---
4+
5+ Make Math.log2 branchless
Original file line number Diff line number Diff line change @@ -391,42 +391,57 @@ library Math {
391391 * @dev Return the log in base 2 of a positive value rounded towards zero.
392392 * Returns 0 if given 0.
393393 */
394- function log2 (uint256 value ) internal pure returns (uint256 ) {
395- uint256 result = 0 ;
394+ function log2 (uint256 value ) internal pure returns (uint256 result ) {
396395 unchecked {
397- if (value >> 128 > 0 ) {
398- value >>= 128 ;
399- result += 128 ;
396+ uint256 isGt;
397+
398+ assembly {
399+ isGt := gt (value, 0xffffffffffffffffffffffffffffffff )
400400 }
401- if (value >> 64 > 0 ) {
402- value >>= 64 ;
403- result += 64 ;
401+ value >>= isGt * 128 ;
402+ result += isGt * 128 ;
403+
404+ assembly {
405+ isGt := gt (value, 0xffffffffffffffff )
404406 }
405- if (value >> 32 > 0 ) {
406- value >>= 32 ;
407- result += 32 ;
407+ value >>= isGt * 64 ;
408+ result += isGt * 64 ;
409+
410+ assembly {
411+ isGt := gt (value, 0xffffffff )
408412 }
409- if (value >> 16 > 0 ) {
410- value >>= 16 ;
411- result += 16 ;
413+ value >>= isGt * 32 ;
414+ result += isGt * 32 ;
415+
416+ assembly {
417+ isGt := gt (value, 0xffff )
412418 }
413- if (value >> 8 > 0 ) {
414- value >>= 8 ;
415- result += 8 ;
419+ value >>= isGt * 16 ;
420+ result += isGt * 16 ;
421+
422+ assembly {
423+ isGt := gt (value, 0xff )
416424 }
417- if (value >> 4 > 0 ) {
418- value >>= 4 ;
419- result += 4 ;
425+ value >>= isGt * 8 ;
426+ result += isGt * 8 ;
427+
428+ assembly {
429+ isGt := gt (value, 0xf )
420430 }
421- if (value >> 2 > 0 ) {
422- value >>= 2 ;
423- result += 2 ;
431+ value >>= isGt * 4 ;
432+ result += isGt * 4 ;
433+
434+ assembly {
435+ isGt := gt (value, 0x3 )
424436 }
425- if (value >> 1 > 0 ) {
426- result += 1 ;
437+ value >>= isGt * 2 ;
438+ result += isGt * 2 ;
439+
440+ assembly {
441+ isGt := gt (value, 0x1 )
427442 }
443+ result += isGt;
428444 }
429- return result;
430445 }
431446
432447 /**
You can’t perform that action at this time.
0 commit comments