int typed_3_null(int a, int b) {
  int x = 0;
  x += __builtin_sadd_overflow(a, b, (int *)0);
  x += __builtin_uadd_overflow(a, b, (unsigned *)0);
  x += __builtin_saddl_overflow(a, b, (long *)0);
  x += __builtin_uaddl_overflow(a, b, (unsigned long *)0);
  x += __builtin_saddll_overflow(a, b, (long long *)0);
  x += __builtin_uaddll_overflow(a, b, (unsigned long long *)0);
  x += __builtin_ssub_overflow(a, b, (int *)0);
  x += __builtin_usub_overflow(a, b, (unsigned *)0);
  x += __builtin_ssubl_overflow(a, b, (long *)0);
  x += __builtin_usubl_overflow(a, b, (unsigned long *)0);
  x += __builtin_ssubll_overflow(a, b, (long long *)0);
  x += __builtin_usubll_overflow(a, b, (unsigned long long *)0);
  x += __builtin_smul_overflow(a, b, (int *)0);
  x += __builtin_umul_overflow(a, b, (unsigned *)0);
  x += __builtin_smull_overflow(a, b, (long *)0);
  x += __builtin_umull_overflow(a, b, (unsigned long *)0);
  x += __builtin_smulll_overflow(a, b, (long long *)0);
  x += __builtin_umulll_overflow(a, b, (unsigned long long *)0);
  return x;
}


x86 assembly (clang, -O0):
<typed_3_null>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
mov    -0x4(%rbp),%edx
add    -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%edx
add    -0x8(%rbp),%edx
setb   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
add    %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
add    %rax,%rdx
setb   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
add    %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
add    %rax,%rdx
setb   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%edx
sub    -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%edx
sub    -0x8(%rbp),%edx
setb   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
sub    %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
sub    %rax,%rdx
setb   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
sub    %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
sub    %rax,%rdx
setb   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%edx
imul   -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%eax
mull   -0x8(%rbp)
mov    %eax,%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
imul   %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rax
movslq -0x8(%rbp),%rcx
mul    %rcx
mov    %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rdx
movslq -0x8(%rbp),%rax
imul   %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
movslq -0x4(%rbp),%rax
movslq -0x8(%rbp),%rcx
mul    %rcx
mov    %rax,%rdx
seto   %al
xor    %ecx,%ecx
mov    %rdx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
LLVM IR (-O0):
define i32 @typed_3_null(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
store i32 %0, i32* %3
store i32 %1, i32* %4
store i32 0, i32* %5
%6 = load i32, i32* %3
%7 = load i32, i32* %4
%8 = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %6, i32 %7)
%9 = extractvalue { i32, i1 } %8, 1
%10 = extractvalue { i32, i1 } %8, 0
store i32 %10, i32* null
%11 = zext i1 %9 to i32
%12 = load i32, i32* %5
%13 = add nsw i32 %12, %11
store i32 %13, i32* %5
%14 = load i32, i32* %3
%15 = load i32, i32* %4
%16 = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %14, i32 %15)
%17 = extractvalue { i32, i1 } %16, 1
%18 = extractvalue { i32, i1 } %16, 0
store i32 %18, i32* null
%19 = zext i1 %17 to i32
%20 = load i32, i32* %5
%21 = add nsw i32 %20, %19
store i32 %21, i32* %5
%22 = load i32, i32* %3
%23 = sext i32 %22 to i64
%24 = load i32, i32* %4
%25 = sext i32 %24 to i64
%26 = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %23, i64 %25)
%27 = extractvalue { i64, i1 } %26, 1
%28 = extractvalue { i64, i1 } %26, 0
store i64 %28, i64* null
%29 = zext i1 %27 to i32
%30 = load i32, i32* %5
%31 = add nsw i32 %30, %29
store i32 %31, i32* %5
%32 = load i32, i32* %3
%33 = sext i32 %32 to i64
%34 = load i32, i32* %4
%35 = sext i32 %34 to i64
%36 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %33, i64 %35)
%37 = extractvalue { i64, i1 } %36, 1
%38 = extractvalue { i64, i1 } %36, 0
store i64 %38, i64* null
%39 = zext i1 %37 to i32
%40 = load i32, i32* %5
%41 = add nsw i32 %40, %39
store i32 %41, i32* %5
%42 = load i32, i32* %3
%43 = sext i32 %42 to i64
%44 = load i32, i32* %4
%45 = sext i32 %44 to i64
%46 = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %43, i64 %45)
%47 = extractvalue { i64, i1 } %46, 1
%48 = extractvalue { i64, i1 } %46, 0
store i64 %48, i64* null
%49 = zext i1 %47 to i32
%50 = load i32, i32* %5
%51 = add nsw i32 %50, %49
store i32 %51, i32* %5
%52 = load i32, i32* %3
%53 = sext i32 %52 to i64
%54 = load i32, i32* %4
%55 = sext i32 %54 to i64
%56 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %53, i64 %55)
%57 = extractvalue { i64, i1 } %56, 1
%58 = extractvalue { i64, i1 } %56, 0
store i64 %58, i64* null
%59 = zext i1 %57 to i32
%60 = load i32, i32* %5
%61 = add nsw i32 %60, %59
store i32 %61, i32* %5
%62 = load i32, i32* %3
%63 = load i32, i32* %4
%64 = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %62, i32 %63)
%65 = extractvalue { i32, i1 } %64, 1
%66 = extractvalue { i32, i1 } %64, 0
store i32 %66, i32* null
%67 = zext i1 %65 to i32
%68 = load i32, i32* %5
%69 = add nsw i32 %68, %67
store i32 %69, i32* %5
%70 = load i32, i32* %3
%71 = load i32, i32* %4
%72 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %70, i32 %71)
%73 = extractvalue { i32, i1 } %72, 1
%74 = extractvalue { i32, i1 } %72, 0
store i32 %74, i32* null
%75 = zext i1 %73 to i32
%76 = load i32, i32* %5
%77 = add nsw i32 %76, %75
store i32 %77, i32* %5
%78 = load i32, i32* %3
%79 = sext i32 %78 to i64
%80 = load i32, i32* %4
%81 = sext i32 %80 to i64
%82 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %79, i64 %81)
%83 = extractvalue { i64, i1 } %82, 1
%84 = extractvalue { i64, i1 } %82, 0
store i64 %84, i64* null
%85 = zext i1 %83 to i32
%86 = load i32, i32* %5
%87 = add nsw i32 %86, %85
store i32 %87, i32* %5
%88 = load i32, i32* %3
%89 = sext i32 %88 to i64
%90 = load i32, i32* %4
%91 = sext i32 %90 to i64
%92 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %89, i64 %91)
%93 = extractvalue { i64, i1 } %92, 1
%94 = extractvalue { i64, i1 } %92, 0
store i64 %94, i64* null
%95 = zext i1 %93 to i32
%96 = load i32, i32* %5
%97 = add nsw i32 %96, %95
store i32 %97, i32* %5
%98 = load i32, i32* %3
%99 = sext i32 %98 to i64
%100 = load i32, i32* %4
%101 = sext i32 %100 to i64
%102 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %99, i64 %101)
%103 = extractvalue { i64, i1 } %102, 1
%104 = extractvalue { i64, i1 } %102, 0
store i64 %104, i64* null
%105 = zext i1 %103 to i32
%106 = load i32, i32* %5
%107 = add nsw i32 %106, %105
store i32 %107, i32* %5
%108 = load i32, i32* %3
%109 = sext i32 %108 to i64
%110 = load i32, i32* %4
%111 = sext i32 %110 to i64
%112 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %109, i64 %111)
%113 = extractvalue { i64, i1 } %112, 1
%114 = extractvalue { i64, i1 } %112, 0
store i64 %114, i64* null
%115 = zext i1 %113 to i32
%116 = load i32, i32* %5
%117 = add nsw i32 %116, %115
store i32 %117, i32* %5
%118 = load i32, i32* %3
%119 = load i32, i32* %4
%120 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %118, i32 %119)
%121 = extractvalue { i32, i1 } %120, 1
%122 = extractvalue { i32, i1 } %120, 0
store i32 %122, i32* null
%123 = zext i1 %121 to i32
%124 = load i32, i32* %5
%125 = add nsw i32 %124, %123
store i32 %125, i32* %5
%126 = load i32, i32* %3
%127 = load i32, i32* %4
%128 = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %126, i32 %127)
%129 = extractvalue { i32, i1 } %128, 1
%130 = extractvalue { i32, i1 } %128, 0
store i32 %130, i32* null
%131 = zext i1 %129 to i32
%132 = load i32, i32* %5
%133 = add nsw i32 %132, %131
store i32 %133, i32* %5
%134 = load i32, i32* %3
%135 = sext i32 %134 to i64
%136 = load i32, i32* %4
%137 = sext i32 %136 to i64
%138 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %135, i64 %137)
%139 = extractvalue { i64, i1 } %138, 1
%140 = extractvalue { i64, i1 } %138, 0
store i64 %140, i64* null
%141 = zext i1 %139 to i32
%142 = load i32, i32* %5
%143 = add nsw i32 %142, %141
store i32 %143, i32* %5
%144 = load i32, i32* %3
%145 = sext i32 %144 to i64
%146 = load i32, i32* %4
%147 = sext i32 %146 to i64
%148 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %145, i64 %147)
%149 = extractvalue { i64, i1 } %148, 1
%150 = extractvalue { i64, i1 } %148, 0
store i64 %150, i64* null
%151 = zext i1 %149 to i32
%152 = load i32, i32* %5
%153 = add nsw i32 %152, %151
store i32 %153, i32* %5
%154 = load i32, i32* %3
%155 = sext i32 %154 to i64
%156 = load i32, i32* %4
%157 = sext i32 %156 to i64
%158 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %155, i64 %157)
%159 = extractvalue { i64, i1 } %158, 1
%160 = extractvalue { i64, i1 } %158, 0
store i64 %160, i64* null
%161 = zext i1 %159 to i32
%162 = load i32, i32* %5
%163 = add nsw i32 %162, %161
store i32 %163, i32* %5
%164 = load i32, i32* %3
%165 = sext i32 %164 to i64
%166 = load i32, i32* %4
%167 = sext i32 %166 to i64
%168 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %165, i64 %167)
%169 = extractvalue { i64, i1 } %168, 1
%170 = extractvalue { i64, i1 } %168, 0
store i64 %170, i64* null
%171 = zext i1 %169 to i32
%172 = load i32, i32* %5
%173 = add nsw i32 %172, %171
store i32 %173, i32* %5
%174 = load i32, i32* %5
ret i32 %174
}

LLVM IR (-O2):