| // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s | 
 | // Verify checked operations are emitted for integers and longs. | 
 | // unsigned short/char's tested in unsigned-promotion.c | 
 |  | 
 | unsigned long li, lj, lk; | 
 | unsigned int ii, ij, ik; | 
 |  | 
 | extern void opaquelong(unsigned long); | 
 | extern void opaqueint(unsigned int); | 
 |  | 
 | // CHECK: define void @testlongadd() | 
 | void testlongadd() { | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i64* @lj | 
 |   // CHECK-NEXT: [[T2:%.*]] = load i64* @lk | 
 |   // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 [[T2]]) | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 | 
 |   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 | 
 |   // CHECK: call void @__ubsan_handle_add_overflow | 
 |   li = lj + lk; | 
 | } | 
 |  | 
 | // CHECK: define void @testlongsub() | 
 | void testlongsub() { | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i64* @lj | 
 |   // CHECK-NEXT: [[T2:%.*]] = load i64* @lk | 
 |   // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[T1]], i64 [[T2]]) | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 | 
 |   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 | 
 |   // CHECK: call void @__ubsan_handle_sub_overflow | 
 |   li = lj - lk; | 
 | } | 
 |  | 
 | // CHECK: define void @testlongmul() | 
 | void testlongmul() { | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i64* @lj | 
 |   // CHECK-NEXT: [[T2:%.*]] = load i64* @lk | 
 |   // CHECK-NEXT: [[T3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[T1]], i64 [[T2]]) | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T3]], 0 | 
 |   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i64, i1 } [[T3]], 1 | 
 |   // CHECK: call void @__ubsan_handle_mul_overflow | 
 |   li = lj * lk; | 
 | } | 
 |  | 
 | // CHECK: define void @testlongpostinc() | 
 | void testlongpostinc() { | 
 |   opaquelong(li++); | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i64* @li | 
 |   // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1) | 
 |   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0 | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1 | 
 |   // CHECK:      call void @__ubsan_handle_add_overflow | 
 | } | 
 |  | 
 | // CHECK: define void @testlongpreinc() | 
 | void testlongpreinc() { | 
 |   opaquelong(++li); | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i64* @li | 
 |   // CHECK-NEXT: [[T2:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[T1]], i64 1) | 
 |   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i64, i1 } [[T2]], 0 | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i64, i1 } [[T2]], 1 | 
 |   // CHECK:      call void @__ubsan_handle_add_overflow | 
 | } | 
 |  | 
 | // CHECK: define void @testintadd() | 
 | void testintadd() { | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i32* @ij | 
 |   // CHECK-NEXT: [[T2:%.*]] = load i32* @ik | 
 |   // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 | 
 |   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 | 
 |   // CHECK:      call void @__ubsan_handle_add_overflow | 
 |   ii = ij + ik; | 
 | } | 
 |  | 
 | // CHECK: define void @testintsub() | 
 | void testintsub() { | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i32* @ij | 
 |   // CHECK-NEXT: [[T2:%.*]] = load i32* @ik | 
 |   // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1]], i32 [[T2]]) | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 | 
 |   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 | 
 |   // CHECK:      call void @__ubsan_handle_sub_overflow | 
 |   ii = ij - ik; | 
 | } | 
 |  | 
 | // CHECK: define void @testintmul() | 
 | void testintmul() { | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i32* @ij | 
 |   // CHECK-NEXT: [[T2:%.*]] = load i32* @ik | 
 |   // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 [[T2]]) | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 | 
 |   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 | 
 |   // CHECK:      call void @__ubsan_handle_mul_overflow | 
 |   ii = ij * ik; | 
 | } | 
 |  | 
 | // CHECK: define void @testintpostinc() | 
 | void testintpostinc() { | 
 |   opaqueint(ii++); | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i32* @ii | 
 |   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1) | 
 |   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 | 
 |   // CHECK:      call void @__ubsan_handle_add_overflow | 
 | } | 
 |  | 
 | // CHECK: define void @testintpreinc() | 
 | void testintpreinc() { | 
 |   opaqueint(++ii); | 
 |  | 
 |   // CHECK:      [[T1:%.*]] = load i32* @ii | 
 |   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T1]], i32 1) | 
 |   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 | 
 |   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 | 
 |   // CHECK:      call void @__ubsan_handle_add_overflow | 
 | } |