See This example on CompilerExplorer Function foo() and bar() generate the same few assembly instructions with GCC or Clang, but with ICPC (19.0.0), the function baz() is much larger and more complex. In particular, it has loops. icpc -O2 -std=c++17 -Wall -Werror #include <algorithm> int foo(int a, int b, int c) { return std::min(std::min(a,b), c); // this is correctly optimized } int bar(int a, int b, int c) { return std::min({a,b,c}); // this should be optmized down to what's in foo() } int main(int, char **) { return foo(1,2,3); }
foo(int, int, int): cmp esi, edi #4.12 cmovl edi, esi #4.12 cmp edi, edx #4.12 cmovl edx, edi #4.12 mov eax, edx #4.12 ret #4.12 bar(int, int, int): mov DWORD PTR [-24+rsp], edi #8.22 lea rcx, QWORD PTR [-12+rsp] #79.37 mov DWORD PTR [-8+rcx], esi #8.24 lea rax, QWORD PTR [-24+rsp] #5619.14 mov DWORD PTR [8+rax], edx #8.26 cmp rax, rcx #5591.22 je ..B3.7 # Prob 5% #5591.22 lea rdx, QWORD PTR [-20+rsp] #5588.5 cmp rdx, rcx #5594.27 je ..B3.7 # Prob 50% #5594.27 xor edx, edx #5594.7 jmp ..B3.9 # Prob 100% #5594.7 ..B3.4: # Preds ..B3.12 cmp rcx, 2 #5594.7 jae ..B3.7 # Prob 1% #5594.7 lea rcx, QWORD PTR [-20+rsp+rdx*8] #43.17 mov edx, DWORD PTR [rcx] #43.17 cmp edx, DWORD PTR [rax] #5596.4 cmovl rax, rcx #5596.4 ..B3.7: # Preds ..B3.1 ..B3.2 ..B3.4 ..B3.5 mov eax, DWORD PTR [rax] #8.12 ret #8.12 ..B3.9: # Preds ..B3.3 ..B3.11 mov ecx, DWORD PTR [rax] #43.26 cmp ecx, DWORD PTR [-20+rsp+rdx*8] #43.26 jle ..B3.11 # Prob 50% #43.26 lea rax, QWORD PTR [-20+rsp+rdx*8] #5594.16 mov ecx, DWORD PTR [rax] #43.26 ..B3.11: # Preds ..B3.10 ..B3.9 cmp ecx, DWORD PTR [-16+rsp+rdx*8] #5596.4 lea rsi, QWORD PTR [-16+rsp+rdx*8] #5594.16 cmovg rax, rsi #5596.4 inc rdx #5594.7 cmp rdx, 1 #5594.7 jb ..B3.9 # Prob 64% #5594.7 lea rcx, QWORD PTR [rdx+rdx] #5595.2 jmp ..B3.4 # Prob 100% #5595.2