aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/env.cff1
-rw-r--r--src/llvm.cff74
-rw-r--r--src/parse.cff1
-rw-r--r--x.ll309
4 files changed, 373 insertions, 12 deletions
diff --git a/src/env.cff b/src/env.cff
index 04dc81d..d45e373 100644
--- a/src/env.cff
+++ b/src/env.cff
@@ -32,6 +32,7 @@ extern fn envput_alloc(env *Env, alloc *Allocator, decl Decl, old **const Decl)
switch {
case old.u.#tag == :Fn and decl.u.#tag == :Fn
and decl.u.Fn.ty == old.u.Fn.ty and (old.u.Fn.body->empty() or decl.u.Fn.body->empty());
+ decl.u.Fn.id = old.u.Fn.id;
case old.u.#tag == :Ty and decl.u.#tag == :Ty and old.u.Ty == decl.u.Ty;
diff --git a/src/llvm.cff b/src/llvm.cff
index ba4b556..3dcebe6 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -19,6 +19,7 @@ struct Value {
LocalRef *Var,
GlobalRef *Var,
Fn *Fn,
+ FnRef *Fn,
}
}
@@ -90,7 +91,8 @@ fn gen(fmt *const u8, ...) void {
case Ptr p; gen("ptr");
case Slice p; gen("{ %t, %t }", mkptrtype(p), ty_usize);
case Arr arr;
- gen("[%z x %t]", arr.length, arr.child);
+ assert(arr.length >= 0, "arr length");
+ gen("[%z x %t]", arr.length, arr.child);
case Agg;
genagg(ty);
case Enum enu; pritype(enu.intty);
@@ -138,13 +140,17 @@ fn gen(fmt *const u8, ...) void {
case 'I';
fprintf(outfp, "%lld", as(c_llong)ap->arg(i64));
case 'f';
- fprintf(outfp, "%.17f", ap->arg(f64));
+ let f f64 = as(f32)ap->arg(f64);
+ fprintf(outfp, "%#.16llx", *as(*u64)&f);
+ case 'F';
+ fprintf(outfp, "%e", ap->arg(f64));
case 'z';
fprintf(outfp, "%zu", ap->arg(usize));
case 'v';
- switch ap->arg(Value).u {
+ let val = ap->arg(Value);
+ switch val.u {
case IImm i; gen("%I", i);
- case FImm f; gen("%f", f);
+ case FImm f; gen(val.ty.size == 4 ? "%f" : "%F", f);
case BImm b; gen("%d", as(int)b);
case Null; gen("null");
case ZeroIni; gen("zeroinitializer");
@@ -164,6 +170,13 @@ fn gen(fmt *const u8, ...) void {
} else {
gen("@%s", decl.name);
}
+ case FnRef f;
+ let decl = container_of(f, Decl, u.Fn);
+ if !decl.externp {
+ gen("@%s.%d", decl.name, f.id);
+ } else {
+ gen("@%s", decl.name);
+ }
case StrConstRef id;
gen("@.str.%d", id);
@@ -206,6 +219,7 @@ fn genaddr(f *Fn, ex *Expr) Value {
switch decl.u {
case Let *var; return {mkptrtype(var.ty), :LocalRef(var)};
case Static *var; return {mkptrtype(var.ty), :GlobalRef(var)};
+ case Fn *f; return {mkptrtype(f.ty), :FnRef(f)};
}
case UnOp un;
switch un.op {
@@ -217,12 +231,19 @@ fn genaddr(f *Fn, ex *Expr) Value {
}
case Index idx;
let lhs Value #?;
- if idx.lhs.ty->is(:Arr) {
+ switch idx.lhs.ty.u {
+ case Arr arrty;
let arr = genaddr(f, idx.lhs);
lhs = mktmp(mkptrtype(ex.ty));
- gen("\t%v = getelementptr %t, %t %v, i32 0, i32 0\n", lhs, arr.ty.u.Arr.child, arr.ty, arr);
- } else {
+ gen("\t%v = getelementptr %t, %t %v, i32 0, i32 0\n", lhs, idx.lhs.ty, arr.ty, arr);
+ case Ptr;
lhs = genexpr(f, idx.lhs);
+ case Slice child;
+ let tmp = genexpr(f, idx.lhs);
+ lhs = mktmp(mkptrtype(child));
+ gen("\t%v = extractvalue %t %v, 0\n", lhs, tmp.ty, tmp);
+ case else;
+ assert(#f, "index");
}
let rhs = genexpr(f, idx.rhs),
addr = mktmp(mkptrtype(ex.ty));
@@ -271,7 +292,20 @@ fn genaddr(f *Fn, ex *Expr) Value {
case :Union;
gen("\t%v = bitcast %t %v to %t\n", ptr, tmp.ty, tmp, ptr.ty);
}
- gen("\tstore %t %v, %t %v\n", fex.ty, convert(f, fld.ty, fex), ptr.ty, ptr);
+ gen("\tstore %t %v, %t %v\n", fld.ty, convert(f, fld.ty, fex), ptr.ty, ptr);
+ }
+ return tmp;
+
+ case ArrIni ini;
+ let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child);
+ let tmp = mktmp(mkptrtype(ty));
+ gen("\t%v = alloca %t\n", tmp, ty);
+ gen("\tstore %t zeroinitializer, %t %v\n", ty, tmp.ty, tmp);
+ foreach(idx, i, ini.idxs) {
+ let fex = &ini.exs[i];
+ let ptr = mktmp(mkptrtype(fex.ty));
+ gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", ptr, ty, tmp.ty, tmp, idx);
+ gen("\tstore %t %v, %t %v\n", fex.ty, convert(f, ty.u.Arr.child, fex), ptr.ty, ptr);
}
return tmp;
}
@@ -695,7 +729,16 @@ fn genexpr(f *Fn, ex *Expr) Value {
case Slice sl;
if sl.lhs.ty.u.#tag == :Arr {
- assert(#f,"");
+ let addr = genaddr(f, sl.lhs);
+ let begin = convert(f, ty_usize, sl.begin);
+ let end = convert(f, ty_usize, sl.end);
+ let len = mktmp(ty_usize);
+ gen("\t%v = sub %t %v, %v\n", len, ty_usize, end, begin);
+ let tmp = mktmp(ex.ty);
+ gen("\t%v = insertvalue %t undef, %t %v, 0\n", tmp, ex.ty, addr.ty, addr);
+ let res = mktmp(ex.ty);
+ gen("\t%v = insertvalue %t %v, %t %v, 1\n", res, ex.ty, tmp, len.ty, len);
+ return res;
} else if sl.lhs.ty.u.#tag == :Ptr {
let addr = genexpr(f, sl.lhs);
let begin = convert(f, ty_usize, sl.begin);
@@ -755,6 +798,13 @@ fn genexpr(f *Fn, ex *Expr) Value {
gen("\t%v = load %t, %t %v\n", val, ex.ty, tmp.ty, tmp);
return val;
+ case ArrIni ini;
+ let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child);
+ let tmp = genaddr(f, ex);
+ let val = mktmp(ty);
+ gen("\t%v = load %t, %t %v\n", val, ty, tmp.ty, tmp);
+ return val;
+
case EUnionIni ini;
let t0 = mktmp(mkptrtype(ex.ty));
let vidx = ini.var - ex.ty.u.Agg.flds.#ptr;
@@ -907,8 +957,8 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen("\tswitch %t %v, label %%ISx%d [", test.ty, test);
foreach (c, i, sw.cs) {
foreach_ptr (ex, _, c.es) {
- let t = convert(f, test.ty, ex);
- gen(" %t %v, label %%IS%d.%d ", t.ty, t, id, i);
+ assert(ex.u.#tag == :IntLit or ex.u.#tag == :EnumIni, "case");
+ gen(" %t %I, label %%IS%d.%d ", test.ty, ex.u.IntLit.i, id, i);
}
}
gen(" ]\n");
@@ -1043,7 +1093,7 @@ struct GloblKeyTraits {
static globls Map<GloblKey, GloblEntry, GloblKeyTraits> = {};
extern fn llvm_addglobl(decl *Decl, staticp bool) void {
- assert(decl.toplevel, "llvm-addfn");
+ assert(decl.toplevel or decl.externp, "llvm-addfn %d", decl.u.#tag);
let slot = globls->get_slot({decl.name, decl.externp});
if slot.t != :Def {
slot.t = :Decl;
diff --git a/src/parse.cff b/src/parse.cff
index 0eb251d..3512c96 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -2584,6 +2584,7 @@ fn parsefn(P *Parser, loc Loc, toplevel bool, externp bool, name *const u8) *Dec
Fn.id = ++id;
// TODO tlalloc necessary for templates. but it leaks some memory
let decl = putdecl_alloc(P, P.tlalloc, loc, decl);
+ let Fn = &decl.u.Fn;
decl.toplevel = toplevel;
if !lexmatch(P, #null, '{') {
diff --git a/x.ll b/x.ll
new file mode 100644
index 0000000..84182a2
--- /dev/null
+++ b/x.ll
@@ -0,0 +1,309 @@
+target triple = "x86_64-pc-linux-gnu"
+%.type.opaque = type opaque
+
+@xs.2 = internal global ptr zeroinitializer
+define internal i32 @icmp.4(ptr %lhs, ptr %rhs, ptr %_) {
+%lhs.0 = alloca ptr store ptr %lhs, ptr %lhs.0
+%rhs.1 = alloca ptr store ptr %rhs, ptr %rhs.1
+%_.2 = alloca ptr store ptr %_, ptr %_.2
+ %lhs.3 = alloca i32
+ %t1 = load ptr, ptr %lhs.0
+ %t0 = bitcast ptr %t1 to ptr
+ %t2 = load i32, ptr %t0
+ store i32 %t2, ptr %lhs.3
+ %rhs.4 = alloca i32
+ %t4 = load ptr, ptr %rhs.1
+ %t3 = bitcast ptr %t4 to ptr
+ %t5 = load i32, ptr %t3
+ store i32 %t5, ptr %rhs.4
+ %t6 = load i32, ptr %lhs.3
+ %t7 = load i32, ptr %rhs.4
+ %t8 = sub i32 %t6, %t7
+ ret i32 %t8
+ ret i32 undef
+}
+define internal void @foo.5() {
+ ret void
+}
+define internal void @isort.3(ptr %xs, i64 %n) {
+%xs.0 = alloca ptr store ptr %xs, ptr %xs.0
+%n.1 = alloca i64 store i64 %n, ptr %n.1
+ %t1 = load ptr, ptr %xs.0
+ %t0 = bitcast ptr %t1 to ptr
+ %t2 = load i64, ptr %n.1
+ %t3 = sext i32 4 to i64
+ call void(ptr, i64, i64, ptr) @qsort(ptr %t0, i64 %t2, i64 %t3, ptr @icmp.4)
+ %x.2 = alloca ptr
+ store ptr @foo.5, ptr %x.2
+ %t4 = load ptr, ptr %x.2
+ call ptr %t4()
+ ret void
+}
+define internal i64 @length.7(ptr %l) {
+%l.0 = alloca ptr store ptr %l, ptr %l.0
+ %n.1 = alloca i64
+ store i64 0, ptr %n.1
+ %t0 = load ptr, ptr %l.0
+ %t1 = load { ptr, i32 }, ptr %t0
+ call void({ ptr, i32 }) @ok.6({ ptr, i32 } %t1)
+ br label %Cont1
+Cont1: %t2 = bitcast i8 0 to i8 ; NOP
+ %t3 = load ptr, ptr %l.0
+ %t4 = icmp ne ptr %t3, null
+ br i1 %t4, label %Next1, label %Brk1
+Next1: %t5 = bitcast i8 0 to i8 ; NOP
+ %t6 = load i64, ptr %n.1
+ %t7 = add i64 %t6, 1
+ store i64 %t7, ptr %n.1
+ %t9 = load ptr, ptr %l.0
+ %t10 = getelementptr { ptr, i32 }, ptr %t9, i32 0, i32 0
+ %t8 = load ptr, ptr %t10
+ store ptr %t8, ptr %l.0
+ br label %Cont1
+Brk1: %t11 = bitcast i8 0 to i8 ; NOP
+ %t12 = load i64, ptr %n.1
+ ret i64 %t12
+ ret i64 undef
+}
+define internal void @ok.8({ ptr, i32 } %l) {
+%l.0 = alloca { ptr, i32 } store { ptr, i32 } %l, ptr %l.0
+ ret void
+}
+define internal float @mag.9({ float, float } %v) {
+%v.0 = alloca { float, float } store { float, float } %v, ptr %v.0
+ %t1 = getelementptr { float, float }, ptr %v.0, i32 0, i32 0
+ %t0 = load float, ptr %t1
+ %t3 = getelementptr { float, float }, ptr %v.0, i32 0, i32 0
+ %t2 = load float, ptr %t3
+ %t4 = fmul float %t0, %t2
+ %t6 = getelementptr { float, float }, ptr %v.0, i32 0, i32 1
+ %t5 = load float, ptr %t6
+ %t8 = getelementptr { float, float }, ptr %v.0, i32 0, i32 1
+ %t7 = load float, ptr %t8
+ %t9 = fmul float %t5, %t7
+ %t10 = fadd float %t4, %t9
+ %t11 = call float(float) @sqrtf(float %t10)
+ ret float %t11
+ ret float undef
+}
+define internal void @zero.11(ptr %v) {
+%v.0 = alloca ptr store ptr %v, ptr %v.0
+ %t0 = load ptr, ptr %v.0
+ %t1 = getelementptr { float, float }, ptr %t0, i32 0, i32 0
+ %t2 = sitofp i32 0 to float
+ store float %t2, ptr %t1
+ %t3 = load ptr, ptr %v.0
+ %t4 = getelementptr { float, float }, ptr %t3, i32 0, i32 1
+ %t5 = sitofp i32 0 to float
+ store float %t5, ptr %t4
+ ret void
+}
+define internal { ptr, i64 } @spanz.12(ptr %cstr) {
+%cstr.0 = alloca ptr store ptr %cstr, ptr %cstr.0
+ %t0 = load ptr, ptr %cstr.0
+ %t1 = sext i32 0 to i64
+ %t2 = load ptr, ptr %cstr.0
+ %t3 = call i64(ptr) @strlen(ptr %t2)
+ %t4 = sub i64 %t3, %t1
+ %t5 = insertvalue { ptr, i64 } undef, ptr %t0, 0
+ %t6 = insertvalue { ptr, i64 } %t5, i64 %t4, 1
+ ret { ptr, i64 } %t6
+ ret { ptr, i64 } undef
+}
+define i32 @main(i32 %argc, ptr %argv) {
+%argc.0 = alloca i32 store i32 %argc, ptr %argc.0
+%argv.1 = alloca ptr store ptr %argv, ptr %argv.1
+ %colors.2 = alloca [3 x i16]
+ %t0 = alloca [3 x i16]
+ store [3 x i16] zeroinitializer, ptr %t0
+ %t1 = getelementptr [3 x i16], ptr %t0, i32 0, i32 0
+ store i16 0, ptr %t1
+ %t2 = getelementptr [3 x i16], ptr %t0, i32 0, i32 1
+ store i16 1, ptr %t2
+ %t3 = getelementptr [3 x i16], ptr %t0, i32 0, i32 2
+ store i16 2, ptr %t3
+ %t4 = load [3 x i16], ptr %t0
+ store [3 x i16] %t4, ptr %colors.2
+ %x.3 = alloca { float, float }
+ %t5 = alloca { float, float }
+ store { float, float } zeroinitializer, ptr %t5
+ %t6 = getelementptr { float, float }, ptr %t5, i32 0, i32 1
+ %t7 = sitofp i32 1 to float
+ store float %t7, ptr %t6
+ %t8 = getelementptr { float, float }, ptr %t5, i32 0, i32 0
+ %t9 = fptrunc double 2.39999999999999991118216 to float
+ store float %t9, ptr %t8
+ %t10 = load { float, float }, ptr %t5
+ store { float, float } %t10, ptr %x.3
+ %p.4 = alloca ptr
+ %t11 = bitcast ptr %x.3 to ptr
+ store ptr %t11, ptr %p.4
+ %t12 = getelementptr [16 x i8], ptr @.str.0, i64 0, i64 0
+ %t14 = getelementptr { float, float }, ptr %x.3, i32 0, i32 0
+ %t13 = load float, ptr %t14
+ %t16 = load ptr, ptr %p.4
+ %t17 = getelementptr { float, float }, ptr %t16, i32 0, i32 1
+ %t15 = load float, ptr %t17
+ %t18 = call i32(ptr, ...) @printf(ptr %t12, float %t13, float %t15)
+ %t19 = getelementptr [10 x i8], ptr @.str.1, i64 0, i64 0
+ %t20 = load { float, float }, ptr %x.3
+ %t21 = call float({ float, float }) @mag.9({ float, float } %t20)
+ %t22 = call i32(ptr, ...) @printf(ptr %t19, float %t21)
+ call void(ptr) @zero.11(ptr %x.3)
+ %t23 = getelementptr [10 x i8], ptr @.str.2, i64 0, i64 0
+ %t24 = load { float, float }, ptr %x.3
+ %t25 = call float({ float, float }) @mag.9({ float, float } %t24)
+ %t26 = call i32(ptr, ...) @printf(ptr %t23, float %t25)
+ %x.5 = alloca { i8, i64 }
+ %t27 = alloca { i8, i64 }
+ store { i8, i64 } zeroinitializer, ptr %t27
+ store i8 0, ptr %t27
+ %t28 = load { i8, i64 }, ptr %t27
+ store { i8, i64 } %t28, ptr %x.5
+ %x.6 = alloca { i8, i64 }
+ %t29 = alloca { i8, i64 }
+ store { i8, i64 } zeroinitializer, ptr %t29
+ store i8 1, ptr %t29
+ %t30 = bitcast ptr %t29 to ptr
+ %t31 = getelementptr i64, ptr %t30, i32 1
+ store i64 zeroinitializer, ptr %t31
+ %t32 = load { i8, i64 }, ptr %t29
+ store { i8, i64 } %t32, ptr %x.6
+ %is.7 = alloca [6 x i32]
+ %t33 = alloca [6 x i32]
+ store [6 x i32] zeroinitializer, ptr %t33
+ %t34 = getelementptr [6 x i32], ptr %t33, i32 0, i32 4
+ store i32 1, ptr %t34
+ %t35 = getelementptr [6 x i32], ptr %t33, i32 0, i32 5
+ store i32 2, ptr %t35
+ %t36 = getelementptr [6 x i32], ptr %t33, i32 0, i32 0
+ store i32 3, ptr %t36
+ %t37 = load [6 x i32], ptr %t33
+ store [6 x i32] %t37, ptr %is.7
+ %t38 = getelementptr [6 x i32], ptr %is.7, i64 0, i64 0
+ call void(ptr, i64) @isort.3(ptr %t38, i64 6)
+ %i.8 = alloca i64
+ store i64 0, ptr %i.8
+ br label %Cont1
+Cont1: %t39 = bitcast i8 0 to i8 ; NOP
+ %t40 = load i64, ptr %i.8
+ %t41 = icmp ult i64 %t40, 6
+ %t42 = zext i1 %t41 to i8
+ %t43 = icmp ne i8 %t42, 0
+ br i1 %t43, label %Next1, label %Brk1
+Next1: %t44 = bitcast i8 0 to i8 ; NOP
+ %x.9 = alloca i32
+ %t46 = getelementptr [6 x i32], ptr %is.7, i32 0, i32 0
+ %t47 = load i64, ptr %i.8
+ %t48 = getelementptr i32, ptr %t46, i64 %t47
+ %t45 = load i32, ptr %t48
+ store i32 %t45, ptr %x.9
+ %t49 = getelementptr [4 x i8], ptr @.str.3, i64 0, i64 0
+ %t50 = load i32, ptr %x.9
+ %t51 = call i32(ptr, ...) @printf(ptr %t49, i32 %t50)
+ %t52 = load i64, ptr %i.8
+ %t53 = add i64 %t52, 1
+ store i64 %t53, ptr %i.8
+ br label %Cont1
+Brk1: %t54 = bitcast i8 0 to i8 ; NOP
+ %i.10 = alloca i64
+ store i64 0, ptr %i.10
+ br label %Cont2
+Cont2: %t55 = bitcast i8 0 to i8 ; NOP
+ %t56 = load i64, ptr %i.10
+ %t57 = icmp ult i64 %t56, 6
+ %t58 = zext i1 %t57 to i8
+ %t59 = icmp ne i8 %t58, 0
+ br i1 %t59, label %Next2, label %Brk2
+Next2: %t60 = bitcast i8 0 to i8 ; NOP
+ %x.11 = alloca i32
+ %t62 = getelementptr [6 x i32], ptr %is.7, i32 0, i32 0
+ %t63 = load i64, ptr %i.10
+ %t64 = getelementptr i32, ptr %t62, i64 %t63
+ %t61 = load i32, ptr %t64
+ store i32 %t61, ptr %x.11
+ %t65 = getelementptr [4 x i8], ptr @.str.4, i64 0, i64 0
+ %t66 = load i32, ptr %x.11
+ %t67 = call i32(ptr, ...) @printf(ptr %t65, i32 %t66)
+ %t68 = load i64, ptr %i.10
+ %t69 = add i64 %t68, 1
+ store i64 %t69, ptr %i.10
+ br label %Cont2
+Brk2: %t70 = bitcast i8 0 to i8 ; NOP
+ %slice.12 = alloca { ptr, i64 }
+ %t71 = sext i32 3 to i64
+ %t72 = sext i32 5 to i64
+ %t73 = sub i64 %t72, %t71
+ %t74 = insertvalue { ptr, i64 } undef, ptr %is.7, 0
+ %t75 = insertvalue { ptr, i64 } %t74, i64 %t73, 1
+ store { ptr, i64 } %t75, ptr %slice.12
+ %t76 = getelementptr [7 x i8], ptr @.str.5, i64 0, i64 0
+ %t78 = load { ptr, i64 }, ptr %slice.12
+ %t79 = extractvalue { ptr, i64 } %t78, 0
+ %t80 = getelementptr i32, ptr %t79, i32 0
+ %t77 = load i32, ptr %t80
+ %t81 = call i32(ptr, ...) @printf(ptr %t76, i32 %t77)
+ %t82 = load { ptr, i64 }, ptr %slice.12
+ %t83 = sext i32 1 to i64
+ %t84 = sext i32 4 to i64
+ %t85 = extractvalue { ptr, i64 } %t82, 0 %t86 = sub i64 %t84, %t83
+ %t87 = insertvalue { ptr, i64 } undef, ptr %t85, 0
+ %t88 = insertvalue { ptr, i64 } %t87, i64 %t86, 1
+ store { ptr, i64 } %t88, ptr %slice.12
+ %t89 = getelementptr [7 x i8], ptr @.str.6, i64 0, i64 0
+ %t91 = load { ptr, i64 }, ptr %slice.12
+ %t92 = extractvalue { ptr, i64 } %t91, 0
+ %t93 = getelementptr i32, ptr %t92, i32 0
+ %t90 = load i32, ptr %t93
+ %t94 = call i32(ptr, ...) @printf(ptr %t89, i32 %t90)
+ %t95 = load { ptr, i64 }, ptr %slice.12
+ %t96 = extractvalue { ptr, i64 } %t95, 1
+ %v.13 = alloca { float, float }
+ store { float, float } zeroinitializer, ptr %v.13
+ %t97 = getelementptr [18 x i8], ptr @.str.7, i64 0, i64 0
+ %t98 = call i32(ptr, ...) @printf(ptr %t97, i64 24)
+ %t99 = getelementptr [20 x i8], ptr @.str.8, i64 0, i64 0
+ %t100 = call i32(ptr, ...) @printf(ptr %t99, i64 8)
+ %t101 = getelementptr [18 x i8], ptr @.str.9, i64 0, i64 0
+ %t102 = call i32(ptr, ...) @printf(ptr %t101, i64 8)
+ %t103 = getelementptr [14 x i8], ptr @.str.10, i64 0, i64 0
+ %t105 = alloca { float }
+ store { float } zeroinitializer, ptr %t105
+ %t106 = bitcast ptr %t105 to ptr
+ store float 1.19999999999999995559108, ptr %t106
+ %t107 = bitcast ptr %t105 to ptr %t104 = load i32, ptr %t107
+ %t108 = call i32(ptr, ...) @printf(ptr %t103, i32 %t104)
+ switch i64 6, label %ISx0 [ i64 0, label %IS0.0 i64 1, label %IS0.0 i64 3, label %IS0.1 ]
+IS0.0: %t109 = icmp ult i64 6, 2
+ %t110 = zext i1 %t109 to i8
+ br label %ISe0
+IS0.1: br label %ISe0
+ISx0: br label %ISe0
+ISe0: %t111 = bitcast i8 0 to i8 ; NOP
+ %t113 = getelementptr [3 x i16], ptr %colors.2, i32 0, i32 0
+ %t114 = getelementptr i16, ptr %t113, i32 0
+ %t112 = load i16, ptr %t114
+ switch i16 %t112, label %ISx0 [ i16 0, label %IS1.0 ]
+IS1.0: br label %ISe1
+ISx1: br label %ISe1
+ISe1: %t115 = bitcast i8 0 to i8 ; NOP
+ ret i32 0
+ ret i32 undef
+}
+@.str.0 = internal constant [16 x i8] c"v = { %g, %g }\0A\00";
+@.str.1 = internal constant [10 x i8] c"mag = %g\0A\00";
+@.str.2 = internal constant [10 x i8] c"mag = %g\0A\00";
+@.str.3 = internal constant [4 x i8] c"%d\0A\00";
+@.str.4 = internal constant [4 x i8] c"%d\0A\00";
+@.str.5 = internal constant [7 x i8] c"sl %d\0A\00";
+@.str.6 = internal constant [7 x i8] c"sl %d\0A\00";
+@.str.7 = internal constant [18 x i8] c"sizeof(is) = %zu\0A\00";
+@.str.8 = internal constant [20 x i8] c"sizeof *void = %zu\0A\00";
+@.str.9 = internal constant [18 x i8] c"alignof f64= %zu\0A\00";
+@.str.10 = internal constant [14 x i8] c"1.2 -> %#.8x\0A\00";
+declare float @sqrtf(float);
+@stderr = external global ptr
+declare i32 @printf(ptr, ...);
+declare i64 @strlen(ptr);
+@stdin = external global ptr
+declare void @qsort(ptr, i64, i64, ptr);