GCC專門有一條優化,把各種各樣的奇葩寫法「還原」成(a &< b) ? b : a

https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/match.pd;h=349eab61d6b3e158c520586f3b35aa1b9157c62d;hb=HEAD#l2844

/* Undo fancy way of writing max/min or other ?: expressions,
like a - ((a - b) -(a &< b)), in this case into (a &< b) ? b : a. People normally use ?: and that is what we actually try to optimize. */ (for cmp (simple_comparison) (simplify (minus @0 (bit_and:c (minus @0 @1) (convert? (negate@4 (convert? (cmp@5 @2 @3)))))) (if (INTEGRAL_TYPE_P (type) INTEGRAL_TYPE_P (TREE_TYPE (@4)) TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE INTEGRAL_TYPE_P (TREE_TYPE (@5)) (TYPE_PRECISION (TREE_TYPE (@4)) &>= TYPE_PRECISION (type)
|| !TYPE_UNSIGNED (TREE_TYPE (@4)))
(GIMPLE || !TREE_SIDE_EFFECTS (@1)))
(cond (cmp @2 @3) @1 @0)))
(simplify
(plus:c @0 (bit_and:c (minus @1 @0)
(convert? (negate@4 (convert? (cmp@5 @2 @3))))))
(if (INTEGRAL_TYPE_P (type)
INTEGRAL_TYPE_P (TREE_TYPE (@4))
TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
INTEGRAL_TYPE_P (TREE_TYPE (@5))
(TYPE_PRECISION (TREE_TYPE (@4)) &>= TYPE_PRECISION (type)
|| !TYPE_UNSIGNED (TREE_TYPE (@4)))
(GIMPLE || !TREE_SIDE_EFFECTS (@1)))
(cond (cmp @2 @3) @1 @0)))
/* Similarly with ^ instead of - though in that case with :c. */
(simplify
(bit_xor:c @0 (bit_and:c (bit_xor:c @0 @1)
(convert? (negate@4 (convert? (cmp@5 @2 @3))))))
(if (INTEGRAL_TYPE_P (type)
INTEGRAL_TYPE_P (TREE_TYPE (@4))
TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
INTEGRAL_TYPE_P (TREE_TYPE (@5))
(TYPE_PRECISION (TREE_TYPE (@4)) &>= TYPE_PRECISION (type)
|| !TYPE_UNSIGNED (TREE_TYPE (@4)))
(GIMPLE || !TREE_SIDE_EFFECTS (@1)))
(cond (cmp @2 @3) @1 @0))))


有一說一,確實沒有用比較運算符。

__asm__ volatile("cmpl %2, %1
"
"cmovl %2, %0
"
: "=r"(a)
: "r"(a), "r"(b));


這個問題我和我的同學討論過,但很遺憾我們只得出了a,b為正整數的做法

有趣的問題系列-僅能使用加減乘除,主函數,分別輸出兩個數的最大值和最小值 - 東北小蟹蟹 - 博客園?

www.cnblogs.com

原文來自@東北小蟹蟹 ,dbxxx yyds!


用減法獲得大小關係,在最高位上

用間接定址[]替代跳轉

int max[2]={a,b},min[2]={b,a},s=(b-a)&>&>31;

a=max[s];

b=min[s];

性能優化時,為了減少分支命中壓力,這是減少跳轉的標準做法。


a=std::max(a, b);


推薦閱讀:
相關文章