int lookfor_notzero(int imax, int jmax, double matrix[imax][jmax], int i,
                    int j) {
  for (; i < imax; ++i) {
    if (matrix[i][j] != 0)
      return i;
  }
  return -1;
}


x86 assembly (clang, -O0):
<lookfor_notzero>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8d,-0x20(%rbp)
mov    -0xc(%rbp),%eax
mov    %rax,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    117e <lookfor_notzero+0x7e>
mov    -0x28(%rbp),%rdx
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1160 <lookfor_notzero+0x60>
jp     1160 <lookfor_notzero+0x60>
jmp    116b <lookfor_notzero+0x6b>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1185 <lookfor_notzero+0x85>
jmp    1170 <lookfor_notzero+0x70>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    111c <lookfor_notzero+0x1c>
movl   $0xffffffff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<lookfor_notzero>:
mov    $0xffffffff,%eax
cmp    %edi,%ecx
jge    1146 <lookfor_notzero+0x46>
mov    %esi,%r9d
movslq %r8d,%r8
movslq %ecx,%rsi
imul   %r9,%rsi
add    %r8,%rsi
lea    (%rdx,%rsi,8),%rdx
shl    $0x3,%r9
xorpd  %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nop
movsd  (%rdx),%xmm1
ucomisd %xmm0,%xmm1
jne    1147 <lookfor_notzero+0x47>
jp     1147 <lookfor_notzero+0x47>
add    $0x1,%ecx
add    %r9,%rdx
cmp    %ecx,%edi
jne    1130 <lookfor_notzero+0x30>
ret
mov    %ecx,%eax
ret

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

LLVM IR (-O2):
define i32 @lookfor_notzero(i32 %0, i32 %1, double* nocapture %2, i32 %3, i32 %4) {
%6 = zext i32 %1 to i64
%7 = icmp slt i32 %3, %0
br i1 %7, label %8, label %24
8: ; preds = %5
%9 = sext i32 %4 to i64
%10 = sext i32 %3 to i64
%11 = getelementptr inbounds double, double* %2, i64 %9
br label %12
12: ; preds = %8, %18
%13 = phi i64 [ %10, %8 ], [ %19, %18 ]
%14 = mul nsw i64 %13, %6
%15 = getelementptr inbounds double, double* %11, i64 %14
%16 = load double, double* %15
%17 = fcmp une double %16, 0.000000e+00
br i1 %17, label %22, label %18
18: ; preds = %12
%19 = add nsw i64 %13, 1
%20 = trunc i64 %19 to i32
%21 = icmp eq i32 %20, %0
br i1 %21, label %24, label %12
22: ; preds = %12
%23 = trunc i64 %13 to i32
br label %24
24: ; preds = %18, %22, %5
%25 = phi i32 [ -1, %5 ], [ %23, %22 ], [ -1, %18 ]
ret i32 %25
}