void fconv(float a[], int m, float b[], int n, float r[]) {
  int i, j, t = m + n - 1;
  for (i = 0; i < t; i++)
    for (j = 0; j < m && j <= i; j++)
      if (i - j < n)
        r[i] += a[j] * b[i - j];
}


x86 assembly (clang, -O0):
<fconv>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8,-0x28(%rbp)
mov    -0xc(%rbp),%eax
add    -0x1c(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x34(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x34(%rbp),%eax
jge    11d7 <fconv+0xd7>
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%ecx
xor    %eax,%eax
cmp    -0xc(%rbp),%ecx
mov    %al,-0x35(%rbp)
jge    1159 <fconv+0x59>
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
setle  %al
mov    %al,-0x35(%rbp)
mov    -0x35(%rbp),%al
test   $0x1,%al
jne    1169 <fconv+0x69>
jmp    11c4 <fconv+0xc4>
mov    -0x2c(%rbp),%eax
sub    -0x30(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    11b1 <fconv+0xb1>
mov    -0x8(%rbp),%rax
movslq -0x30(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x2c(%rbp),%ecx
sub    -0x30(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm2
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,(%rax,%rcx,4)
jmp    11b6 <fconv+0xb6>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    113c <fconv+0x3c>
jmp    11c9 <fconv+0xc9>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1129 <fconv+0x29>
pop    %rbp
ret

x86 assembly (clang, -O2):
<fconv>:
push   %r14
push   %rbx
lea    (%rsi,%rcx,1),%eax
add    $0xffffffff,%eax
test   %eax,%eax
jle    1172 <fconv+0x72>
movslq %ecx,%r10
movslq %esi,%r11
mov    %eax,%r9d
xor    %r14d,%r14d
jmp    1129 <fconv+0x29>
nopl   0x0(%rax,%rax,1)
add    $0x1,%r14
cmp    %r9,%r14
je     1172 <fconv+0x72>
test   %esi,%esi
jle    1120 <fconv+0x20>
mov    %r14,%rax
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
cmp    %r10,%rax
jge    115b <fconv+0x5b>
movss  (%rdi,%rcx,4),%xmm0
mulss  (%rdx,%rax,4),%xmm0
addss  (%r8,%r14,4),%xmm0
movss  %xmm0,(%r8,%r14,4)
lea    0x1(%rcx),%rbx
cmp    %r11,%rbx
jge    1120 <fconv+0x20>
add    $0xffffffffffffffff,%rax
cmp    %rcx,%r14
mov    %rbx,%rcx
ja     1140 <fconv+0x40>
jmp    1120 <fconv+0x20>
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @fconv(float* %0, i32 %1, float* %2, i32 %3, float* %4) {
%6 = alloca float*
%7 = alloca i32
%8 = alloca float*
%9 = alloca i32
%10 = alloca float*
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
store float* %0, float** %6
store i32 %1, i32* %7
store float* %2, float** %8
store i32 %3, i32* %9
store float* %4, float** %10
%14 = load i32, i32* %7
%15 = load i32, i32* %9
%16 = add nsw i32 %14, %15
%17 = sub nsw i32 %16, 1
store i32 %17, i32* %13
store i32 0, i32* %11
br label %18
18: ; preds = %63, %5
%19 = load i32, i32* %11
%20 = load i32, i32* %13
%21 = icmp slt i32 %19, %20
br i1 %21, label %22, label %66
22: ; preds = %18
store i32 0, i32* %12
br label %23
23: ; preds = %59, %22
%24 = load i32, i32* %12
%25 = load i32, i32* %7
%26 = icmp slt i32 %24, %25
br i1 %26, label %27, label %31
27: ; preds = %23
%28 = load i32, i32* %12
%29 = load i32, i32* %11
%30 = icmp sle i32 %28, %29
br label %31
31: ; preds = %27, %23
%32 = phi i1 [ false, %23 ], [ %30, %27 ]
br i1 %32, label %33, label %62
33: ; preds = %31
%34 = load i32, i32* %11
%35 = load i32, i32* %12
%36 = sub nsw i32 %34, %35
%37 = load i32, i32* %9
%38 = icmp slt i32 %36, %37
br i1 %38, label %39, label %58
39: ; preds = %33
%40 = load float*, float** %6
%41 = load i32, i32* %12
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds float, float* %40, i64 %42
%44 = load float, float* %43
%45 = load float*, float** %8
%46 = load i32, i32* %11
%47 = load i32, i32* %12
%48 = sub nsw i32 %46, %47
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds float, float* %45, i64 %49
%51 = load float, float* %50
%52 = load float*, float** %10
%53 = load i32, i32* %11
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds float, float* %52, i64 %54
%56 = load float, float* %55
%57 = call float @llvm.fmuladd.f32(float %44, float %51, float %56)
store float %57, float* %55
br label %58
58: ; preds = %39, %33
br label %59
59: ; preds = %58
%60 = load i32, i32* %12
%61 = add nsw i32 %60, 1
store i32 %61, i32* %12
br label %23
62: ; preds = %31
br label %63
63: ; preds = %62
%64 = load i32, i32* %11
%65 = add nsw i32 %64, 1
store i32 %65, i32* %11
br label %18
66: ; preds = %18
ret void
}

LLVM IR (-O2):
define void @fconv(float* nocapture %0, i32 %1, float* nocapture %2, i32 %3, float* nocapture %4) {
%6 = add i32 %1, -1
%7 = add i32 %6, %3
%8 = icmp sgt i32 %7, 0
br i1 %8, label %9, label %37
9: ; preds = %5
%10 = icmp sgt i32 %1, 0
%11 = sext i32 %3 to i64
%12 = sext i32 %1 to i64
%13 = zext i32 %7 to i64
br label %14
14: ; preds = %9, %34
%15 = phi i64 [ 0, %9 ], [ %35, %34 ]
br i1 %10, label %16, label %34
16: ; preds = %14
%17 = getelementptr inbounds float, float* %4, i64 %15
br label %18
18: ; preds = %16, %29
%19 = phi i64 [ 0, %16 ], [ %30, %29 ]
%20 = sub nsw i64 %15, %19
%21 = icmp slt i64 %20, %11
br i1 %21, label %22, label %29
22: ; preds = %18
%23 = getelementptr inbounds float, float* %0, i64 %19
%24 = load float, float* %23
%25 = getelementptr inbounds float, float* %2, i64 %20
%26 = load float, float* %25
%27 = load float, float* %17
%28 = tail call float @llvm.fmuladd.f32(float %24, float %26, float %27)
store float %28, float* %17
br label %29
29: ; preds = %18, %22
%30 = add nuw nsw i64 %19, 1
%31 = icmp slt i64 %30, %12
%32 = icmp ugt i64 %15, %19
%33 = select i1 %31, i1 %32, i1 false
br i1 %33, label %18, label %34
34: ; preds = %29, %14
%35 = add nuw nsw i64 %15, 1
%36 = icmp eq i64 %35, %13
br i1 %36, label %37, label %14
37: ; preds = %34, %5
ret void
}