#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 powf(float, double);
void dt_XYZ_to_sRGB(const float *const XYZ, float *sRGB) {
  const float xyz_to_srgb_matrix[3][3] = {{3.1338561, -1.6168667, -0.4906146},
                                          {-0.9787684, 1.9161415, 0.0334540},
                                          {0.0719453, -0.2289914, 1.4052427}};
  float rgb[3] = {0, 0, 0};
  for (int r = 0; r < 3; r++)
    for (int c = 0; c < 3; c++)
      rgb[r] += xyz_to_srgb_matrix[r][c] * XYZ[c];
  for (int c = 0; c < 3; c++)
    sRGB[c] = rgb[c] <= 0.0031308
                  ? 12.92 * rgb[c]
                  : (1.0 + 0.055) * powf(rgb[c], 1.0 / 2.4) - 0.055;
}


x86 assembly (clang, -O0):
<dt_XYZ_to_sRGB>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
lea    -0x40(%rbp),%rdi
lea    0xee5(%rip),%rsi
mov    $0x24,%edx
call   1050 <memcpy@plt>
lea    -0x4c(%rbp),%rdi
xor    %esi,%esi
mov    $0xc,%edx
call   1040 <memset@plt>
movl   $0x0,-0x50(%rbp)
cmpl   $0x3,-0x50(%rbp)
jge    11e5 <dt_XYZ_to_sRGB+0xb5>
movl   $0x0,-0x54(%rbp)
cmpl   $0x3,-0x54(%rbp)
jge    11d2 <dt_XYZ_to_sRGB+0xa2>
movslq -0x50(%rbp),%rcx
lea    -0x40(%rbp),%rax
imul   $0xc,%rcx,%rcx
add    %rcx,%rax
movslq -0x54(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x54(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movslq -0x50(%rbp),%rax
movss  -0x4c(%rbp,%rax,4),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x4c(%rbp,%rax,4)
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
jmp    117d <dt_XYZ_to_sRGB+0x4d>
jmp    11d7 <dt_XYZ_to_sRGB+0xa7>
mov    -0x50(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x50(%rbp)
jmp    116c <dt_XYZ_to_sRGB+0x3c>
movl   $0x0,-0x58(%rbp)
cmpl   $0x3,-0x58(%rbp)
jge    1292 <dt_XYZ_to_sRGB+0x162>
movslq -0x58(%rbp),%rax
movss  -0x4c(%rbp,%rax,4),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xdf4(%rip),%xmm0
ucomisd %xmm1,%xmm0
jb     123a <dt_XYZ_to_sRGB+0x10a>
movslq -0x58(%rbp),%rax
movss  -0x4c(%rbp,%rax,4),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xdf4(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
jmp    126e <dt_XYZ_to_sRGB+0x13e>
movslq -0x58(%rbp),%rax
movss  -0x4c(%rbp,%rax,4),%xmm0
movsd  0xdcc(%rip),%xmm1
call   1030 <powf@plt>
movsd  0xdaf(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xdab(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x60(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x10(%rbp),%rax
movslq -0x58(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x58(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x58(%rbp)
jmp    11ec <dt_XYZ_to_sRGB+0xbc>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dt_XYZ_to_sRGB>:
push   %rbx
sub    $0x10,%rsp
mov    %rsi,%rbx
movss  (%rdi),%xmm1
movss  0x4(%rdi),%xmm6
movss  0xed7(%rip),%xmm0
mulss  %xmm1,%xmm0
xorps  %xmm2,%xmm2
addss  %xmm2,%xmm0
movss  0xec8(%rip),%xmm3
mulss  %xmm6,%xmm3
addss  %xmm0,%xmm3
movss  0x8(%rdi),%xmm5
movss  0xeb7(%rip),%xmm0
mulss  %xmm5,%xmm0
addss  %xmm3,%xmm0
movss  0xeab(%rip),%xmm3
mulss  %xmm1,%xmm3
addss  %xmm2,%xmm3
movss  0xe9f(%rip),%xmm4
mulss  %xmm6,%xmm4
addss  %xmm3,%xmm4
movss  0xe93(%rip),%xmm3
mulss  %xmm5,%xmm3
addss  %xmm4,%xmm3
mulss  0xe87(%rip),%xmm1
mulss  0xe83(%rip),%xmm6
addss  %xmm2,%xmm1
addss  %xmm1,%xmm6
mulss  0xe77(%rip),%xmm5
xorps  %xmm1,%xmm1
cvtss2sd %xmm0,%xmm1
movsd  0xe70(%rip),%xmm2
ucomisd %xmm1,%xmm2
jae    120c <dt_XYZ_to_sRGB+0xfc>
movsd  0xe72(%rip),%xmm1
movss  %xmm5,0x4(%rsp)
movss  %xmm6,0xc(%rsp)
movss  %xmm3,0x8(%rsp)
call   1030 <powf@plt>
movss  0x8(%rsp),%xmm3
movsd  0xe3d(%rip),%xmm2
movss  0xc(%rsp),%xmm6
movss  0x4(%rsp),%xmm5
movaps %xmm0,%xmm1
mulsd  0xe3e(%rip),%xmm1
addsd  0xe3e(%rip),%xmm1
jmp    1214 <dt_XYZ_to_sRGB+0x104>
mulsd  0xe1c(%rip),%xmm1
addss  %xmm6,%xmm5
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
movss  %xmm0,(%rbx)
xorps  %xmm0,%xmm0
cvtss2sd %xmm3,%xmm0
ucomisd %xmm0,%xmm2
jae    1266 <dt_XYZ_to_sRGB+0x156>
movsd  0xe00(%rip),%xmm1
movaps %xmm3,%xmm0
movss  %xmm5,0x4(%rsp)
call   1030 <powf@plt>
movsd  0xdda(%rip),%xmm2
movss  0x4(%rsp),%xmm5
mulsd  0xde4(%rip),%xmm0
addsd  0xde4(%rip),%xmm0
jmp    126e <dt_XYZ_to_sRGB+0x15e>
mulsd  0xdc2(%rip),%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x4(%rbx)
xorps  %xmm0,%xmm0
cvtss2sd %xmm5,%xmm0
ucomisd %xmm0,%xmm2
jae    12a6 <dt_XYZ_to_sRGB+0x196>
movsd  0xdac(%rip),%xmm1
movaps %xmm5,%xmm0
call   1030 <powf@plt>
mulsd  0xda4(%rip),%xmm0
addsd  0xda4(%rip),%xmm0
jmp    12ae <dt_XYZ_to_sRGB+0x19e>
mulsd  0xd82(%rip),%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,0x8(%rbx)
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@__const.dt_XYZ_to_sRGB.xyz_to_srgb_matrix = [3 x [3 x float]] [[3 x float] [float 0x4009122320000000, float 0xBFF9DEAFA0000000, float 0xBFDF663AC0000000], [3 x float] [float 0xBFEF521220000000, float 0x3FFEA88400000000, float 0x3FA120E200000000], [3 x float] [float 0x3FB26B01E0000000, float 0xBFCD4F9720000000, float 0x3FF67BDFC0000000]]
define void @dt_XYZ_to_sRGB(float* %0, float* %1) {
%3 = alloca float*
%4 = alloca float*
%5 = alloca [3 x [3 x float]]
%6 = alloca [3 x float]
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store float* %0, float** %3
store float* %1, float** %4
%10 = bitcast [3 x [3 x float]]* %5 to i8*
%11 = bitcast [3 x float]* %6 to i8*
store i32 0, i32* %7
br label %12
12: ; preds = %41, %2
%13 = load i32, i32* %7
%14 = icmp slt i32 %13, 3
br i1 %14, label %15, label %44
15: ; preds = %12
store i32 0, i32* %8
br label %16
16: ; preds = %37, %15
%17 = load i32, i32* %8
%18 = icmp slt i32 %17, 3
br i1 %18, label %19, label %40
19: ; preds = %16
%20 = load i32, i32* %7
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds [3 x [3 x float]], [3 x [3 x float]]* %5, i64 0, i64 %21
%23 = load i32, i32* %8
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds [3 x float], [3 x float]* %22, i64 0, i64 %24
%26 = load float, float* %25
%27 = load float*, float** %3
%28 = load i32, i32* %8
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds float, float* %27, i64 %29
%31 = load float, float* %30
%32 = load i32, i32* %7
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds [3 x float], [3 x float]* %6, i64 0, i64 %33
%35 = load float, float* %34
%36 = call float @llvm.fmuladd.f32(float %26, float %31, float %35)
store float %36, float* %34
br label %37
37: ; preds = %19
%38 = load i32, i32* %8
%39 = add nsw i32 %38, 1
store i32 %39, i32* %8
br label %16
40: ; preds = %16
br label %41
41: ; preds = %40
%42 = load i32, i32* %7
%43 = add nsw i32 %42, 1
store i32 %43, i32* %7
br label %12
44: ; preds = %12
store i32 0, i32* %9
br label %45
45: ; preds = %76, %44
%46 = load i32, i32* %9
%47 = icmp slt i32 %46, 3
br i1 %47, label %48, label %79
48: ; preds = %45
%49 = load i32, i32* %9
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds [3 x float], [3 x float]* %6, i64 0, i64 %50
%52 = load float, float* %51
%53 = fpext float %52 to double
%54 = fcmp ole double %53, 3.130800e-03
br i1 %54, label %55, label %62
55: ; preds = %48
%56 = load i32, i32* %9
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds [3 x float], [3 x float]* %6, i64 0, i64 %57
%59 = load float, float* %58
%60 = fpext float %59 to double
%61 = fmul double 1.292000e+01, %60
br label %69
62: ; preds = %48
%63 = load i32, i32* %9
%64 = sext i32 %63 to i64
%65 = getelementptr inbounds [3 x float], [3 x float]* %6, i64 0, i64 %64
%66 = load float, float* %65
%67 = call double @powf(float %66, double 0x3FDAAAAAAAAAAAAB)
%68 = call double @llvm.fmuladd.f64(double 1.055000e+00, double %67, double -5.500000e-02)
br label %69
69: ; preds = %62, %55
%70 = phi double [ %61, %55 ], [ %68, %62 ]
%71 = fptrunc double %70 to float
%72 = load float*, float** %4
%73 = load i32, i32* %9
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds float, float* %72, i64 %74
store float %71, float* %75
br label %76
76: ; preds = %69
%77 = load i32, i32* %9
%78 = add nsw i32 %77, 1
store i32 %78, i32* %9
br label %45
79: ; preds = %45
ret void
}

LLVM IR (-O2):
define void @dt_XYZ_to_sRGB(float* nocapture %0, float* nocapture writeonly %1) {
%3 = load float, float* %0
%4 = tail call float @llvm.fmuladd.f32(float %3, float 0x4009122320000000, float 0.000000e+00)
%5 = getelementptr inbounds float, float* %0, i64 1
%6 = load float, float* %5
%7 = tail call float @llvm.fmuladd.f32(float %6, float 0xBFF9DEAFA0000000, float %4)
%8 = getelementptr inbounds float, float* %0, i64 2
%9 = load float, float* %8
%10 = tail call float @llvm.fmuladd.f32(float %9, float 0xBFDF663AC0000000, float %7)
%11 = tail call float @llvm.fmuladd.f32(float %3, float 0xBFEF521220000000, float 0.000000e+00)
%12 = tail call float @llvm.fmuladd.f32(float %6, float 0x3FFEA88400000000, float %11)
%13 = tail call float @llvm.fmuladd.f32(float %9, float 0x3FA120E200000000, float %12)
%14 = tail call float @llvm.fmuladd.f32(float %3, float 0x3FB26B01E0000000, float 0.000000e+00)
%15 = tail call float @llvm.fmuladd.f32(float %6, float 0xBFCD4F9720000000, float %14)
%16 = tail call float @llvm.fmuladd.f32(float %9, float 0x3FF67BDFC0000000, float %15)
%17 = fpext float %10 to double
%18 = fcmp ugt double %17, 3.130800e-03
br i1 %18, label %21, label %19
19: ; preds = %2
%20 = fmul double %17, 1.292000e+01
br label %24
21: ; preds = %2
%22 = tail call double @powf(float %10, double 0x3FDAAAAAAAAAAAAB)
%23 = tail call double @llvm.fmuladd.f64(double %22, double 1.055000e+00, double -5.500000e-02)
br label %24
24: ; preds = %21, %19
%25 = phi double [ %20, %19 ], [ %23, %21 ]
%26 = fptrunc double %25 to float
store float %26, float* %1
%27 = fpext float %13 to double
%28 = fcmp ugt double %27, 3.130800e-03
br i1 %28, label %31, label %29
29: ; preds = %24
%30 = fmul double %27, 1.292000e+01
br label %34
31: ; preds = %24
%32 = tail call double @powf(float %13, double 0x3FDAAAAAAAAAAAAB)
%33 = tail call double @llvm.fmuladd.f64(double %32, double 1.055000e+00, double -5.500000e-02)
br label %34
34: ; preds = %31, %29
%35 = phi double [ %30, %29 ], [ %33, %31 ]
%36 = fptrunc double %35 to float
%37 = getelementptr inbounds float, float* %1, i64 1
store float %36, float* %37
%38 = fpext float %16 to double
%39 = fcmp ugt double %38, 3.130800e-03
br i1 %39, label %42, label %40
40: ; preds = %34
%41 = fmul double %38, 1.292000e+01
br label %45
42: ; preds = %34
%43 = tail call double @powf(float %16, double 0x3FDAAAAAAAAAAAAB)
%44 = tail call double @llvm.fmuladd.f64(double %43, double 1.055000e+00, double -5.500000e-02)
br label %45
45: ; preds = %42, %40
%46 = phi double [ %41, %40 ], [ %44, %42 ]
%47 = fptrunc double %46 to float
%48 = getelementptr inbounds float, float* %1, i64 2
store float %47, float* %48
ret void
}