void kp(unsigned f[], unsigned c, unsigned wi, unsigned vi) {
  for (; c >= wi; --c) {
    int temp = f[c - wi] + vi;
    if (f[c] < temp)
      f[c] = temp;
  }
}


x86 assembly (clang, -O0):
<kp>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x10(%rbp),%eax
jb     1165 <kp+0x65>
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
sub    -0x10(%rbp),%ecx
mov    %ecx,%ecx
mov    (%rax,%rcx,4),%eax
add    -0x14(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
mov    (%rax,%rcx,4),%eax
cmp    -0x18(%rbp),%eax
jae    1152 <kp+0x52>
mov    -0x18(%rbp),%edx
mov    -0x8(%rbp),%rax
mov    -0xc(%rbp),%ecx
mov    %edx,(%rax,%rcx,4)
jmp    1157 <kp+0x57>
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
jmp    1111 <kp+0x11>
pop    %rbp
ret

x86 assembly (clang, -O2):
<kp>:
push   %r15
push   %r14
push   %rbx
mov    %esi,%r15d
sub    %edx,%r15d
jae    1113 <kp+0x13>
pop    %rbx
pop    %r14
pop    %r15
ret
lea    -0x1(%rdx),%r10d
lea    -0x1(%rsi),%r9d
cmp    %r9d,%r10d
mov    %r9d,%ebx
cmovb  %r10d,%ebx
mov    %esi,%r8d
sub    %ebx,%r8d
cmp    $0x4,%r8d
jae    115b <kp+0x5b>
mov    %esi,%eax
mov    %edx,%esi
neg    %esi
jmp    1147 <kp+0x47>
nopl   0x0(%rax)
add    $0xffffffff,%eax
cmp    %edx,%eax
jb     110d <kp+0xd>
lea    (%rsi,%rax,1),%ebx
mov    (%rdi,%rbx,4),%ebx
add    %ecx,%ebx
mov    %eax,%eax
cmp    %ebx,(%rdi,%rax,4)
jae    1140 <kp+0x40>
mov    %ebx,(%rdi,%rax,4)
jmp    1140 <kp+0x40>
xor    %r11d,%r11d
mov    %r9d,%ebx
sub    %r10d,%ebx
cmovb  %r11d,%ebx
cmp    %esi,%ebx
ja     1131 <kp+0x31>
cmp    %r15d,%ebx
ja     1131 <kp+0x31>
mov    %esi,%r11d
lea    (%rdi,%r11,4),%r14
shl    $0x2,%rbx
mov    %r14,%rax
sub    %rbx,%rax
cmp    %r14,%rax
ja     1131 <kp+0x31>
lea    (%rdi,%r15,4),%r14
mov    %r14,%rax
sub    %rbx,%rax
cmp    %r14,%rax
ja     1131 <kp+0x31>
xor    %eax,%eax
sub    %r10d,%r9d
cmovb  %eax,%r9d
mov    %r11,%rax
sub    %r9,%rax
lea    (%rdi,%rax,4),%rax
lea    (%rdi,%r15,4),%rbx
add    $0x4,%rbx
cmp    %rbx,%rax
jae    11ce <kp+0xce>
lea    (%rdi,%r11,4),%rax
add    $0x4,%rax
sub    %r9,%r15
lea    (%rdi,%r15,4),%rbx
cmp    %rax,%rbx
jb     1131 <kp+0x31>
mov    %r8d,%r9d
and    $0xfffffffc,%r9d
mov    %esi,%eax
sub    %r9d,%eax
movd   %ecx,%xmm0
pshufd $0x0,%xmm0,%xmm0
mov    %edx,%r10d
neg    %r10d
movdqa 0xe0f(%rip),%xmm1
mov    %r9d,%r11d
jmp    120d <kp+0x10d>
cs nopw 0x0(%rax,%rax,1)
add    $0xfffffffc,%esi
add    $0xfffffffc,%r11d
je     1299 <kp+0x199>
lea    (%r10,%rsi,1),%ebx
movdqu -0xc(%rdi,%rbx,4),%xmm2
pshufd $0x1b,%xmm2,%xmm2
paddd  %xmm0,%xmm2
mov    %esi,%esi
movdqu -0xc(%rdi,%rsi,4),%xmm3
pshufd $0x1b,%xmm3,%xmm4
pxor   %xmm1,%xmm4
movdqa %xmm2,%xmm3
pxor   %xmm1,%xmm3
pcmpgtd %xmm4,%xmm3
movd   %xmm3,%ebx
test   $0x1,%bl
je     124b <kp+0x14b>
movd   %xmm2,(%rdi,%rsi,4)
pextrw $0x2,%xmm3,%ebx
test   $0x1,%bl
je     1262 <kp+0x162>
lea    -0x1(%rsi),%ebx
pshufd $0x55,%xmm2,%xmm4
movd   %xmm4,(%rdi,%rbx,4)
pextrw $0x4,%xmm3,%ebx
test   $0x1,%bl
je     1279 <kp+0x179>
lea    -0x2(%rsi),%ebx
pshufd $0xee,%xmm2,%xmm4
movd   %xmm4,(%rdi,%rbx,4)
pextrw $0x6,%xmm3,%ebx
test   $0x1,%bl
je     1200 <kp+0x100>
lea    -0x3(%rsi),%ebx
pshufd $0xff,%xmm2,%xmm2
movd   %xmm2,(%rdi,%rbx,4)
jmp    1200 <kp+0x100>
cmp    %r9d,%r8d
jne    1133 <kp+0x33>
jmp    110d <kp+0xd>

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

LLVM IR (-O2):
define void @kp(i32* nocapture %0, i32 %1, i32 %2, i32 %3) {
%5 = icmp ult i32 %1, %2
br i1 %5, label %125, label %6
6: ; preds = %4
%7 = add i32 %2, -1
%8 = add i32 %1, -1
%9 = call i32 @llvm.umin.i32(i32 %7, i32 %8)
%10 = sub i32 %1, %9
%11 = icmp ult i32 %10, 4
br i1 %11, label %108, label %12
12: ; preds = %6
%13 = add i32 %1, -1
%14 = add i32 %2, -1
%15 = call i32 @llvm.umin.i32(i32 %14, i32 %13)
%16 = sub i32 %13, %15
%17 = icmp ugt i32 %16, %1
%18 = sub i32 %1, %2
%19 = icmp ugt i32 %16, %18
%20 = zext i32 %1 to i64
%21 = getelementptr i32, i32* %0, i64 %20
%22 = zext i32 %16 to i64
%23 = sub nsw i64 0, %22
%24 = getelementptr i32, i32* %21, i64 %23
%25 = icmp ugt i32* %24, %21
%26 = zext i32 %18 to i64
%27 = getelementptr i32, i32* %0, i64 %26
%28 = zext i32 %16 to i64
%29 = sub nsw i64 0, %28
%30 = getelementptr i32, i32* %27, i64 %29
%31 = icmp ugt i32* %30, %27
%32 = or i1 %17, %19
%33 = or i1 %32, %25
%34 = or i1 %33, %31
br i1 %34, label %108, label %35
35: ; preds = %12
%36 = zext i32 %1 to i64
%37 = add i32 %1, -1
%38 = add i32 %2, -1
%39 = call i32 @llvm.umin.i32(i32 %38, i32 %37)
%40 = sub i32 %37, %39
%41 = zext i32 %40 to i64
%42 = sub nsw i64 %36, %41
%43 = getelementptr i32, i32* %0, i64 %42
%44 = add nuw nsw i64 %36, 1
%45 = getelementptr i32, i32* %0, i64 %44
%46 = sub i32 %1, %2
%47 = zext i32 %46 to i64
%48 = sub nsw i64 %47, %41
%49 = getelementptr i32, i32* %0, i64 %48
%50 = add nuw nsw i64 %47, 1
%51 = getelementptr i32, i32* %0, i64 %50
%52 = icmp ult i32* %43, %51
%53 = icmp ult i32* %49, %45
%54 = and i1 %52, %53
br i1 %54, label %108, label %55
55: ; preds = %35
%56 = and i32 %10, -4
%57 = sub i32 %1, %56
%58 = insertelement <4 x i32> poison, i32 %3, i64 0
%59 = shufflevector <4 x i32> %58, <4 x i32> poison, <4 x i32> zeroinitializer
%60 = getelementptr inbounds i32, i32* %0, i64 -3
%61 = getelementptr inbounds i32, i32* %0, i64 -3
br label %62
62: ; preds = %103, %55
%63 = phi i32 [ 0, %55 ], [ %104, %103 ]
%64 = sub i32 %1, %63
%65 = sub i32 %64, %2
%66 = zext i32 %65 to i64
%67 = getelementptr inbounds i32, i32* %60, i64 %66
%68 = bitcast i32* %67 to <4 x i32>*
%69 = load <4 x i32>, <4 x i32>* %68
%70 = shufflevector <4 x i32> %69, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%71 = add <4 x i32> %70, %59
%72 = zext i32 %64 to i64
%73 = getelementptr inbounds i32, i32* %61, i64 %72
%74 = bitcast i32* %73 to <4 x i32>*
%75 = load <4 x i32>, <4 x i32>* %74
%76 = shufflevector <4 x i32> %75, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%77 = icmp ult <4 x i32> %76, %71
%78 = extractelement <4 x i1> %77, i64 0
br i1 %78, label %79, label %82
79: ; preds = %62
%80 = getelementptr inbounds i32, i32* %0, i64 %72
%81 = extractelement <4 x i32> %71, i64 0
store i32 %81, i32* %80
br label %82
82: ; preds = %79, %62
%83 = extractelement <4 x i1> %77, i64 1
br i1 %83, label %84, label %89
84: ; preds = %82
%85 = add i32 %64, -1
%86 = zext i32 %85 to i64
%87 = getelementptr inbounds i32, i32* %0, i64 %86
%88 = extractelement <4 x i32> %71, i64 1
store i32 %88, i32* %87
br label %89
89: ; preds = %84, %82
%90 = extractelement <4 x i1> %77, i64 2
br i1 %90, label %91, label %96
91: ; preds = %89
%92 = add i32 %64, -2
%93 = zext i32 %92 to i64
%94 = getelementptr inbounds i32, i32* %0, i64 %93
%95 = extractelement <4 x i32> %71, i64 2
store i32 %95, i32* %94
br label %96
96: ; preds = %91, %89
%97 = extractelement <4 x i1> %77, i64 3
br i1 %97, label %98, label %103
98: ; preds = %96
%99 = add i32 %64, -3
%100 = zext i32 %99 to i64
%101 = getelementptr inbounds i32, i32* %0, i64 %100
%102 = extractelement <4 x i32> %71, i64 3
store i32 %102, i32* %101
br label %103
103: ; preds = %98, %96
%104 = add nuw i32 %63, 4
%105 = icmp eq i32 %104, %56
br i1 %105, label %106, label %62
106: ; preds = %103
%107 = icmp eq i32 %10, %56
br i1 %107, label %125, label %108
108: ; preds = %35, %12, %6, %106
%109 = phi i32 [ %1, %35 ], [ %1, %12 ], [ %1, %6 ], [ %57, %106 ]
br label %110
110: ; preds = %108, %122
%111 = phi i32 [ %123, %122 ], [ %109, %108 ]
%112 = sub i32 %111, %2
%113 = zext i32 %112 to i64
%114 = getelementptr inbounds i32, i32* %0, i64 %113
%115 = load i32, i32* %114
%116 = add i32 %115, %3
%117 = zext i32 %111 to i64
%118 = getelementptr inbounds i32, i32* %0, i64 %117
%119 = load i32, i32* %118
%120 = icmp ult i32 %119, %116
br i1 %120, label %121, label %122
121: ; preds = %110
store i32 %116, i32* %118
br label %122
122: ; preds = %121, %110
%123 = add i32 %111, -1
%124 = icmp ult i32 %123, %2
br i1 %124, label %125, label %110
125: ; preds = %122, %106, %4
ret void
}