#include "stdlib.h"
#include "stdio.h"
#define N 1000000000
// this is a "saturation" operation, it's quite common for example in code
// that has to save images (where each color component is an unsigned byte)
int sat(int a) {
if (a < 0)
a = 0;
else if (a > 255)
a = 255;
return a;
}
int main() {
int i;
int tot = 0;
for (i = 0; i < N; i++) {
tot += sat(i);
tot += sat(-i);
tot += sat(300);
}
printf("%d\n", tot);
return 0;
}
/*
Args used to compile with gcc and llvm-gcc:
-Wall -O3 -fomit-frame-pointer -msse3 -march=native -S
On Windows
gcc: version 4.3.3-dw2-tdm-1 (GCC)
llvm-gcc: gcc version 4.2.1 (Based on Apple Inc. build 5636) (LLVM build)
----------------------------------
Timings, best of 3, seconds:
GCC sat1: 1.32 s
LLVM-GCC sat1: 4.94 s
----------------------------------
GCC:
_main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebx
movl $255, %ebx
pushl %ecx
subl $20, %esp
call ___main
movl $255, %ecx
movl $1, %edx
.p2align 4,,10
L4:
cmpl $255, %edx
movl %ebx, %eax
cmovle %edx, %eax
incl %edx
leal 255(%ecx,%eax), %ecx
cmpl $1000000000, %edx
jne L4
movl %ecx, 4(%esp)
movl $LC0, (%esp)
call _printf
addl $20, %esp
xorl %eax, %eax
popl %ecx
popl %ebx
leal -4(%ecx), %esp
ret
----------------------------------
LLVM-GCC:
_main:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
subl $8, %esp
call ___main
xorl %eax, %eax
movl %eax, %ecx
jmp LBB2_2 # bb1.i
LBB2_1: # bb
decl %edx
incl %ecx
xorl %esi, %esi
testl %ecx, %ecx
js LBB2_3 # sat.exit
.align 16
LBB2_2: # bb1.i
cmpl $255, %ecx
movl $255, %esi
cmovle %ecx, %esi
movl %ecx, %edx
negl %edx
.align 16
LBB2_3: # sat.exit
testl %edx, %edx
js LBB2_7 # sat.exit.bb1_crit_edge
LBB2_4: # bb1.i6
cmpl $255, %edx
movl $255, %edi
cmovle %edx, %edi
LBB2_5: # bb1
addl %esi, %eax
leal 255(%edi,%eax), %eax
leal 1(%ecx), %esi
cmpl $1000000000, %esi
jl LBB2_1 # bb
LBB2_6: # bb2
movl %eax, 4(%esp)
movl $_.str, (%esp)
call _printf
xorl %eax, %eax
addl $8, %esp
popl %esi
popl %edi
popl %ebp
ret
LBB2_7: # sat.exit.bb1_crit_edge
xorl %edi, %edi
jmp LBB2_5 # bb1
*/