diff options
Diffstat (limited to 'test/CodeGen/unsigned-overflow.c')
-rw-r--r-- | test/CodeGen/unsigned-overflow.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/test/CodeGen/unsigned-overflow.c b/test/CodeGen/unsigned-overflow.c new file mode 100644 index 0000000..341ea35 --- /dev/null +++ b/test/CodeGen/unsigned-overflow.c @@ -0,0 +1,125 @@ +// 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 +} |