// #target: macos-x64 faultdef TEST; macro foo(int x) { if (x) return x; return TEST~; } extern fn void printf(char*, ...); fn int main() { int? a = foo(1); int? b = foo((a + 3) ?? 2); int? c = foo(0); (void)printf("a = %d\n", a); (void)printf("b = %d\n", b); (void)printf("c = %d\n", c); if (@catch(c)) printf("c had error\n"); c = 3; (void)printf("c = %d\n", c); return 0; } /* #expect: failable_catch.ll define i32 @main() #0 { entry: %a = alloca i32, align 4 %a.f = alloca i64, align 8 %blockret = alloca i32, align 4 %b = alloca i32, align 4 %b.f = alloca i64, align 8 %blockret1 = alloca i32, align 4 %c = alloca i32, align 4 %c.f = alloca i64, align 8 %blockret19 = alloca i64, align 8 %f = alloca i64, align 8 br label %if.then if.then: ; preds = %entry store i32 1, ptr %blockret, align 4 br label %expr_block.exit expr_block.exit: ; preds = %if.then %0 = load i32, ptr %blockret, align 4 store i32 %0, ptr %a, align 4 store i64 0, ptr %a.f, align 8 br label %after_assign after_assign: ; preds = %expr_block.exit %optval = load i64, ptr %a.f, align 8 %not_err = icmp eq i64 %optval, 0 %1 = call i1 @llvm.expect.i1(i1 %not_err, i1 true) br i1 %1, label %after_check, label %else_block after_check: ; preds = %after_assign %2 = load i32, ptr %a, align 4 %add = add i32 %2, 3 br label %phi_block else_block: ; preds = %after_assign br label %phi_block phi_block: ; preds = %else_block, %after_check %val = phi i32 [ %add, %after_check ], [ 2, %else_block ] %i2b = icmp ne i32 %val, 0 br i1 %i2b, label %if.then2, label %if.exit if.then2: ; preds = %phi_block store i32 %val, ptr %blockret1, align 4 br label %expr_block.exit3 if.exit: ; preds = %phi_block store i64 ptrtoint (ptr @failable_catch.TEST to i64), ptr %b.f, align 8 br label %after_assign4 expr_block.exit3: ; preds = %if.then2 %3 = load i32, ptr %blockret1, align 4 store i32 %3, ptr %b, align 4 store i64 0, ptr %b.f, align 8 br label %after_assign4 after_assign4: ; preds = %expr_block.exit3, %if.exit br label %if.exit6 if.exit6: ; preds = %after_assign4 store i64 ptrtoint (ptr @failable_catch.TEST to i64), ptr %c.f, align 8 br label %after_assign7 after_assign7: ; preds = %if.exit6 %optval8 = load i64, ptr %a.f, align 8 %not_err9 = icmp eq i64 %optval8, 0 %4 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true) br i1 %4, label %after_check10, label %voiderr after_check10: ; preds = %after_assign7 %5 = load i32, ptr %a, align 4 call void (ptr, ...) @printf(ptr @.str, i32 %5) br label %voiderr voiderr: ; preds = %after_check10, %after_assign7 %optval11 = load i64, ptr %b.f, align 8 %not_err12 = icmp eq i64 %optval11, 0 %6 = call i1 @llvm.expect.i1(i1 %not_err12, i1 true) br i1 %6, label %after_check13, label %voiderr14 after_check13: ; preds = %voiderr %7 = load i32, ptr %b, align 4 call void (ptr, ...) @printf(ptr @.str.1, i32 %7) br label %voiderr14 voiderr14: ; preds = %after_check13, %voiderr %optval15 = load i64, ptr %c.f, align 8 %not_err16 = icmp eq i64 %optval15, 0 %8 = call i1 @llvm.expect.i1(i1 %not_err16, i1 true) br i1 %8, label %after_check17, label %voiderr18 after_check17: ; preds = %voiderr14 %9 = load i32, ptr %c, align 4 call void (ptr, ...) @printf(ptr @.str.2, i32 %9) br label %voiderr18 voiderr18: ; preds = %after_check17, %voiderr14 br label %testblock testblock: ; preds = %voiderr18 %optval20 = load i64, ptr %c.f, align 8 %not_err21 = icmp eq i64 %optval20, 0 %10 = call i1 @llvm.expect.i1(i1 %not_err21, i1 true) br i1 %10, label %after_check22, label %assign_optional assign_optional: ; preds = %testblock store i64 %optval20, ptr %f, align 8 br label %end_block after_check22: ; preds = %testblock store i64 0, ptr %f, align 8 br label %end_block end_block: ; preds = %after_check22, %assign_optional %11 = load i64, ptr %f, align 8 %i2b23 = icmp ne i64 %11, 0 br i1 %i2b23, label %if.then24, label %if.exit25 if.then24: ; preds = %end_block %12 = load i64, ptr %f, align 8 store i64 %12, ptr %blockret19, align 8 br label %expr_block.exit26 if.exit25: ; preds = %end_block store i64 0, ptr %blockret19, align 8 br label %expr_block.exit26 expr_block.exit26: ; preds = %if.exit25, %if.then24 %13 = load i64, ptr %blockret19, align 8 %i2b27 = icmp ne i64 %13, 0 br i1 %i2b27, label %if.then28, label %if.exit29 if.then28: ; preds = %expr_block.exit26 call void (ptr, ...) @printf(ptr @.str.3) br label %if.exit29 if.exit29: ; preds = %if.then28, %expr_block.exit26 store i32 3, ptr %c, align 4 store i64 0, ptr %c.f, align 8 %optval30 = load i64, ptr %c.f, align 8 %not_err31 = icmp eq i64 %optval30, 0 %14 = call i1 @llvm.expect.i1(i1 %not_err31, i1 true) br i1 %14, label %after_check32, label %voiderr33 after_check32: ; preds = %if.exit29 %15 = load i32, ptr %c, align 4 call void (ptr, ...) @printf(ptr @.str.4, i32 %15) br label %voiderr33 voiderr33: ; preds = %after_check32, %if.exit29 ret i32 0 }