Files
c3c/test/test_suite/initializer_lists/fasta.c3t
2021-11-16 17:46:44 +01:00

394 lines
15 KiB
C

// #target: x64-darwin
module fasta;
const IM = 139968u;
const IA = 3877u;
const IC = 29573u;
const SEED = 42u;
global uint seed = SEED;
fn float fasta_rand(float max)
{
seed = (seed * IA + IC) % IM;
return max * seed / IM;
}
private global char[] alu =
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"
"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"
"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"
"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"
"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"
"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"
"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
extern fn int atoi(char *s);
extern fn int printf(char *s, ...);
extern fn void putchar(int c);
global char[] iub = "acgtBDHKMNRSVWY";
global double[] iub_p = {
0.27,
0.12,
0.12,
0.27,
0.02,
0.02,
0.02,
0.02,
0.02,
0.02,
0.02,
0.02,
0.02,
0.02,
0.02 };
global char[] homosapiens = "acgt";
global double[] homosapiens_p = {
0.3029549426680,
0.1979883004921,
0.1975473066391,
0.3015094502008
};
const LINELEN = 60;
// slowest character-at-a-time output
fn void repeat_fasta(char[] seq, int n)
{
usize len = seq.len;
int i = void;
for (i = 0; i < n; i++)
{
putchar(seq[i % len]);
if (i % LINELEN == LINELEN - 1) putchar('\n');
}
if (i % LINELEN != 0) putchar('\n');
}
fn void random_fasta(char[] symb, double[] probability, int n)
{
assert(symb.len == probability.len);
int len = probability.len;
int i = void;
for (i = 0; i < n; i++)
{
double v = fasta_rand(1.0);
/* slowest idiomatic linear lookup. Fast if len is short though. */
int j = void;
for (j = 0; j < len - 1; j++)
{
v -= probability[j];
if (v < 0) break;
}
putchar(symb[j]);
if (i % LINELEN == LINELEN - 1) putchar('\n');
}
if (i % LINELEN != 0) putchar('\n');
}
fn void main(int argc, char **argv)
{
int n = 1000;
if (argc > 1) n = atoi(argv[1]);
printf(">ONE Homo sapiens alu\n");
repeat_fasta(alu, n * 2);
printf(">TWO IUB ambiguity codes\n");
random_fasta(iub, iub_p, n * 3);
printf(">THREE Homo sapiens frequency\n");
random_fasta(homosapiens, homosapiens_p, n * 5);
}
// #expect: fasta.ll
%"char[]" = type { i8*, i64 }
%"double[]" = type { double*, i64 }
@fasta.IM = constant i32 139968, align 4
@fasta.IA = constant i32 3877, align 4
@fasta.IC = constant i32 29573, align 4
@fasta.SEED = constant i32 42, align 4
@fasta.seed = global i32 42, align 4
@.str = private constant [288 x i8] c"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA\00", align 1
@fasta.alu = protected global %"char[]" { i8* getelementptr inbounds ([288 x i8], [288 x i8]* @.str, i32 0, i32 0), i64 287 }, align 8
@.str.11 = private constant [16 x i8] c"acgtBDHKMNRSVWY\00", align 1
@fasta.iub = global %"char[]" { i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.11, i32 0, i32 0), i64 15 }, align 8
@.taddr = private hidden global [15 x double] [double 2.700000e-01, double 1.200000e-01, double 1.200000e-01, double 2.700000e-01, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02], align 8
@fasta.iub_p = global %"double[]" { double* getelementptr inbounds ([15 x double], [15 x double]* @.taddr, i32 0, i32 0), i64 15 }, align 8
@.str.12 = private constant [5 x i8] c"acgt\00", align 1
@fasta.homosapiens = global %"char[]" { i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.12, i32 0, i32 0), i64 4 }, align 8
@.taddr.13 = private hidden global [4 x double] [double 0x3FD3639D20BAEB5B, double 0x3FC957AE3DCD561B, double 0x3FC9493AEAB6C2BF, double 0x3FD34BEE4B030838], align 8
@fasta.homosapiens_p = global %"double[]" { double* getelementptr inbounds ([4 x double], [4 x double]* @.taddr.13, i32 0, i32 0), i64 4 }, align 8
@fasta.LINELEN = constant i32 60, align 4
@.str.14 = private constant [23 x i8] c">ONE Homo sapiens alu\0A\00", align 1
@.str.15 = private constant [26 x i8] c">TWO IUB ambiguity codes\0A\00", align 1
@.str.16 = private constant [31 x i8] c">THREE Homo sapiens frequency\0A\00", align 1
; Function Attrs: nounwind
define float @fasta.fasta_rand(float %0) #0 {
entry:
%max = alloca float, align 4
store float %0, float* %max, align 4
%1 = load i32, i32* @fasta.seed, align 4
%mul = mul i32 %1, 3877
%add = add i32 %mul, 29573
%umod = urem i32 %add, 139968
store i32 %umod, i32* @fasta.seed, align 4
%2 = load float, float* %max, align 4
%3 = load i32, i32* @fasta.seed, align 4
%uifp = uitofp i32 %3 to float
%fmul = fmul float %2, %uifp
%fdiv = fdiv float %fmul, 1.399680e+05
ret float %fdiv
}
; Function Attrs: nounwind
declare i32 @atoi(i8*) #0
; Function Attrs: nounwind
declare i32 @printf(i8*, ...) #0
; Function Attrs: nounwind
declare void @putchar(i32) #0
; Function Attrs: nounwind
define void @fasta.repeat_fasta(i8* %0, i64 %1, i32 %2) #0 {
entry:
%seq = alloca %"char[]", align 8
%n = alloca i32, align 4
%len = alloca i64, align 8
%i = alloca i32, align 4
%pair = bitcast %"char[]"* %seq to { i8*, i64 }*
%3 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %pair, i32 0, i32 0
store i8* %0, i8** %3, align 8
%4 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %pair, i32 0, i32 1
store i64 %1, i64* %4, align 8
store i32 %2, i32* %n, align 4
%5 = getelementptr inbounds %"char[]", %"char[]"* %seq, i32 0, i32 1
%6 = load i64, i64* %5, align 8
store i64 %6, i64* %len, align 8
store i32 0, i32* %i, align 4
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%7 = load i32, i32* %i, align 4
%8 = load i32, i32* %n, align 4
%lt = icmp slt i32 %7, %8
br i1 %lt, label %for.body, label %for.exit
for.body: ; preds = %for.cond
%9 = getelementptr inbounds %"char[]", %"char[]"* %seq, i32 0, i32 0
%10 = load i8*, i8** %9, align 8
%11 = load i32, i32* %i, align 4
%sisiext = sext i32 %11 to i64
%12 = load i64, i64* %len, align 8
%smod = srem i64 %sisiext, %12
%ptroffset = getelementptr inbounds i8, i8* %10, i64 %smod
%13 = load i8, i8* %ptroffset, align 1
%uisiext = zext i8 %13 to i32
call void @putchar(i32 %uisiext)
%14 = load i32, i32* %i, align 4
%smod1 = srem i32 %14, 60
%eq = icmp eq i32 %smod1, 59
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %for.body
call void @putchar(i32 10)
br label %if.exit
if.exit: ; preds = %if.then, %for.body
br label %for.inc
for.inc: ; preds = %if.exit
%15 = load i32, i32* %i, align 4
%add = add i32 %15, 1
store i32 %add, i32* %i, align 4
br label %for.cond
for.exit: ; preds = %for.cond
%16 = load i32, i32* %i, align 4
%smod2 = srem i32 %16, 60
%neq = icmp ne i32 %smod2, 0
br i1 %neq, label %if.then3, label %if.exit4
if.then3: ; preds = %for.exit
call void @putchar(i32 10)
br label %if.exit4
if.exit4: ; preds = %if.then3, %for.exit
ret void
}
; Function Attrs: nounwind
define void @fasta.random_fasta(i8* %0, i64 %1, i8* %2, i64 %3, i32 %4) #0 {
entry:
%symb = alloca %"char[]", align 8
%probability = alloca %"double[]", align 8
%n = alloca i32, align 4
%len = alloca i32, align 4
%i = alloca i32, align 4
%v = alloca double, align 8
%j = alloca i32, align 4
%pair = bitcast %"char[]"* %symb to { i8*, i64 }*
%5 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %pair, i32 0, i32 0
store i8* %0, i8** %5, align 8
%6 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %pair, i32 0, i32 1
store i64 %1, i64* %6, align 8
%pair1 = bitcast %"double[]"* %probability to { i8*, i64 }*
%7 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %pair1, i32 0, i32 0
store i8* %2, i8** %7, align 8
%8 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %pair1, i32 0, i32 1
store i64 %3, i64* %8, align 8
store i32 %4, i32* %n, align 4
%9 = getelementptr inbounds %"char[]", %"char[]"* %symb, i32 0, i32 1
%10 = load i64, i64* %9, align 8
%11 = getelementptr inbounds %"double[]", %"double[]"* %probability, i32 0, i32 1
%12 = load i64, i64* %11, align 8
%eq = icmp eq i64 %10, %12
call void @llvm.assume(i1 %eq)
%13 = getelementptr inbounds %"double[]", %"double[]"* %probability, i32 0, i32 1
%14 = load i64, i64* %13, align 8
%uisitrunc = trunc i64 %14 to i32
store i32 %uisitrunc, i32* %len, align 4
store i32 0, i32* %i, align 4
br label %for.cond
for.cond: ; preds = %for.inc11, %entry
%15 = load i32, i32* %i, align 4
%16 = load i32, i32* %n, align 4
%lt = icmp slt i32 %15, %16
br i1 %lt, label %for.body, label %for.exit13
for.body: ; preds = %for.cond
%17 = call float @fasta.fasta_rand(float 1.000000e+00)
%fpfpext = fpext float %17 to double
store double %fpfpext, double* %v, align 8
store i32 0, i32* %j, align 4
br label %for.cond2
for.cond2: ; preds = %for.inc, %for.body
%18 = load i32, i32* %j, align 4
%19 = load i32, i32* %len, align 4
%sub = sub i32 %19, 1
%lt3 = icmp slt i32 %18, %sub
br i1 %lt3, label %for.body4, label %for.exit
for.body4: ; preds = %for.cond2
%20 = load double, double* %v, align 8
%21 = getelementptr inbounds %"double[]", %"double[]"* %probability, i32 0, i32 0
%22 = load double*, double** %21, align 8
%23 = load i32, i32* %j, align 4
%sisiext = sext i32 %23 to i64
%ptroffset = getelementptr inbounds double, double* %22, i64 %sisiext
%24 = load double, double* %ptroffset, align 8
%fsub = fsub double %20, %24
store double %fsub, double* %v, align 8
%25 = load double, double* %v, align 8
%lt5 = fcmp olt double %25, 0.000000e+00
br i1 %lt5, label %if.then, label %if.exit
if.then: ; preds = %for.body4
br label %for.exit
if.exit: ; preds = %for.body4
br label %for.inc
for.inc: ; preds = %if.exit
%26 = load i32, i32* %j, align 4
%add = add i32 %26, 1
store i32 %add, i32* %j, align 4
br label %for.cond2
for.exit: ; preds = %if.then, %for.cond2
%27 = getelementptr inbounds %"char[]", %"char[]"* %symb, i32 0, i32 0
%28 = load i8*, i8** %27, align 8
%29 = load i32, i32* %j, align 4
%sisiext6 = sext i32 %29 to i64
%ptroffset7 = getelementptr inbounds i8, i8* %28, i64 %sisiext6
%30 = load i8, i8* %ptroffset7, align 1
%uisiext = zext i8 %30 to i32
call void @putchar(i32 %uisiext)
%31 = load i32, i32* %i, align 4
%smod = srem i32 %31, 60
%eq8 = icmp eq i32 %smod, 59
br i1 %eq8, label %if.then9, label %if.exit10
if.then9: ; preds = %for.exit
call void @putchar(i32 10)
br label %if.exit10
if.exit10: ; preds = %if.then9, %for.exit
br label %for.inc11
for.inc11: ; preds = %if.exit10
%32 = load i32, i32* %i, align 4
%add12 = add i32 %32, 1
store i32 %add12, i32* %i, align 4
br label %for.cond
for.exit13: ; preds = %for.cond
%33 = load i32, i32* %i, align 4
%smod14 = srem i32 %33, 60
%neq = icmp ne i32 %smod14, 0
br i1 %neq, label %if.then15, label %if.exit16
if.then15: ; preds = %for.exit13
call void @putchar(i32 10)
br label %if.exit16
if.exit16: ; preds = %if.then15, %for.exit13
ret void
}
; Function Attrs: nounwind
define void @main(i32 %0, i8** %1) #0 {
entry:
%argc = alloca i32, align 4
%argv = alloca i8**, align 8
%n = alloca i32, align 4
store i32 %0, i32* %argc, align 4
store i8** %1, i8*** %argv, align 8
store i32 1000, i32* %n, align 4
%2 = load i32, i32* %argc, align 4
%gt = icmp sgt i32 %2, 1
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
%3 = load i8**, i8*** %argv, align 8
%ptroffset = getelementptr inbounds i8*, i8** %3, i64 1
%4 = load i8*, i8** %ptroffset, align 8
%5 = call i32 @atoi(i8* %4)
store i32 %5, i32* %n, align 4
br label %if.exit
if.exit: ; preds = %if.then, %entry
%6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.14, i32 0, i32 0))
%lo = load i8*, i8** getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"char[]"* @fasta.alu to { i8*, i64 }*), i32 0, i32 0), align 8
%hi = load i64, i64* getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"char[]"* @fasta.alu to { i8*, i64 }*), i32 0, i32 1), align 8
%7 = load i32, i32* %n, align 4
%mul = mul i32 %7, 2
call void @fasta.repeat_fasta(i8* %lo, i64 %hi, i32 %mul)
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.15, i32 0, i32 0))
%lo1 = load i8*, i8** getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"char[]"* @fasta.iub to { i8*, i64 }*), i32 0, i32 0), align 8
%hi2 = load i64, i64* getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"char[]"* @fasta.iub to { i8*, i64 }*), i32 0, i32 1), align 8
%lo3 = load i8*, i8** getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"double[]"* @fasta.iub_p to { i8*, i64 }*), i32 0, i32 0), align 8
%hi4 = load i64, i64* getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"double[]"* @fasta.iub_p to { i8*, i64 }*), i32 0, i32 1), align 8
%9 = load i32, i32* %n, align 4
%mul5 = mul i32 %9, 3
call void @fasta.random_fasta(i8* %lo1, i64 %hi2, i8* %lo3, i64 %hi4, i32 %mul5)
%10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.16, i32 0, i32 0))
%lo6 = load i8*, i8** getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"char[]"* @fasta.homosapiens to { i8*, i64 }*), i32 0, i32 0), align 8
%hi7 = load i64, i64* getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"char[]"* @fasta.homosapiens to { i8*, i64 }*), i32 0, i32 1), align 8
%lo8 = load i8*, i8** getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"double[]"* @fasta.homosapiens_p to { i8*, i64 }*), i32 0, i32 0), align 8
%hi9 = load i64, i64* getelementptr inbounds ({ i8*, i64 }, { i8*, i64 }* bitcast (%"double[]"* @fasta.homosapiens_p to { i8*, i64 }*), i32 0, i32 1), align 8
%11 = load i32, i32* %n, align 4
%mul10 = mul i32 %11, 5
call void @fasta.random_fasta(i8* %lo6, i64 %hi7, i8* %lo8, i64 %hi9, i32 %mul10)
ret void
}