int generic_3(int a, int b, int c) {
  int x = __builtin_add_overflow(a, b, &c);
  x += __builtin_sub_overflow(a, b, &c);
  x += __builtin_mul_overflow(a, b, &c);
  x += __builtin_add_overflow(a, 1, &c);
  x += __builtin_sub_overflow(a, 2, &c);
  x += __builtin_mul_overflow(a, 3, &c);
  x += __builtin_add_overflow(4, b, &c);
  x += __builtin_sub_overflow(5, b, &c);
  x += __builtin_mul_overflow(6, b, &c);
  x += __builtin_add_overflow(7, 8, &c);
  x += __builtin_sub_overflow(9, 10, &c);
  x += __builtin_mul_overflow(11, 12, &c);
  x += __builtin_sub_overflow(0, 0, (char *)0);
  x += __builtin_add_overflow(0, 0, (short *)0);
  x += __builtin_add_overflow(a, b, (int *)0);
  x += __builtin_sub_overflow(a, b, (int *)0);
  x += __builtin_mul_overflow(a, b, (int *)0);
  x += __builtin_add_overflow(a, 1, (int *)0);
  x += __builtin_sub_overflow(a, 2, (int *)0);
  x += __builtin_mul_overflow(a, 3, (int *)0);
  x += __builtin_add_overflow(4, b, (int *)0);
  x += __builtin_sub_overflow(5, b, (int *)0);
  x += __builtin_mul_overflow(6, b, (int *)0);
  x += __builtin_add_overflow(7, 8, (int *)0);
  x += __builtin_sub_overflow(9, 10, (int *)0);
  x += __builtin_mul_overflow(11, 12, (int *)0);
  return x;
}


x86 assembly (clang, -O0):
<generic_3>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    -0x4(%rbp),%ecx
add    -0x8(%rbp),%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%ecx
sub    -0x8(%rbp),%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%ecx
imul   -0x8(%rbp),%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%ecx
inc    %ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%ecx
sub    $0x2,%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x3,%ecx
imul   -0x4(%rbp),%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%ecx
add    $0x4,%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x5,%ecx
sub    -0x8(%rbp),%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x6,%ecx
imul   -0x8(%rbp),%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x7,%ecx
add    $0x8,%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x9,%ecx
sub    $0xa,%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0xb,%ecx
mov    $0xc,%eax
imul   %eax,%ecx
seto   %al
mov    %ecx,-0xc(%rbp)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
xor    %ecx,%ecx
sub    $0x0,%ecx
seto   %al
mov    %cl,%dl
movsbl %dl,%esi
cmp    %esi,%ecx
setne  %cl
or     %cl,%al
xor    %ecx,%ecx
mov    %dl,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
xor    %ecx,%ecx
add    $0x0,%ecx
seto   %al
mov    %cx,%dx
movswl %dx,%esi
cmp    %esi,%ecx
setne  %cl
or     %cl,%al
xor    %ecx,%ecx
mov    %dx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%edx
add    -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%edx
sub    -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%edx
imul   -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%edx
inc    %edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x4(%rbp),%edx
sub    $0x2,%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x3,%edx
imul   -0x4(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x8(%rbp),%edx
add    $0x4,%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x5,%edx
sub    -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x6,%edx
imul   -0x8(%rbp),%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x7,%edx
add    $0x8,%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0x9,%edx
sub    $0xa,%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    $0xb,%edx
mov    $0xc,%eax
imul   %eax,%edx
seto   %al
xor    %ecx,%ecx
mov    %edx,(%rcx)
and    $0x1,%al
movzbl %al,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
pop    %rbp
ret

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

LLVM IR (-O2):