#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 */
double *cross(double *, double *);
double fabs(int);
int intersect_tri_with_line(double *, double *, double *, double *, double *);
double metric(double *);
int line_intersect_2D_3D(double *a1, double *a2, double *q1, double *q2,
                         double *intersect, double *u_a, double *u_q) {
  double plane[9];
  double plane_p[2];
  double u;
  double p1[3], v1[3], v2[3];
  double coincident, sense, norm;
  int i;
  int is_inter1, is_inter2;
  plane[0] = q1[0];
  plane[1] = q1[1];
  plane[2] = q1[2];
  plane[3] = q2[0];
  plane[4] = q2[1];
  plane[5] = q2[2];
  plane[6] = 0.0;
  plane[7] = 0.0;
  plane[8] = 0.0;
  is_inter1 = intersect_tri_with_line(plane, a1, a2, plane_p, u_a);
  if (!is_inter1)
    return 0;
  if (fabs(*u_a) < (1.0e-10))
    *u_a = 0;
  if (fabs(1 - *u_a) < (1.0e-10))
    *u_a = 1;
  if ((*u_a < 0) || (*u_a > 1))
    return 0;
  plane[0] = a1[0];
  plane[1] = a1[1];
  plane[2] = a1[2];
  plane[3] = a2[0];
  plane[4] = a2[1];
  plane[5] = a2[2];
  plane[6] = 0.0;
  plane[7] = 0.0;
  plane[8] = 0.0;
  is_inter2 = intersect_tri_with_line(plane, q1, q2, plane_p, u_q);
  if (!is_inter2)
    return 0;
  if (fabs(*u_q) < (1.0e-10))
    *u_q = 0;
  if (fabs(1 - *u_q) < (1.0e-10))
    *u_q = 1;
  if ((*u_q < 0) || (*u_q > 1))
    return 0;
  u = *u_q;
  coincident = metric(cross(cross(a1, a2), cross(q1, q2)));
  if (coincident < (1.0e-10))
    return 0;
  intersect[0] = q1[0] + u * (q2[0] - q1[0]);
  intersect[1] = q1[1] + u * (q2[1] - q1[1]);
  intersect[2] = q1[2] + u * (q2[2] - q1[2]);
  norm = metric(intersect);
  for (i = 0; i < 3; i++)
    intersect[i] /= norm;
  return 1;
}


x86 assembly (clang, -O0):
<line_intersect_2D_3D>:
push   %rbp
mov    %rsp,%rbp
sub    $0x120,%rsp
mov    0x10(%rbp),%rax
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x80(%rbp)
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x28(%rbp),%rax
movsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
lea    -0x80(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
lea    -0x90(%rbp),%rcx
mov    -0x38(%rbp),%r8
call   1030 <intersect_tri_with_line@plt>
mov    %eax,-0x110(%rbp)
cmpl   $0x0,-0x110(%rbp)
jne    120c <line_intersect_2D_3D+0xcc>
movl   $0x0,-0x4(%rbp)
jmp    1563 <line_intersect_2D_3D+0x423>
mov    -0x38(%rbp),%rax
cvttsd2si (%rax),%edi
call   1040 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xddc(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    1239 <line_intersect_2D_3D+0xf9>
mov    -0x38(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax)
mov    -0x38(%rbp),%rax
movsd  0xdc3(%rip),%xmm0
subsd  (%rax),%xmm0
cvttsd2si %xmm0,%edi
call   1040 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xda3(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    1277 <line_intersect_2D_3D+0x137>
mov    -0x38(%rbp),%rax
movsd  0xd95(%rip),%xmm0
movsd  %xmm0,(%rax)
mov    -0x38(%rbp),%rax
xorps  %xmm0,%xmm0
ucomisd (%rax),%xmm0
ja     12a2 <line_intersect_2D_3D+0x162>
mov    -0x38(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xd70(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12ae <line_intersect_2D_3D+0x16e>
movl   $0x0,-0x4(%rbp)
jmp    1563 <line_intersect_2D_3D+0x423>
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x80(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x78(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x18(%rbp),%rax
movsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x58(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
lea    -0x80(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
lea    -0x90(%rbp),%rcx
mov    0x10(%rbp),%r8
call   1030 <intersect_tri_with_line@plt>
mov    %eax,-0x114(%rbp)
cmpl   $0x0,-0x114(%rbp)
jne    1353 <line_intersect_2D_3D+0x213>
movl   $0x0,-0x4(%rbp)
jmp    1563 <line_intersect_2D_3D+0x423>
mov    0x10(%rbp),%rax
cvttsd2si (%rax),%edi
call   1040 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xc95(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    1380 <line_intersect_2D_3D+0x240>
mov    0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax)
mov    0x10(%rbp),%rax
movsd  0xc7c(%rip),%xmm0
subsd  (%rax),%xmm0
cvttsd2si %xmm0,%edi
call   1040 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xc5c(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    13be <line_intersect_2D_3D+0x27e>
mov    0x10(%rbp),%rax
movsd  0xc4e(%rip),%xmm0
movsd  %xmm0,(%rax)
mov    0x10(%rbp),%rax
xorps  %xmm0,%xmm0
ucomisd (%rax),%xmm0
ja     13e9 <line_intersect_2D_3D+0x2a9>
mov    0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xc29(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    13f5 <line_intersect_2D_3D+0x2b5>
movl   $0x0,-0x4(%rbp)
jmp    1563 <line_intersect_2D_3D+0x423>
mov    0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1060 <cross@plt>
mov    %rax,-0x120(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1060 <cross@plt>
mov    -0x120(%rbp),%rdi
mov    %rax,%rsi
call   1060 <cross@plt>
mov    %rax,%rdi
call   1050 <metric@plt>
movsd  %xmm0,-0xf8(%rbp)
ff
movsd  0xbb3(%rip),%xmm0
ucomisd -0xf8(%rbp),%xmm0
ff
jbe    1467 <line_intersect_2D_3D+0x327>
movl   $0x0,-0x4(%rbp)
jmp    1563 <line_intersect_2D_3D+0x423>
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm1
movsd  -0x98(%rbp),%xmm0
ff
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm2
mov    -0x20(%rbp),%rax
subsd  (%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x30(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x20(%rbp),%rax
movsd  0x8(%rax),%xmm1
movsd  -0x98(%rbp),%xmm0
ff
mov    -0x28(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x20(%rbp),%rax
subsd  0x8(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x30(%rbp),%rax
movsd  %xmm0,0x8(%rax)
mov    -0x20(%rbp),%rax
movsd  0x10(%rax),%xmm1
movsd  -0x98(%rbp),%xmm0
ff
mov    -0x28(%rbp),%rax
movsd  0x10(%rax),%xmm2
mov    -0x20(%rbp),%rax
subsd  0x10(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x30(%rbp),%rax
movsd  %xmm0,0x10(%rax)
mov    -0x30(%rbp),%rdi
call   1050 <metric@plt>
movsd  %xmm0,-0x108(%rbp)
ff
movl   $0x0,-0x10c(%rbp)
cmpl   $0x3,-0x10c(%rbp)
jge    155c <line_intersect_2D_3D+0x41c>
movsd  -0x108(%rbp),%xmm1
ff
mov    -0x30(%rbp),%rax
movslq -0x10c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x10c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10c(%rbp)
jmp    151a <line_intersect_2D_3D+0x3da>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x120,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<line_intersect_2D_3D>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x78,%rsp
mov    %r9,%r14
mov    %r8,0x8(%rsp)
mov    %rcx,%r15
mov    %rdx,%rbx
mov    %rsi,%r13
mov    %rdi,%rbp
movups (%rdx),%xmm0
movaps %xmm0,0x10(%rsp)
movsd  0x10(%rdx),%xmm0
movsd  %xmm0,0x20(%rsp)
movups (%rcx),%xmm0
movups %xmm0,0x28(%rsp)
movsd  0x10(%rcx),%xmm0
movsd  %xmm0,0x38(%rsp)
xorpd  %xmm0,%xmm0
movapd %xmm0,0x40(%rsp)
movq   $0x0,0x50(%rsp)
lea    0x10(%rsp),%rdi
lea    0x60(%rsp),%rcx
mov    %rbp,%rsi
mov    %r13,%rdx
mov    %r9,%r8
call   1030 <intersect_tri_with_line@plt>
xor    %r12d,%r12d
test   %eax,%eax
je     1400 <line_intersect_2D_3D+0x2c0>
cvttsd2si (%r14),%edi
call   1040 <fabs@plt>
movsd  0xe30(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    11e3 <line_intersect_2D_3D+0xa3>
movq   $0x0,(%r14)
xorpd  %xmm0,%xmm0
jmp    11e8 <line_intersect_2D_3D+0xa8>
movsd  (%r14),%xmm0
movsd  0xe18(%rip),%xmm1
subsd  %xmm0,%xmm1
cvttsd2si %xmm1,%edi
call   1040 <fabs@plt>
movsd  0xdfb(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    1222 <line_intersect_2D_3D+0xe2>
movabs $0x3ff0000000000000,%rax
mov    %rax,(%r14)
movsd  0xde8(%rip),%xmm0
jmp    1227 <line_intersect_2D_3D+0xe7>
movsd  (%r14),%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
ja     1400 <line_intersect_2D_3D+0x2c0>
ucomisd 0xdcb(%rip),%xmm0
ja     1400 <line_intersect_2D_3D+0x2c0>
mov    0xb0(%rsp),%r14
lea    0x40(%rsp),%rax
movups 0x0(%rbp),%xmm0
movaps %xmm0,0x10(%rsp)
movsd  0x10(%rbp),%xmm0
movsd  %xmm0,0x20(%rsp)
movups 0x0(%r13),%xmm0
movups %xmm0,0x28(%rsp)
movsd  0x10(%r13),%xmm0
movsd  %xmm0,0x38(%rsp)
xorpd  %xmm0,%xmm0
movapd %xmm0,(%rax)
movq   $0x0,0x10(%rax)
lea    0x10(%rsp),%rdi
lea    0x60(%rsp),%rcx
mov    %rbx,%rsi
mov    %r15,%rdx
mov    %r14,%r8
call   1030 <intersect_tri_with_line@plt>
test   %eax,%eax
je     1400 <line_intersect_2D_3D+0x2c0>
cvttsd2si (%r14),%edi
call   1040 <fabs@plt>
movsd  0xd44(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    12cf <line_intersect_2D_3D+0x18f>
movq   $0x0,(%r14)
xorpd  %xmm0,%xmm0
jmp    12d4 <line_intersect_2D_3D+0x194>
movsd  (%r14),%xmm0
movsd  0xd2c(%rip),%xmm1
subsd  %xmm0,%xmm1
cvttsd2si %xmm1,%edi
call   1040 <fabs@plt>
movsd  0xd0f(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    130e <line_intersect_2D_3D+0x1ce>
movabs $0x3ff0000000000000,%rax
mov    %rax,(%r14)
movsd  0xcfc(%rip),%xmm1
jmp    1313 <line_intersect_2D_3D+0x1d3>
movsd  (%r14),%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
ja     1400 <line_intersect_2D_3D+0x2c0>
ucomisd 0xcdf(%rip),%xmm1
ja     1400 <line_intersect_2D_3D+0x2c0>
movsd  %xmm1,(%rsp)
mov    %rbp,%rdi
mov    %r13,%rsi
call   1060 <cross@plt>
mov    %rax,%rbp
mov    %rbx,%rdi
mov    %r15,%rsi
call   1060 <cross@plt>
mov    %rbp,%rdi
mov    %rax,%rsi
call   1060 <cross@plt>
mov    %rax,%rdi
call   1050 <metric@plt>
movsd  0xc98(%rip),%xmm1
ucomisd %xmm0,%xmm1
ja     1400 <line_intersect_2D_3D+0x2c0>
movsd  (%rbx),%xmm0
movsd  (%r15),%xmm1
subsd  %xmm0,%xmm1
movsd  (%rsp),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    0x8(%rsp),%rbp
movsd  %xmm1,0x0(%rbp)
movsd  0x8(%rbx),%xmm0
movsd  0x8(%r15),%xmm1
subsd  %xmm0,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rbp)
movsd  0x10(%rbx),%xmm0
movsd  0x10(%r15),%xmm1
subsd  %xmm0,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rbp)
mov    %rbp,%rdi
call   1050 <metric@plt>
movupd 0x0(%rbp),%xmm1
movapd %xmm0,%xmm2
unpcklpd %xmm0,%xmm2
divpd  %xmm2,%xmm1
movupd %xmm1,0x0(%rbp)
movsd  0x10(%rbp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rbp)
mov    $0x1,%r12d
mov    %r12d,%eax
add    $0x78,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @line_intersect_2D_3D(double* %0, double* %1, double* %2, double* %3, double* %4, double* %5, double* %6) {
%8 = alloca i32
%9 = alloca double*
%10 = alloca double*
%11 = alloca double*
%12 = alloca double*
%13 = alloca double*
%14 = alloca double*
%15 = alloca double*
%16 = alloca [9 x double]
%17 = alloca [2 x double]
%18 = alloca double
%19 = alloca [3 x double]
%20 = alloca [3 x double]
%21 = alloca [3 x double]
%22 = alloca double
%23 = alloca double
%24 = alloca double
%25 = alloca i32
%26 = alloca i32
%27 = alloca i32
store double* %0, double** %9
store double* %1, double** %10
store double* %2, double** %11
store double* %3, double** %12
store double* %4, double** %13
store double* %5, double** %14
store double* %6, double** %15
%28 = load double*, double** %11
%29 = getelementptr inbounds double, double* %28, i64 0
%30 = load double, double* %29
%31 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 0
store double %30, double* %31
%32 = load double*, double** %11
%33 = getelementptr inbounds double, double* %32, i64 1
%34 = load double, double* %33
%35 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 1
store double %34, double* %35
%36 = load double*, double** %11
%37 = getelementptr inbounds double, double* %36, i64 2
%38 = load double, double* %37
%39 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 2
store double %38, double* %39
%40 = load double*, double** %12
%41 = getelementptr inbounds double, double* %40, i64 0
%42 = load double, double* %41
%43 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 3
store double %42, double* %43
%44 = load double*, double** %12
%45 = getelementptr inbounds double, double* %44, i64 1
%46 = load double, double* %45
%47 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 4
store double %46, double* %47
%48 = load double*, double** %12
%49 = getelementptr inbounds double, double* %48, i64 2
%50 = load double, double* %49
%51 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 5
store double %50, double* %51
%52 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 6
store double 0.000000e+00, double* %52
%53 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 7
store double 0.000000e+00, double* %53
%54 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 8
store double 0.000000e+00, double* %54
%55 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 0
%56 = load double*, double** %9
%57 = load double*, double** %10
%58 = getelementptr inbounds [2 x double], [2 x double]* %17, i64 0, i64 0
%59 = load double*, double** %14
%60 = call i32 @intersect_tri_with_line(double* %55, double* %56, double* %57, double* %58, double* %59)
store i32 %60, i32* %26
%61 = load i32, i32* %26
%62 = icmp ne i32 %61, 0
br i1 %62, label %64, label %63
63: ; preds = %7
store i32 0, i32* %8
br label %227
64: ; preds = %7
%65 = load double*, double** %14
%66 = load double, double* %65
%67 = fptosi double %66 to i32
%68 = call double @fabs(i32 %67)
%69 = fcmp olt double %68, 1.000000e-10
br i1 %69, label %70, label %72
70: ; preds = %64
%71 = load double*, double** %14
store double 0.000000e+00, double* %71
br label %72
72: ; preds = %70, %64
%73 = load double*, double** %14
%74 = load double, double* %73
%75 = fsub double 1.000000e+00, %74
%76 = fptosi double %75 to i32
%77 = call double @fabs(i32 %76)
%78 = fcmp olt double %77, 1.000000e-10
br i1 %78, label %79, label %81
79: ; preds = %72
%80 = load double*, double** %14
store double 1.000000e+00, double* %80
br label %81
81: ; preds = %79, %72
%82 = load double*, double** %14
%83 = load double, double* %82
%84 = fcmp olt double %83, 0.000000e+00
br i1 %84, label %89, label %85
85: ; preds = %81
%86 = load double*, double** %14
%87 = load double, double* %86
%88 = fcmp ogt double %87, 1.000000e+00
br i1 %88, label %89, label %90
89: ; preds = %85, %81
store i32 0, i32* %8
br label %227
90: ; preds = %85
%91 = load double*, double** %9
%92 = getelementptr inbounds double, double* %91, i64 0
%93 = load double, double* %92
%94 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 0
store double %93, double* %94
%95 = load double*, double** %9
%96 = getelementptr inbounds double, double* %95, i64 1
%97 = load double, double* %96
%98 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 1
store double %97, double* %98
%99 = load double*, double** %9
%100 = getelementptr inbounds double, double* %99, i64 2
%101 = load double, double* %100
%102 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 2
store double %101, double* %102
%103 = load double*, double** %10
%104 = getelementptr inbounds double, double* %103, i64 0
%105 = load double, double* %104
%106 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 3
store double %105, double* %106
%107 = load double*, double** %10
%108 = getelementptr inbounds double, double* %107, i64 1
%109 = load double, double* %108
%110 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 4
store double %109, double* %110
%111 = load double*, double** %10
%112 = getelementptr inbounds double, double* %111, i64 2
%113 = load double, double* %112
%114 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 5
store double %113, double* %114
%115 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 6
store double 0.000000e+00, double* %115
%116 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 7
store double 0.000000e+00, double* %116
%117 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 8
store double 0.000000e+00, double* %117
%118 = getelementptr inbounds [9 x double], [9 x double]* %16, i64 0, i64 0
%119 = load double*, double** %11
%120 = load double*, double** %12
%121 = getelementptr inbounds [2 x double], [2 x double]* %17, i64 0, i64 0
%122 = load double*, double** %15
%123 = call i32 @intersect_tri_with_line(double* %118, double* %119, double* %120, double* %121, double* %122)
store i32 %123, i32* %27
%124 = load i32, i32* %27
%125 = icmp ne i32 %124, 0
br i1 %125, label %127, label %126
126: ; preds = %90
store i32 0, i32* %8
br label %227
127: ; preds = %90
%128 = load double*, double** %15
%129 = load double, double* %128
%130 = fptosi double %129 to i32
%131 = call double @fabs(i32 %130)
%132 = fcmp olt double %131, 1.000000e-10
br i1 %132, label %133, label %135
133: ; preds = %127
%134 = load double*, double** %15
store double 0.000000e+00, double* %134
br label %135
135: ; preds = %133, %127
%136 = load double*, double** %15
%137 = load double, double* %136
%138 = fsub double 1.000000e+00, %137
%139 = fptosi double %138 to i32
%140 = call double @fabs(i32 %139)
%141 = fcmp olt double %140, 1.000000e-10
br i1 %141, label %142, label %144
142: ; preds = %135
%143 = load double*, double** %15
store double 1.000000e+00, double* %143
br label %144
144: ; preds = %142, %135
%145 = load double*, double** %15
%146 = load double, double* %145
%147 = fcmp olt double %146, 0.000000e+00
br i1 %147, label %152, label %148
148: ; preds = %144
%149 = load double*, double** %15
%150 = load double, double* %149
%151 = fcmp ogt double %150, 1.000000e+00
br i1 %151, label %152, label %153
152: ; preds = %148, %144
store i32 0, i32* %8
br label %227
153: ; preds = %148
%154 = load double*, double** %15
%155 = load double, double* %154
store double %155, double* %18
%156 = load double*, double** %9
%157 = load double*, double** %10
%158 = call double* @cross(double* %156, double* %157)
%159 = load double*, double** %11
%160 = load double*, double** %12
%161 = call double* @cross(double* %159, double* %160)
%162 = call double* @cross(double* %158, double* %161)
%163 = call double @metric(double* %162)
store double %163, double* %22
%164 = load double, double* %22
%165 = fcmp olt double %164, 1.000000e-10
br i1 %165, label %166, label %167
166: ; preds = %153
store i32 0, i32* %8
br label %227
167: ; preds = %153
%168 = load double*, double** %11
%169 = getelementptr inbounds double, double* %168, i64 0
%170 = load double, double* %169
%171 = load double, double* %18
%172 = load double*, double** %12
%173 = getelementptr inbounds double, double* %172, i64 0
%174 = load double, double* %173
%175 = load double*, double** %11
%176 = getelementptr inbounds double, double* %175, i64 0
%177 = load double, double* %176
%178 = fsub double %174, %177
%179 = call double @llvm.fmuladd.f64(double %171, double %178, double %170)
%180 = load double*, double** %13
%181 = getelementptr inbounds double, double* %180, i64 0
store double %179, double* %181
%182 = load double*, double** %11
%183 = getelementptr inbounds double, double* %182, i64 1
%184 = load double, double* %183
%185 = load double, double* %18
%186 = load double*, double** %12
%187 = getelementptr inbounds double, double* %186, i64 1
%188 = load double, double* %187
%189 = load double*, double** %11
%190 = getelementptr inbounds double, double* %189, i64 1
%191 = load double, double* %190
%192 = fsub double %188, %191
%193 = call double @llvm.fmuladd.f64(double %185, double %192, double %184)
%194 = load double*, double** %13
%195 = getelementptr inbounds double, double* %194, i64 1
store double %193, double* %195
%196 = load double*, double** %11
%197 = getelementptr inbounds double, double* %196, i64 2
%198 = load double, double* %197
%199 = load double, double* %18
%200 = load double*, double** %12
%201 = getelementptr inbounds double, double* %200, i64 2
%202 = load double, double* %201
%203 = load double*, double** %11
%204 = getelementptr inbounds double, double* %203, i64 2
%205 = load double, double* %204
%206 = fsub double %202, %205
%207 = call double @llvm.fmuladd.f64(double %199, double %206, double %198)
%208 = load double*, double** %13
%209 = getelementptr inbounds double, double* %208, i64 2
store double %207, double* %209
%210 = load double*, double** %13
%211 = call double @metric(double* %210)
store double %211, double* %24
store i32 0, i32* %25
br label %212
212: ; preds = %223, %167
%213 = load i32, i32* %25
%214 = icmp slt i32 %213, 3
br i1 %214, label %215, label %226
215: ; preds = %212
%216 = load double, double* %24
%217 = load double*, double** %13
%218 = load i32, i32* %25
%219 = sext i32 %218 to i64
%220 = getelementptr inbounds double, double* %217, i64 %219
%221 = load double, double* %220
%222 = fdiv double %221, %216
store double %222, double* %220
br label %223
223: ; preds = %215
%224 = load i32, i32* %25
%225 = add nsw i32 %224, 1
store i32 %225, i32* %25
br label %212
226: ; preds = %212
store i32 1, i32* %8
br label %227
227: ; preds = %226, %166, %152, %126, %89, %63
%228 = load i32, i32* %8
ret i32 %228
}

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