void main1(int *arr, int n, int a, int b) {
  int i;
  for (i = 0; i < n; i++) {
    int m = arr[i];
    arr[i] = (m < a ? m - a : b);
  }
}


x86 assembly (clang, -O0):
<main1>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    116e <main1+0x6e>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    114c <main1+0x4c>
mov    -0x1c(%rbp),%eax
sub    -0x10(%rbp),%eax
mov    %eax,-0x20(%rbp)
jmp    1152 <main1+0x52>
mov    -0x14(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%edx
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1118 <main1+0x18>
pop    %rbp
ret

x86 assembly (clang, -O2):
<main1>:
test   %esi,%esi
jle    1254 <main1+0x154>
mov    %esi,%r8d
cmp    $0x8,%esi
jae    1117 <main1+0x17>
xor    %esi,%esi
jmp    1240 <main1+0x140>
mov    %r8d,%esi
and    $0xfffffff8,%esi
movd   %edx,%xmm0
pshufd $0x0,%xmm0,%xmm1
movd   %ecx,%xmm0
pshufd $0x0,%xmm0,%xmm0
lea    -0x8(%rsi),%rax
mov    %rax,%r9
shr    $0x3,%r9
add    $0x1,%r9
test   %rax,%rax
je     1255 <main1+0x155>
mov    %r9,%r10
and    $0xfffffffffffffffe,%r10
xor    %eax,%eax
movdqu (%rdi,%rax,4),%xmm4
movdqu 0x10(%rdi,%rax,4),%xmm5
movdqu 0x20(%rdi,%rax,4),%xmm3
movdqu 0x30(%rdi,%rax,4),%xmm2
movdqa %xmm1,%xmm6
pcmpgtd %xmm4,%xmm6
movdqa %xmm1,%xmm7
pcmpgtd %xmm5,%xmm7
psubd  %xmm1,%xmm4
psubd  %xmm1,%xmm5
pand   %xmm6,%xmm4
pandn  %xmm0,%xmm6
por    %xmm4,%xmm6
pand   %xmm7,%xmm5
pandn  %xmm0,%xmm7
por    %xmm5,%xmm7
movdqu %xmm6,(%rdi,%rax,4)
movdqu %xmm7,0x10(%rdi,%rax,4)
movdqa %xmm1,%xmm4
pcmpgtd %xmm3,%xmm4
movdqa %xmm1,%xmm5
pcmpgtd %xmm2,%xmm5
psubd  %xmm1,%xmm3
psubd  %xmm1,%xmm2
pand   %xmm4,%xmm3
pandn  %xmm0,%xmm4
por    %xmm3,%xmm4
pand   %xmm5,%xmm2
pandn  %xmm0,%xmm5
por    %xmm2,%xmm5
movdqu %xmm4,0x20(%rdi,%rax,4)
movdqu %xmm5,0x30(%rdi,%rax,4)
add    $0x10,%rax
add    $0xfffffffffffffffe,%r10
jne    1150 <main1+0x50>
test   $0x1,%r9b
je     1238 <main1+0x138>
movdqu (%rdi,%rax,4),%xmm2
movdqu 0x10(%rdi,%rax,4),%xmm3
movdqa %xmm1,%xmm4
pcmpgtd %xmm2,%xmm4
movdqa %xmm1,%xmm5
pcmpgtd %xmm3,%xmm5
psubd  %xmm1,%xmm2
psubd  %xmm1,%xmm3
pand   %xmm4,%xmm2
pandn  %xmm0,%xmm4
por    %xmm2,%xmm4
pand   %xmm5,%xmm3
pandn  %xmm0,%xmm5
por    %xmm3,%xmm5
movdqu %xmm4,(%rdi,%rax,4)
movdqu %xmm5,0x10(%rdi,%rax,4)
cmp    %r8,%rsi
je     1254 <main1+0x154>
nopl   (%rax)
mov    (%rdi,%rsi,4),%eax
sub    %edx,%eax
cmovge %ecx,%eax
mov    %eax,(%rdi,%rsi,4)
add    $0x1,%rsi
cmp    %rsi,%r8
jne    1240 <main1+0x140>
ret
xor    %eax,%eax
test   $0x1,%r9b
jne    11f2 <main1+0xf2>
jmp    1238 <main1+0x138>

LLVM IR (-O0):
define void @main1(i32* %0, i32 %1, i32 %2, i32 %3) {
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
store i32* %0, i32** %5
store i32 %1, i32* %6
store i32 %2, i32* %7
store i32 %3, i32* %8
store i32 0, i32* %9
br label %11
11: ; preds = %36, %4
%12 = load i32, i32* %9
%13 = load i32, i32* %6
%14 = icmp slt i32 %12, %13
br i1 %14, label %15, label %39
15: ; preds = %11
%16 = load i32*, i32** %5
%17 = load i32, i32* %9
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds i32, i32* %16, i64 %18
%20 = load i32, i32* %19
store i32 %20, i32* %10
%21 = load i32, i32* %10
%22 = load i32, i32* %7
%23 = icmp slt i32 %21, %22
br i1 %23, label %24, label %28
24: ; preds = %15
%25 = load i32, i32* %10
%26 = load i32, i32* %7
%27 = sub nsw i32 %25, %26
br label %30
28: ; preds = %15
%29 = load i32, i32* %8
br label %30
30: ; preds = %28, %24
%31 = phi i32 [ %27, %24 ], [ %29, %28 ]
%32 = load i32*, i32** %5
%33 = load i32, i32* %9
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds i32, i32* %32, i64 %34
store i32 %31, i32* %35
br label %36
36: ; preds = %30
%37 = load i32, i32* %9
%38 = add nsw i32 %37, 1
store i32 %38, i32* %9
br label %11
39: ; preds = %11
ret void
}

LLVM IR (-O2):
define void @main1(i32* nocapture %0, i32 %1, i32 %2, i32 %3) {
%5 = icmp sgt i32 %1, 0
br i1 %5, label %6, label %92
6: ; preds = %4
%7 = zext i32 %1 to i64
%8 = icmp ult i32 %1, 8
br i1 %8, label %81, label %9
9: ; preds = %6
%10 = and i64 %7, 4294967288
%11 = insertelement <4 x i32> poison, i32 %2, i64 0
%12 = shufflevector <4 x i32> %11, <4 x i32> poison, <4 x i32> zeroinitializer
%13 = insertelement <4 x i32> poison, i32 %2, i64 0
%14 = shufflevector <4 x i32> %13, <4 x i32> poison, <4 x i32> zeroinitializer
%15 = insertelement <4 x i32> poison, i32 %3, i64 0
%16 = shufflevector <4 x i32> %15, <4 x i32> poison, <4 x i32> zeroinitializer
%17 = insertelement <4 x i32> poison, i32 %3, i64 0
%18 = shufflevector <4 x i32> %17, <4 x i32> poison, <4 x i32> zeroinitializer
%19 = add nsw i64 %10, -8
%20 = lshr exact i64 %19, 3
%21 = add nuw nsw i64 %20, 1
%22 = and i64 %21, 1
%23 = icmp eq i64 %19, 0
br i1 %23, label %61, label %24
24: ; preds = %9
%25 = and i64 %21, 4611686018427387902
br label %26
26: ; preds = %26, %24
%27 = phi i64 [ 0, %24 ], [ %58, %26 ]
%28 = phi i64 [ 0, %24 ], [ %59, %26 ]
%29 = getelementptr inbounds i32, i32* %0, i64 %27
%30 = bitcast i32* %29 to <4 x i32>*
%31 = load <4 x i32>, <4 x i32>* %30
%32 = getelementptr inbounds i32, i32* %29, i64 4
%33 = bitcast i32* %32 to <4 x i32>*
%34 = load <4 x i32>, <4 x i32>* %33
%35 = icmp slt <4 x i32> %31, %12
%36 = icmp slt <4 x i32> %34, %14
%37 = sub nsw <4 x i32> %31, %12
%38 = sub nsw <4 x i32> %34, %14
%39 = select <4 x i1> %35, <4 x i32> %37, <4 x i32> %16
%40 = select <4 x i1> %36, <4 x i32> %38, <4 x i32> %18
%41 = bitcast i32* %29 to <4 x i32>*
store <4 x i32> %39, <4 x i32>* %41
%42 = bitcast i32* %32 to <4 x i32>*
store <4 x i32> %40, <4 x i32>* %42
%43 = or i64 %27, 8
%44 = getelementptr inbounds i32, i32* %0, i64 %43
%45 = bitcast i32* %44 to <4 x i32>*
%46 = load <4 x i32>, <4 x i32>* %45
%47 = getelementptr inbounds i32, i32* %44, i64 4
%48 = bitcast i32* %47 to <4 x i32>*
%49 = load <4 x i32>, <4 x i32>* %48
%50 = icmp slt <4 x i32> %46, %12
%51 = icmp slt <4 x i32> %49, %14
%52 = sub nsw <4 x i32> %46, %12
%53 = sub nsw <4 x i32> %49, %14
%54 = select <4 x i1> %50, <4 x i32> %52, <4 x i32> %16
%55 = select <4 x i1> %51, <4 x i32> %53, <4 x i32> %18
%56 = bitcast i32* %44 to <4 x i32>*
store <4 x i32> %54, <4 x i32>* %56
%57 = bitcast i32* %47 to <4 x i32>*
store <4 x i32> %55, <4 x i32>* %57
%58 = add nuw i64 %27, 16
%59 = add i64 %28, 2
%60 = icmp eq i64 %59, %25
br i1 %60, label %61, label %26
61: ; preds = %26, %9
%62 = phi i64 [ 0, %9 ], [ %58, %26 ]
%63 = icmp eq i64 %22, 0
br i1 %63, label %79, label %64
64: ; preds = %61
%65 = getelementptr inbounds i32, i32* %0, i64 %62
%66 = bitcast i32* %65 to <4 x i32>*
%67 = load <4 x i32>, <4 x i32>* %66
%68 = getelementptr inbounds i32, i32* %65, i64 4
%69 = bitcast i32* %68 to <4 x i32>*
%70 = load <4 x i32>, <4 x i32>* %69
%71 = icmp slt <4 x i32> %67, %12
%72 = icmp slt <4 x i32> %70, %14
%73 = sub nsw <4 x i32> %67, %12
%74 = sub nsw <4 x i32> %70, %14
%75 = select <4 x i1> %71, <4 x i32> %73, <4 x i32> %16
%76 = select <4 x i1> %72, <4 x i32> %74, <4 x i32> %18
%77 = bitcast i32* %65 to <4 x i32>*
store <4 x i32> %75, <4 x i32>* %77
%78 = bitcast i32* %68 to <4 x i32>*
store <4 x i32> %76, <4 x i32>* %78
br label %79
79: ; preds = %61, %64
%80 = icmp eq i64 %10, %7
br i1 %80, label %92, label %81
81: ; preds = %6, %79
%82 = phi i64 [ 0, %6 ], [ %10, %79 ]
br label %83
83: ; preds = %81, %83
%84 = phi i64 [ %90, %83 ], [ %82, %81 ]
%85 = getelementptr inbounds i32, i32* %0, i64 %84
%86 = load i32, i32* %85
%87 = icmp slt i32 %86, %2
%88 = sub nsw i32 %86, %2
%89 = select i1 %87, i32 %88, i32 %3
store i32 %89, i32* %85
%90 = add nuw nsw i64 %84, 1
%91 = icmp eq i64 %90, %7
br i1 %91, label %92, label %83
92: ; preds = %83, %79, %4
ret void
}