// #target: macos-x64 module foo; import std::io; faultdef ABC; fn void blurb() { io::printn("Blurb");} macro int? tester() { defer blurb(); return ABC~; } fn void? test(int x) { io::printfn("test(%d)", x); if (x || (tester()!)) io::printn("Ok1"); io::printn("Test next"); if (tester()! || x) io::printn("Ok?"); io::printn("Test ok"); } fn void? test2(int x) { io::printfn("test2(%d)", x); if (x && (tester()!)) io::printn("Ok1"); io::printn("Test next"); if ((tester()!) && x) io::printn("Ok?"); io::printn("Test ok"); } fn void main() { fault a = @catch(test(0)); fault b = @catch(test(1)); fault c = @catch(test2(0)); fault d = @catch(test2(1)); } /* #expect: foo.ll define i64 @foo.test(i32 %0) #0 { entry: %varargslots = alloca [1 x %any], align 16 %taddr = alloca i32, align 4 %retparam = alloca i64, align 8 %error_var = alloca i64, align 8 %blockret = alloca i32, align 4 %len = alloca i64, align 8 %error_var2 = alloca i64, align 8 %retparam4 = alloca i64, align 8 %error_var6 = alloca i64, align 8 %error_var12 = alloca i64, align 8 %len19 = alloca i64, align 8 %error_var20 = alloca i64, align 8 %retparam22 = alloca i64, align 8 %error_var28 = alloca i64, align 8 %error_var34 = alloca i64, align 8 %error_var42 = alloca i64, align 8 %blockret43 = alloca i32, align 4 store i32 %0, ptr %taddr, align 4 %1 = insertvalue %any undef, ptr %taddr, 0 %2 = insertvalue %any %1, i64 ptrtoint (ptr @"$ct.int" to i64), 1 store %any %2, ptr %varargslots, align 16 %3 = call i64 @std.io.printfn(ptr %retparam, ptr @.str.1, i64 8, ptr %varargslots, i64 1) %i2b = icmp ne i32 %0, 0 br i1 %i2b, label %or.phi, label %or.rhs or.rhs: ; preds = %entry store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var, align 8 br label %opt_block_cleanup opt_block_cleanup: ; preds = %or.rhs call void @foo.blurb() br label %guard_block guard_block: ; preds = %opt_block_cleanup %4 = load i64, ptr %error_var, align 8 ret i64 %4 or.phi: ; preds = %entry br label %if.then if.then: ; preds = %or.phi %5 = call ptr @std.io.stdout() %6 = call i64 @std.io.File.write(ptr %retparam4, ptr %5, ptr @.str.2, i64 3) %not_err = icmp eq i64 %6, 0 %7 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %7, label %after_check, label %assign_optional assign_optional: ; preds = %if.then store i64 %6, ptr %error_var2, align 8 br label %guard_block5 after_check: ; preds = %if.then br label %noerr_block guard_block5: ; preds = %assign_optional br label %voiderr noerr_block: ; preds = %after_check %8 = load i64, ptr %retparam4, align 8 store i64 %8, ptr %len, align 8 %9 = call i64 @std.io.File.write_byte(ptr %5, i8 zeroext 10) %not_err7 = icmp eq i64 %9, 0 %10 = call i1 @llvm.expect.i1(i1 %not_err7, i1 true) br i1 %10, label %after_check9, label %assign_optional8 assign_optional8: ; preds = %noerr_block store i64 %9, ptr %error_var6, align 8 br label %guard_block10 after_check9: ; preds = %noerr_block br label %noerr_block11 guard_block10: ; preds = %assign_optional8 br label %voiderr noerr_block11: ; preds = %after_check9 %11 = call i64 @std.io.File.flush(ptr %5) %not_err13 = icmp eq i64 %11, 0 %12 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true) br i1 %12, label %after_check15, label %assign_optional14 assign_optional14: ; preds = %noerr_block11 store i64 %11, ptr %error_var12, align 8 br label %guard_block16 after_check15: ; preds = %noerr_block11 br label %noerr_block17 guard_block16: ; preds = %assign_optional14 br label %voiderr noerr_block17: ; preds = %after_check15 %13 = load i64, ptr %len, align 8 %add = add i64 %13, 1 br label %voiderr voiderr: ; preds = %noerr_block17, %guard_block16, %guard_block10, %guard_block5 br label %if.exit if.exit: ; preds = %voiderr %14 = call ptr @std.io.stdout() %15 = call i64 @std.io.File.write(ptr %retparam22, ptr %14, ptr @.str.3, i64 9) %not_err23 = icmp eq i64 %15, 0 %16 = call i1 @llvm.expect.i1(i1 %not_err23, i1 true) br i1 %16, label %after_check25, label %assign_optional24 assign_optional24: ; preds = %if.exit store i64 %15, ptr %error_var20, align 8 br label %guard_block26 after_check25: ; preds = %if.exit br label %noerr_block27 guard_block26: ; preds = %assign_optional24 br label %voiderr41 noerr_block27: ; preds = %after_check25 %17 = load i64, ptr %retparam22, align 8 store i64 %17, ptr %len19, align 8 %18 = call i64 @std.io.File.write_byte(ptr %14, i8 zeroext 10) %not_err29 = icmp eq i64 %18, 0 %19 = call i1 @llvm.expect.i1(i1 %not_err29, i1 true) br i1 %19, label %after_check31, label %assign_optional30 assign_optional30: ; preds = %noerr_block27 store i64 %18, ptr %error_var28, align 8 br label %guard_block32 after_check31: ; preds = %noerr_block27 br label %noerr_block33 guard_block32: ; preds = %assign_optional30 br label %voiderr41 noerr_block33: ; preds = %after_check31 %20 = call i64 @std.io.File.flush(ptr %14) %not_err35 = icmp eq i64 %20, 0 %21 = call i1 @llvm.expect.i1(i1 %not_err35, i1 true) br i1 %21, label %after_check37, label %assign_optional36 assign_optional36: ; preds = %noerr_block33 store i64 %20, ptr %error_var34, align 8 br label %guard_block38 after_check37: ; preds = %noerr_block33 br label %noerr_block39 guard_block38: ; preds = %assign_optional36 br label %voiderr41 noerr_block39: ; preds = %after_check37 %22 = load i64, ptr %len19, align 8 %add40 = add i64 %22, 1 br label %voiderr41 voiderr41: ; preds = %noerr_block39, %guard_block38, %guard_block32, %guard_block26 store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var42, align 8 br label %opt_block_cleanup44 opt_block_cleanup44: ; preds = %voiderr41 call void @foo.blurb() br label %guard_block45 guard_block45: ; preds = %opt_block_cleanup44 %23 = load i64, ptr %error_var42, align 8 ret i64 %23 } ; Function Attrs: define i64 @foo.test2(i32 %0) #0 { entry: %varargslots = alloca [1 x %any], align 16 %taddr = alloca i32, align 4 %retparam = alloca i64, align 8 %error_var = alloca i64, align 8 %blockret = alloca i32, align 4 %len = alloca i64, align 8 %error_var2 = alloca i64, align 8 %retparam4 = alloca i64, align 8 %error_var6 = alloca i64, align 8 %error_var12 = alloca i64, align 8 %error_var18 = alloca i64, align 8 %blockret19 = alloca i32, align 4 store i32 %0, ptr %taddr, align 4 %1 = insertvalue %any undef, ptr %taddr, 0 %2 = insertvalue %any %1, i64 ptrtoint (ptr @"$ct.int" to i64), 1 store %any %2, ptr %varargslots, align 16 %3 = call i64 @std.io.printfn(ptr %retparam, ptr @.str.4, i64 9, ptr %varargslots, i64 1) %i2b = icmp ne i32 %0, 0 br i1 %i2b, label %and.rhs, label %and.phi and.rhs: ; preds = %entry store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var, align 8 br label %opt_block_cleanup opt_block_cleanup: ; preds = %and.rhs call void @foo.blurb() br label %guard_block guard_block: ; preds = %opt_block_cleanup %4 = load i64, ptr %error_var, align 8 ret i64 %4 and.phi: ; preds = %entry br label %if.exit if.exit: ; preds = %and.phi %5 = call ptr @std.io.stdout() %6 = call i64 @std.io.File.write(ptr %retparam4, ptr %5, ptr @.str.5, i64 9) %not_err = icmp eq i64 %6, 0 %7 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %7, label %after_check, label %assign_optional assign_optional: ; preds = %if.exit store i64 %6, ptr %error_var2, align 8 br label %guard_block5 after_check: ; preds = %if.exit br label %noerr_block guard_block5: ; preds = %assign_optional br label %voiderr noerr_block: ; preds = %after_check %8 = load i64, ptr %retparam4, align 8 store i64 %8, ptr %len, align 8 %9 = call i64 @std.io.File.write_byte(ptr %5, i8 zeroext 10) %not_err7 = icmp eq i64 %9, 0 %10 = call i1 @llvm.expect.i1(i1 %not_err7, i1 true) br i1 %10, label %after_check9, label %assign_optional8 assign_optional8: ; preds = %noerr_block store i64 %9, ptr %error_var6, align 8 br label %guard_block10 after_check9: ; preds = %noerr_block br label %noerr_block11 guard_block10: ; preds = %assign_optional8 br label %voiderr noerr_block11: ; preds = %after_check9 %11 = call i64 @std.io.File.flush(ptr %5) %not_err13 = icmp eq i64 %11, 0 %12 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true) br i1 %12, label %after_check15, label %assign_optional14 assign_optional14: ; preds = %noerr_block11 store i64 %11, ptr %error_var12, align 8 br label %guard_block16 after_check15: ; preds = %noerr_block11 br label %noerr_block17 guard_block16: ; preds = %assign_optional14 br label %voiderr noerr_block17: ; preds = %after_check15 %13 = load i64, ptr %len, align 8 %add = add i64 %13, 1 br label %voiderr voiderr: ; preds = %noerr_block17, %guard_block16, %guard_block10, %guard_block5 store i64 ptrtoint (ptr @foo.ABC to i64), ptr %error_var18, align 8 br label %opt_block_cleanup20 opt_block_cleanup20: ; preds = %voiderr call void @foo.blurb() br label %guard_block21 guard_block21: ; preds = %opt_block_cleanup20 %14 = load i64, ptr %error_var18, align 8 ret i64 %14 } ; Function Attrs: define void @foo.main() #0 { entry: %a = alloca i64, align 8 %blockret = alloca i64, align 8 %f = alloca i64, align 8 %b = alloca i64, align 8 %blockret1 = alloca i64, align 8 %f2 = alloca i64, align 8 %c = alloca i64, align 8 %blockret12 = alloca i64, align 8 %f13 = alloca i64, align 8 %d = alloca i64, align 8 %blockret23 = alloca i64, align 8 %f24 = alloca i64, align 8 br label %testblock testblock: ; preds = %entry %0 = call i64 @foo.test(i32 0) %not_err = icmp eq i64 %0, 0 %1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %1, label %after_check, label %assign_optional assign_optional: ; preds = %testblock store i64 %0, ptr %f, align 8 br label %end_block after_check: ; preds = %testblock store i64 0, ptr %f, align 8 br label %end_block end_block: ; preds = %after_check, %assign_optional %2 = load i64, ptr %f, align 8 %i2b = icmp ne i64 %2, 0 br i1 %i2b, label %if.then, label %if.exit if.then: ; preds = %end_block %3 = load i64, ptr %f, align 8 store i64 %3, ptr %blockret, align 8 br label %expr_block.exit if.exit: ; preds = %end_block store i64 0, ptr %blockret, align 8 br label %expr_block.exit expr_block.exit: ; preds = %if.exit, %if.then %4 = load i64, ptr %blockret, align 8 store i64 %4, ptr %a, align 8 br label %testblock3 testblock3: ; preds = %expr_block.exit %5 = call i64 @foo.test(i32 1) %not_err4 = icmp eq i64 %5, 0 %6 = call i1 @llvm.expect.i1(i1 %not_err4, i1 true) br i1 %6, label %after_check6, label %assign_optional5 assign_optional5: ; preds = %testblock3 store i64 %5, ptr %f2, align 8 br label %end_block7 after_check6: ; preds = %testblock3 store i64 0, ptr %f2, align 8 br label %end_block7 end_block7: ; preds = %after_check6, %assign_optional5 %7 = load i64, ptr %f2, align 8 %i2b8 = icmp ne i64 %7, 0 br i1 %i2b8, label %if.then9, label %if.exit10 if.then9: ; preds = %end_block7 %8 = load i64, ptr %f2, align 8 store i64 %8, ptr %blockret1, align 8 br label %expr_block.exit11 if.exit10: ; preds = %end_block7 store i64 0, ptr %blockret1, align 8 br label %expr_block.exit11 expr_block.exit11: ; preds = %if.exit10, %if.then9 %9 = load i64, ptr %blockret1, align 8 store i64 %9, ptr %b, align 8 br label %testblock14 testblock14: ; preds = %expr_block.exit11 %10 = call i64 @foo.test2(i32 0) %not_err15 = icmp eq i64 %10, 0 %11 = call i1 @llvm.expect.i1(i1 %not_err15, i1 true) br i1 %11, label %after_check17, label %assign_optional16 assign_optional16: ; preds = %testblock14 store i64 %10, ptr %f13, align 8 br label %end_block18 after_check17: ; preds = %testblock14 store i64 0, ptr %f13, align 8 br label %end_block18 end_block18: ; preds = %after_check17, %assign_optional16 %12 = load i64, ptr %f13, align 8 %i2b19 = icmp ne i64 %12, 0 br i1 %i2b19, label %if.then20, label %if.exit21 if.then20: ; preds = %end_block18 %13 = load i64, ptr %f13, align 8 store i64 %13, ptr %blockret12, align 8 br label %expr_block.exit22 if.exit21: ; preds = %end_block18 store i64 0, ptr %blockret12, align 8 br label %expr_block.exit22 expr_block.exit22: ; preds = %if.exit21, %if.then20 %14 = load i64, ptr %blockret12, align 8 store i64 %14, ptr %c, align 8 br label %testblock25 testblock25: ; preds = %expr_block.exit22 %15 = call i64 @foo.test2(i32 1) %not_err26 = icmp eq i64 %15, 0 %16 = call i1 @llvm.expect.i1(i1 %not_err26, i1 true) br i1 %16, label %after_check28, label %assign_optional27 assign_optional27: ; preds = %testblock25 store i64 %15, ptr %f24, align 8 br label %end_block29 after_check28: ; preds = %testblock25 store i64 0, ptr %f24, align 8 br label %end_block29 end_block29: ; preds = %after_check28, %assign_optional27 %17 = load i64, ptr %f24, align 8 %i2b30 = icmp ne i64 %17, 0 br i1 %i2b30, label %if.then31, label %if.exit32 if.then31: ; preds = %end_block29 %18 = load i64, ptr %f24, align 8 store i64 %18, ptr %blockret23, align 8 br label %expr_block.exit33 if.exit32: ; preds = %end_block29 store i64 0, ptr %blockret23, align 8 br label %expr_block.exit33 expr_block.exit33: ; preds = %if.exit32, %if.then31 %19 = load i64, ptr %blockret23, align 8 store i64 %19, ptr %d, align 8 ret void } ; Function Attrs: define i32 @main(i32 %0, ptr %1) #0 { entry: call void @foo.main() ret i32 0 }