#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 /*<<< orphan*/ assert(int);
double fabs(float);
float t28_routine();
void t28() {
  float threads[32], v1 = 3.14;
  for (int i = 0; i < 32; i++)
    threads[i] = -1;
#pragma acc parallel num_gangs(1) vector_length(32) copy(v1)
  {
    float val = t28_routine();
#pragma acc loop vector
    for (int i = 0; i < 32; i++)
      threads[i] = val + v1 * i;
  }
  for (int i = 0; i < 32; i++)
    assert(fabs(threads[i] - (t28_routine() + v1 * i)) < 0.0001);
}


x86 assembly (clang, -O0):
<t28>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
movss  0xebd(%rip),%xmm0
movss  %xmm0,-0x84(%rbp)
ff
movl   $0x0,-0x88(%rbp)
cmpl   $0x20,-0x88(%rbp)
jge    118b <t28+0x5b>
movslq -0x88(%rbp),%rax
movss  0xe93(%rip),%xmm0
movss  %xmm0,-0x80(%rbp,%rax,4)
mov    -0x88(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x88(%rbp)
jmp    1155 <t28+0x25>
mov    $0x0,%al
call   1050 <t28_routine@plt>
movss  %xmm0,-0x8c(%rbp)
ff
movl   $0x0,-0x90(%rbp)
cmpl   $0x20,-0x90(%rbp)
jge    11f2 <t28+0xc2>
movss  -0x8c(%rbp),%xmm1
ff
movss  -0x84(%rbp),%xmm0
ff
cvtsi2ssl -0x90(%rbp),%xmm2
ff
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movslq -0x90(%rbp),%rax
movss  %xmm0,-0x80(%rbp,%rax,4)
mov    -0x90(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x90(%rbp)
jmp    11a4 <t28+0x74>
movl   $0x0,-0x94(%rbp)
cmpl   $0x20,-0x94(%rbp)
jge    1281 <t28+0x151>
movslq -0x94(%rbp),%rax
movss  -0x80(%rbp,%rax,4),%xmm0
movss  %xmm0,-0x98(%rbp)
ff
mov    $0x0,%al
call   1050 <t28_routine@plt>
movaps %xmm0,%xmm2
movss  -0x98(%rbp),%xmm0
ff
movss  -0x84(%rbp),%xmm1
ff
cvtsi2ssl -0x94(%rbp),%xmm3
ff
mulss  %xmm3,%xmm1
addss  %xmm2,%xmm1
subss  %xmm1,%xmm0
call   1030 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xdac(%rip),%xmm0
ucomisd %xmm1,%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
mov    -0x94(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x94(%rbp)
jmp    11fc <t28+0xcc>
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<t28>:
push   %rbx
sub    $0x90,%rsp
movaps 0xec1(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps %xmm0,0x20(%rsp)
movaps %xmm0,0x30(%rsp)
movaps %xmm0,0x40(%rsp)
movaps %xmm0,0x50(%rsp)
movaps %xmm0,0x60(%rsp)
movaps %xmm0,0x70(%rsp)
movaps %xmm0,0x80(%rsp)
xor    %eax,%eax
call   1050 <t28_routine@plt>
shufps $0x0,%xmm0,%xmm0
movaps 0xe94(%rip),%xmm1
addps  %xmm0,%xmm1
movaps %xmm1,0x10(%rsp)
movaps 0xe95(%rip),%xmm1
addps  %xmm0,%xmm1
movaps %xmm1,0x20(%rsp)
movaps 0xe96(%rip),%xmm1
addps  %xmm0,%xmm1
movaps %xmm1,0x30(%rsp)
movaps 0xe97(%rip),%xmm1
addps  %xmm0,%xmm1
movaps %xmm1,0x40(%rsp)
movaps 0xe98(%rip),%xmm1
addps  %xmm0,%xmm1
movaps %xmm1,0x50(%rsp)
movaps 0xe99(%rip),%xmm1
addps  %xmm0,%xmm1
movaps %xmm1,0x60(%rsp)
movaps 0xe9a(%rip),%xmm1
addps  %xmm0,%xmm1
movaps %xmm1,0x70(%rsp)
addps  0xe9b(%rip),%xmm0
movaps %xmm0,0x80(%rsp)
xor    %ebx,%ebx
nop
movss  0x10(%rsp,%rbx,4),%xmm0
movss  %xmm0,0xc(%rsp)
xor    %eax,%eax
call   1050 <t28_routine@plt>
xorps  %xmm1,%xmm1
cvtsi2ss %ebx,%xmm1
mulss  0xe7e(%rip),%xmm1
addss  %xmm0,%xmm1
movss  0xc(%rsp),%xmm0
subss  %xmm1,%xmm0
call   1030 <fabs@plt>
xor    %edi,%edi
movsd  0xe69(%rip),%xmm1
ucomisd %xmm0,%xmm1
seta   %dil
call   1040 <assert@plt>
add    $0x1,%rbx
cmp    $0x20,%rbx
jne    11f0 <t28+0xc0>
add    $0x90,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define void @t28() {
%1 = alloca [32 x float]
%2 = alloca float
%3 = alloca i32
%4 = alloca float
%5 = alloca i32
%6 = alloca i32
store float 0x40091EB860000000, float* %2
store i32 0, i32* %3
br label %7
7: ; preds = %14, %0
%8 = load i32, i32* %3
%9 = icmp slt i32 %8, 32
br i1 %9, label %10, label %17
10: ; preds = %7
%11 = load i32, i32* %3
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 %12
store float -1.000000e+00, float* %13
br label %14
14: ; preds = %10
%15 = load i32, i32* %3
%16 = add nsw i32 %15, 1
store i32 %16, i32* %3
br label %7
17: ; preds = %7
%18 = call float (...) @t28_routine()
store float %18, float* %4
store i32 0, i32* %5
br label %19
19: ; preds = %31, %17
%20 = load i32, i32* %5
%21 = icmp slt i32 %20, 32
br i1 %21, label %22, label %34
22: ; preds = %19
%23 = load float, float* %4
%24 = load float, float* %2
%25 = load i32, i32* %5
%26 = sitofp i32 %25 to float
%27 = call float @llvm.fmuladd.f32(float %24, float %26, float %23)
%28 = load i32, i32* %5
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 %29
store float %27, float* %30
br label %31
31: ; preds = %22
%32 = load i32, i32* %5
%33 = add nsw i32 %32, 1
store i32 %33, i32* %5
br label %19
34: ; preds = %19
store i32 0, i32* %6
br label %35
35: ; preds = %53, %34
%36 = load i32, i32* %6
%37 = icmp slt i32 %36, 32
br i1 %37, label %38, label %56
38: ; preds = %35
%39 = load i32, i32* %6
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 %40
%42 = load float, float* %41
%43 = call float (...) @t28_routine()
%44 = load float, float* %2
%45 = load i32, i32* %6
%46 = sitofp i32 %45 to float
%47 = call float @llvm.fmuladd.f32(float %44, float %46, float %43)
%48 = fsub float %42, %47
%49 = call double @fabs(float %48)
%50 = fcmp olt double %49, 1.000000e-04
%51 = zext i1 %50 to i32
%52 = call i32 @assert(i32 %51)
br label %53
53: ; preds = %38
%54 = load i32, i32* %6
%55 = add nsw i32 %54, 1
store i32 %55, i32* %6
br label %35
56: ; preds = %35
ret void
}

LLVM IR (-O2):
define void @t28() {
%1 = alloca [32 x float]
%2 = bitcast [32 x float]* %1 to i8*
%3 = bitcast [32 x float]* %1 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %3
%4 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 4
%5 = bitcast float* %4 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %5
%6 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 8
%7 = bitcast float* %6 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %7
%8 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 12
%9 = bitcast float* %8 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %9
%10 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 16
%11 = bitcast float* %10 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %11
%12 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 20
%13 = bitcast float* %12 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %13
%14 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 24
%15 = bitcast float* %14 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %15
%16 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 28
%17 = bitcast float* %16 to <4 x float>*
store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>, <4 x float>* %17
%18 = tail call float (...) @t28_routine()
%19 = insertelement <4 x float> poison, float %18, i64 0
%20 = shufflevector <4 x float> %19, <4 x float> poison, <4 x i32> zeroinitializer
%21 = fadd <4 x float> %20, <float 0.000000e+00, float 0x40091EB860000000, float 0x40191EB860000000, float 0x4022D70A40000000>
%22 = bitcast [32 x float]* %1 to <4 x float>*
store <4 x float> %21, <4 x float>* %22
%23 = fadd <4 x float> %20, <float 0x40291EB860000000, float 0x402F666680000000, float 0x4032D70A40000000, float 0x4035FAE160000000>
%24 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 4
%25 = bitcast float* %24 to <4 x float>*
store <4 x float> %23, <4 x float>* %25
%26 = fadd <4 x float> %20, <float 0x40391EB860000000, float 0x403C428F60000000, float 0x403F666680000000, float 0x4041451EC0000000>
%27 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 8
%28 = bitcast float* %27 to <4 x float>*
store <4 x float> %26, <4 x float>* %28
%29 = fadd <4 x float> %20, <float 0x4042D70A40000000, float 0x404468F5C0000000, float 0x4045FAE160000000, float 0x40478CCCE0000000>
%30 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 12
%31 = bitcast float* %30 to <4 x float>*
store <4 x float> %29, <4 x float>* %31
%32 = fadd <4 x float> %20, <float 0x40491EB860000000, float 0x404AB0A3E0000000, float 0x404C428F60000000, float 0x404DD47B00000000>
%33 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 16
%34 = bitcast float* %33 to <4 x float>*
store <4 x float> %32, <4 x float>* %34
%35 = fadd <4 x float> %20, <float 0x404F666680000000, float 0x40507C2900000000, float 0x4051451EC0000000, float 0x40520E1480000000>
%36 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 20
%37 = bitcast float* %36 to <4 x float>*
store <4 x float> %35, <4 x float>* %37
%38 = fadd <4 x float> %20, <float 0x4052D70A40000000, float 7.850000e+01, float 0x405468F5C0000000, float 0x405531EBA0000000>
%39 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 24
%40 = bitcast float* %39 to <4 x float>*
store <4 x float> %38, <4 x float>* %40
%41 = fadd <4 x float> %20, <float 0x4055FAE160000000, float 0x4056C3D720000000, float 0x40578CCCE0000000, float 0x405855C2A0000000>
%42 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 28
%43 = bitcast float* %42 to <4 x float>*
store <4 x float> %41, <4 x float>* %43
br label %45
44: ; preds = %45
ret void
45: ; preds = %0, %45
%46 = phi i64 [ %58, %45 ], [ 0, %0 ]
%47 = getelementptr inbounds [32 x float], [32 x float]* %1, i64 0, i64 %46
%48 = load float, float* %47
%49 = tail call float (...) @t28_routine()
%50 = trunc i64 %46 to i32
%51 = sitofp i32 %50 to float
%52 = tail call float @llvm.fmuladd.f32(float %51, float 0x40091EB860000000, float %49)
%53 = fsub float %48, %52
%54 = tail call double @fabs(float %53)
%55 = fcmp olt double %54, 1.000000e-04
%56 = zext i1 %55 to i32
%57 = tail call i32 @assert(i32 %56)
%58 = add nuw nsw i64 %46, 1
%59 = icmp eq i64 %58, 32
br i1 %59, label %44, label %45
}