#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int abs(int);
int SSL_Raytrace(int x0, int y0, int x1, int y1, void *data,
                 int (*func)(int, int, void *)) {
  int dx = abs(x1 - x0);
  int dy = abs(y1 - y0);
  int x = x0;
  int y = y0;
  int n = 1 + dx + dy;
  int x_inc = (x1 > x0) ? 1 : -1;
  int y_inc = (y1 > y0) ? 1 : -1;
  int error = dx - dy;
  dx *= 2;
  dy *= 2;
  for (; n > 0; --n) {
    if (func(x, y, data)) {
      return (1);
    }
    if (error > 0) {
      x += x_inc;
      error -= dy;
    } else {
      y += y_inc;
      error += dx;
    }
  }
  return (0);
}


x86 assembly (clang, -O0):
<SSL_Raytrace>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %edi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8,-0x20(%rbp)
mov    %r9,-0x28(%rbp)
mov    -0x10(%rbp),%edi
sub    -0x8(%rbp),%edi
call   1030 <abs@plt>
mov    %eax,-0x2c(%rbp)
mov    -0x14(%rbp),%edi
sub    -0xc(%rbp),%edi
call   1030 <abs@plt>
mov    %eax,-0x30(%rbp)
mov    -0x8(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
add    -0x30(%rbp),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x10(%rbp),%edx
mov    -0x8(%rbp),%esi
mov    $0xffffffff,%eax
mov    $0x1,%ecx
cmp    %esi,%edx
cmovg  %ecx,%eax
mov    %eax,-0x40(%rbp)
mov    -0x14(%rbp),%edx
mov    -0xc(%rbp),%esi
mov    $0xffffffff,%eax
mov    $0x1,%ecx
cmp    %esi,%edx
cmovg  %ecx,%eax
mov    %eax,-0x44(%rbp)
mov    -0x2c(%rbp),%eax
sub    -0x30(%rbp),%eax
mov    %eax,-0x48(%rbp)
mov    -0x2c(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x30(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x30(%rbp)
cmpl   $0x0,-0x3c(%rbp)
jle    1222 <SSL_Raytrace+0x112>
mov    -0x28(%rbp),%rax
mov    -0x34(%rbp),%edi
mov    -0x38(%rbp),%esi
mov    -0x20(%rbp),%rdx
call   *%rax
cmp    $0x0,%eax
je     11da <SSL_Raytrace+0xca>
movl   $0x1,-0x4(%rbp)
jmp    1229 <SSL_Raytrace+0x119>
cmpl   $0x0,-0x48(%rbp)
jle    11fd <SSL_Raytrace+0xed>
mov    -0x40(%rbp),%eax
add    -0x34(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0x30(%rbp),%ecx
mov    -0x48(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x48(%rbp)
jmp    120f <SSL_Raytrace+0xff>
mov    -0x44(%rbp),%eax
add    -0x38(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x2c(%rbp),%eax
add    -0x48(%rbp),%eax
mov    %eax,-0x48(%rbp)
jmp    1214 <SSL_Raytrace+0x104>
mov    -0x3c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x3c(%rbp)
jmp    11ab <SSL_Raytrace+0x9b>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<SSL_Raytrace>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %esi,%ebx
mov    %edi,%ebp
xor    %eax,%eax
sub    %esi,%ecx
setg   %al
xor    %esi,%esi
sub    %edi,%edx
setg   %sil
mov    %edx,%edi
neg    %edi
cmovs  %edx,%edi
mov    %ecx,%edx
neg    %edx
cmovs  %ecx,%edx
mov    %r9,0x10(%rsp)
mov    %r8,0x8(%rsp)
lea    -0x1(%rsi,%rsi,1),%ecx
mov    %ecx,0x4(%rsp)
lea    -0x1(%rax,%rax,1),%eax
mov    %eax,(%rsp)
mov    %edi,%r14d
lea    (%rdi,%rdx,1),%r15d
add    $0x2,%r15d
mov    %edi,%r12d
sub    %edx,%r12d
lea    (%rdx,%rdx,1),%r13d
neg    %r13d
add    %edi,%r14d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %ebp,%edi
mov    %ebx,%esi
mov    0x8(%rsp),%rdx
call   *0x10(%rsp)
test   %eax,%eax
jne    11b0 <SSL_Raytrace+0xb0>
xor    %eax,%eax
test   %r12d,%r12d
mov    $0x0,%ecx
cmovg  0x4(%rsp),%ecx
mov    (%rsp),%edx
cmovg  %eax,%edx
mov    %r14d,%esi
cmovg  %r13d,%esi
add    %ecx,%ebp
add    %edx,%ebx
add    %esi,%r12d
add    $0xffffffff,%r15d
cmp    $0x1,%r15d
jg     1170 <SSL_Raytrace+0x70>
jmp    11b5 <SSL_Raytrace+0xb5>
mov    $0x1,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @SSL_Raytrace(i32 %0, i32 %1, i32 %2, i32 %3, i8* %4, i32 (i32, i32, i8*)* %5) {
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i8*
%13 = alloca i32 (i32, i32, i8*)*
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32
%20 = alloca i32
%21 = alloca i32
store i32 %0, i32* %8
store i32 %1, i32* %9
store i32 %2, i32* %10
store i32 %3, i32* %11
store i8* %4, i8** %12
store i32 (i32, i32, i8*)* %5, i32 (i32, i32, i8*)** %13
%22 = load i32, i32* %10
%23 = load i32, i32* %8
%24 = sub nsw i32 %22, %23
%25 = call i32 @abs(i32 %24)
store i32 %25, i32* %14
%26 = load i32, i32* %11
%27 = load i32, i32* %9
%28 = sub nsw i32 %26, %27
%29 = call i32 @abs(i32 %28)
store i32 %29, i32* %15
%30 = load i32, i32* %8
store i32 %30, i32* %16
%31 = load i32, i32* %9
store i32 %31, i32* %17
%32 = load i32, i32* %14
%33 = add nsw i32 1, %32
%34 = load i32, i32* %15
%35 = add nsw i32 %33, %34
store i32 %35, i32* %18
%36 = load i32, i32* %10
%37 = load i32, i32* %8
%38 = icmp sgt i32 %36, %37
%39 = zext i1 %38 to i64
%40 = select i1 %38, i32 1, i32 -1
store i32 %40, i32* %19
%41 = load i32, i32* %11
%42 = load i32, i32* %9
%43 = icmp sgt i32 %41, %42
%44 = zext i1 %43 to i64
%45 = select i1 %43, i32 1, i32 -1
store i32 %45, i32* %20
%46 = load i32, i32* %14
%47 = load i32, i32* %15
%48 = sub nsw i32 %46, %47
store i32 %48, i32* %21
%49 = load i32, i32* %14
%50 = mul nsw i32 %49, 2
store i32 %50, i32* %14
%51 = load i32, i32* %15
%52 = mul nsw i32 %51, 2
store i32 %52, i32* %15
br label %53
53: ; preds = %82, %6
%54 = load i32, i32* %18
%55 = icmp sgt i32 %54, 0
br i1 %55, label %56, label %85
56: ; preds = %53
%57 = load i32 (i32, i32, i8*)*, i32 (i32, i32, i8*)** %13
%58 = load i32, i32* %16
%59 = load i32, i32* %17
%60 = load i8*, i8** %12
%61 = call i32 %57(i32 %58, i32 %59, i8* %60)
%62 = icmp ne i32 %61, 0
br i1 %62, label %63, label %64
63: ; preds = %56
store i32 1, i32* %7
br label %86
64: ; preds = %56
%65 = load i32, i32* %21
%66 = icmp sgt i32 %65, 0
br i1 %66, label %67, label %74
67: ; preds = %64
%68 = load i32, i32* %19
%69 = load i32, i32* %16
%70 = add nsw i32 %69, %68
store i32 %70, i32* %16
%71 = load i32, i32* %15
%72 = load i32, i32* %21
%73 = sub nsw i32 %72, %71
store i32 %73, i32* %21
br label %81
74: ; preds = %64
%75 = load i32, i32* %20
%76 = load i32, i32* %17
%77 = add nsw i32 %76, %75
store i32 %77, i32* %17
%78 = load i32, i32* %14
%79 = load i32, i32* %21
%80 = add nsw i32 %79, %78
store i32 %80, i32* %21
br label %81
81: ; preds = %74, %67
br label %82
82: ; preds = %81
%83 = load i32, i32* %18
%84 = add nsw i32 %83, -1
store i32 %84, i32* %18
br label %53
85: ; preds = %53
store i32 0, i32* %7
br label %86
86: ; preds = %85, %63
%87 = load i32, i32* %7
ret i32 %87
}

LLVM IR (-O2):
define i32 @SSL_Raytrace(i32 %0, i32 %1, i32 %2, i32 %3, i8* %4, i32 (i32, i32, i8*)* nocapture %5) {
%7 = sub nsw i32 %2, %0
%8 = tail call i32 @llvm.abs.i32(i32 %7, i1 true)
%9 = sub nsw i32 %3, %1
%10 = tail call i32 @llvm.abs.i32(i32 %9, i1 true)
%11 = add nuw nsw i32 %8, 1
%12 = add nuw nsw i32 %11, %10
%13 = icmp sgt i32 %2, %0
%14 = select i1 %13, i32 1, i32 -1
%15 = icmp sgt i32 %3, %1
%16 = select i1 %15, i32 1, i32 -1
%17 = sub nsw i32 %8, %10
%18 = shl nuw nsw i32 %8, 1
%19 = mul i32 %10, -2
br label %20
20: ; preds = %6, %27
%21 = phi i32 [ %17, %6 ], [ %34, %27 ]
%22 = phi i32 [ %12, %6 ], [ %35, %27 ]
%23 = phi i32 [ %1, %6 ], [ %32, %27 ]
%24 = phi i32 [ %0, %6 ], [ %30, %27 ]
%25 = tail call i32 %5(i32 %24, i32 %23, i8* %4)
%26 = icmp eq i32 %25, 0
br i1 %26, label %27, label %37
27: ; preds = %20
%28 = icmp sgt i32 %21, 0
%29 = select i1 %28, i32 %14, i32 0
%30 = add nsw i32 %29, %24
%31 = select i1 %28, i32 0, i32 %16
%32 = add nsw i32 %31, %23
%33 = select i1 %28, i32 %19, i32 %18
%34 = add i32 %33, %21
%35 = add nsw i32 %22, -1
%36 = icmp sgt i32 %22, 1
br i1 %36, label %20, label %37
37: ; preds = %27, %20
%38 = phi i32 [ 1, %20 ], [ 0, %27 ]
ret i32 %38
}