// #target: macos-x64

extern fn int? err();
faultdef QBERT;
extern fn int printf(char* fmt, ...);

fn void main()
{
    int? z = 234;
    int? w;
    if (try x = z && try gh = w)
    {
        printf("Success %d && %d!\n", x, gh);
    }
    if (try x = z + w)
    {
       printf("Test\n");
    }
    if (catch e = z)
    {
        printf("Oh noes!\n");
    }
}

/* #expect: try_assign.ll

define void @try_assign.main() #0 {
entry:
  %z = alloca i32, align 4
  %z.f = alloca i64, align 8
  %w = alloca i32, align 4
  %w.f = alloca i64, align 8
  %x = alloca i32, align 4
  %gh = alloca i32, align 4
  %x8 = alloca i32, align 4
  %e = alloca i64, align 8
  store i32 234, ptr %z, align 4
  store i64 0, ptr %z.f, align 8
  store i64 0, ptr %w.f, align 8
  store i32 0, ptr %w, align 4
  store i32 0, ptr %x, align 4
  %optval = load i64, ptr %z.f, align 8
  %not_err = icmp eq i64 %optval, 0
  %0 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
  br i1 %0, label %after_check, label %catch_landing

after_check:                                      ; preds = %entry
  %1 = load i32, ptr %z, align 4
  store i32 %1, ptr %x, align 4
  br label %phi_try_catch

catch_landing:                                    ; preds = %entry
  br label %phi_try_catch

phi_try_catch:                                    ; preds = %catch_landing, %after_check
  %val = phi i1 [ true, %after_check ], [ false, %catch_landing ]
  br i1 %val, label %chain_next, label %fail_chain

chain_next:                                       ; preds = %phi_try_catch
  store i32 0, ptr %gh, align 4
  %optval1 = load i64, ptr %w.f, align 8
  %not_err2 = icmp eq i64 %optval1, 0
  %2 = call i1 @llvm.expect.i1(i1 %not_err2, i1 true)
  br i1 %2, label %after_check3, label %catch_landing4

after_check3:                                     ; preds = %chain_next
  %3 = load i32, ptr %w, align 4
  store i32 %3, ptr %gh, align 4
  br label %phi_try_catch5

catch_landing4:                                   ; preds = %chain_next
  br label %phi_try_catch5

phi_try_catch5:                                   ; preds = %catch_landing4, %after_check3
  %val6 = phi i1 [ true, %after_check3 ], [ false, %catch_landing4 ]
  br i1 %val6, label %chain_next7, label %fail_chain

chain_next7:                                      ; preds = %phi_try_catch5
  br label %end_chain

fail_chain:                                       ; preds = %phi_try_catch5, %phi_try_catch
  br label %end_chain

end_chain:                                        ; preds = %fail_chain, %chain_next7
  %chain.phi = phi i1 [ true, %chain_next7 ], [ false, %fail_chain ]
  br i1 %chain.phi, label %if.then, label %if.exit

if.then:                                          ; preds = %end_chain
  %4 = load i32, ptr %x, align 4
  %5 = load i32, ptr %gh, align 4
  %6 = call i32 (ptr, ...) @printf(ptr @.str, i32 %4, i32 %5)
  br label %if.exit

if.exit:                                          ; preds = %if.then, %end_chain
  store i32 0, ptr %x8, align 4
  %optval9 = load i64, ptr %z.f, align 8
  %not_err10 = icmp eq i64 %optval9, 0
  %7 = call i1 @llvm.expect.i1(i1 %not_err10, i1 true)
  br i1 %7, label %after_check11, label %catch_landing15

after_check11:                                    ; preds = %if.exit
  %8 = load i32, ptr %z, align 4
  %optval12 = load i64, ptr %w.f, align 8
  %not_err13 = icmp eq i64 %optval12, 0
  %9 = call i1 @llvm.expect.i1(i1 %not_err13, i1 true)
  br i1 %9, label %after_check14, label %catch_landing15

after_check14:                                    ; preds = %after_check11
  %10 = load i32, ptr %w, align 4
  %add = add i32 %8, %10
  store i32 %add, ptr %x8, align 4
  br label %phi_try_catch16

catch_landing15:                                  ; preds = %after_check11, %if.exit
  br label %phi_try_catch16

phi_try_catch16:                                  ; preds = %catch_landing15, %after_check14
  %val17 = phi i1 [ true, %after_check14 ], [ false, %catch_landing15 ]
  br i1 %val17, label %if.then18, label %if.exit19

if.then18:                                        ; preds = %phi_try_catch16
  %11 = call i32 (ptr, ...) @printf(ptr @.str.1)
  br label %if.exit19

if.exit19:                                        ; preds = %if.then18, %phi_try_catch16
  br label %testblock

testblock:                                        ; preds = %if.exit19
  %optval20 = load i64, ptr %z.f, align 8
  %not_err21 = icmp eq i64 %optval20, 0
  %12 = call i1 @llvm.expect.i1(i1 %not_err21, i1 true)
  br i1 %12, label %after_check22, label %assign_optional

assign_optional:                                  ; preds = %testblock
  store i64 %optval20, ptr %e, align 8
  br label %end_block

after_check22:                                    ; preds = %testblock
  store i64 0, ptr %e, align 8
  br label %end_block

end_block:                                        ; preds = %after_check22, %assign_optional
  %13 = load i64, ptr %e, align 8
  %i2b = icmp ne i64 %13, 0
  br i1 %i2b, label %if.then23, label %if.exit24

if.then23:                                        ; preds = %end_block
  %14 = call i32 (ptr, ...) @printf(ptr @.str.2)
  br label %if.exit24

if.exit24:                                        ; preds = %if.then23, %end_block
  ret void
}

