long divide(long a, long b) {
  if (a > 0)
    if (b > 0)
      return a / b;
    else
      return -a / (-b);
  else if (b > 0)
    return -(-a) / b;
  else
    return (-a) / (-b);
}


x86 assembly (clang, -O0):
<divide>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
cmpq   $0x0,-0x10(%rbp)
jle    114f <divide+0x4f>
cmpq   $0x0,-0x18(%rbp)
jle    1135 <divide+0x35>
mov    -0x10(%rbp),%rax
cqto
idivq  -0x18(%rbp)
mov    %rax,-0x8(%rbp)
jmp    118b <divide+0x8b>
xor    %eax,%eax
sub    -0x10(%rbp),%rax
xor    %ecx,%ecx
sub    -0x18(%rbp),%rcx
cqto
idiv   %rcx
mov    %rax,-0x8(%rbp)
jmp    118b <divide+0x8b>
cmpq   $0x0,-0x18(%rbp)
jle    1176 <divide+0x76>
xor    %eax,%eax
mov    %eax,%ecx
sub    -0x10(%rbp),%rcx
xor    %eax,%eax
sub    %rcx,%rax
cqto
idivq  -0x18(%rbp)
mov    %rax,-0x8(%rbp)
jmp    118b <divide+0x8b>
xor    %eax,%eax
sub    -0x10(%rbp),%rax
xor    %ecx,%ecx
sub    -0x18(%rbp),%rcx
cqto
idiv   %rcx
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<divide>:
test   %rdi,%rdi
jle    110f <divide+0xf>
test   %rsi,%rsi
jg     113f <divide+0x3f>
neg    %rsi
jmp    1117 <divide+0x17>
test   %rsi,%rsi
jle    1139 <divide+0x39>
neg    %rdi
mov    %rdi,%rax
or     %rsi,%rax
shr    $0x20,%rax
je     112f <divide+0x2f>
mov    %rdi,%rax
xor    %edx,%edx
div    %rsi
neg    %rax
ret
mov    %edi,%eax
xor    %edx,%edx
div    %esi
neg    %rax
ret
neg    %rsi
neg    %rdi
mov    %rdi,%rax
or     %rsi,%rax
shr    $0x20,%rax
je     1154 <divide+0x54>
mov    %rdi,%rax
xor    %edx,%edx
div    %rsi
ret
mov    %edi,%eax
xor    %edx,%edx
div    %esi
ret

LLVM IR (-O0):
define i64 @divide(i64 %0, i64 %1) {
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
store i64 %0, i64* %4
store i64 %1, i64* %5
%6 = load i64, i64* %4
%7 = icmp sgt i64 %6, 0
br i1 %7, label %8, label %21
8: ; preds = %2
%9 = load i64, i64* %5
%10 = icmp sgt i64 %9, 0
br i1 %10, label %11, label %15
11: ; preds = %8
%12 = load i64, i64* %4
%13 = load i64, i64* %5
%14 = sdiv i64 %12, %13
store i64 %14, i64* %3
br label %36
15: ; preds = %8
%16 = load i64, i64* %4
%17 = sub nsw i64 0, %16
%18 = load i64, i64* %5
%19 = sub nsw i64 0, %18
%20 = sdiv i64 %17, %19
store i64 %20, i64* %3
br label %36
21: ; preds = %2
%22 = load i64, i64* %5
%23 = icmp sgt i64 %22, 0
br i1 %23, label %24, label %30
24: ; preds = %21
%25 = load i64, i64* %4
%26 = sub nsw i64 0, %25
%27 = sub nsw i64 0, %26
%28 = load i64, i64* %5
%29 = sdiv i64 %27, %28
store i64 %29, i64* %3
br label %36
30: ; preds = %21
%31 = load i64, i64* %4
%32 = sub nsw i64 0, %31
%33 = load i64, i64* %5
%34 = sub nsw i64 0, %33
%35 = sdiv i64 %32, %34
store i64 %35, i64* %3
br label %36
36: ; preds = %30, %24, %15, %11
%37 = load i64, i64* %3
ret i64 %37
}

LLVM IR (-O2):
define i64 @divide(i64 %0, i64 %1) {
%3 = icmp sgt i64 %0, 0
%4 = icmp sgt i64 %1, 0
br i1 %3, label %5, label %12
5: ; preds = %2
br i1 %4, label %6, label %8
6: ; preds = %5
%7 = udiv i64 %0, %1
br label %21
8: ; preds = %5
%9 = sub nsw i64 0, %1
%10 = udiv i64 %0, %9
%11 = sub nsw i64 0, %10
br label %21
12: ; preds = %2
br i1 %4, label %13, label %17
13: ; preds = %12
%14 = sub i64 0, %0
%15 = udiv i64 %14, %1
%16 = sub i64 0, %15
br label %21
17: ; preds = %12
%18 = sub nsw i64 0, %1
%19 = sub i64 0, %0
%20 = udiv i64 %19, %18
br label %21
21: ; preds = %17, %13, %8, %6
%22 = phi i64 [ %7, %6 ], [ %11, %8 ], [ %16, %13 ], [ %20, %17 ]
ret i64 %22
}