summaryrefslogtreecommitdiffstats
path: root/test/CodeGen/unsigned-promotion.c
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
committerdim <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
commitc72c57c9e9b69944e3e009cd5e209634839581d3 (patch)
tree4fc2f184c499d106f29a386c452b49e5197bf63d /test/CodeGen/unsigned-promotion.c
parent5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff)
downloadFreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip
FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'test/CodeGen/unsigned-promotion.c')
-rw-r--r--test/CodeGen/unsigned-promotion.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/test/CodeGen/unsigned-promotion.c b/test/CodeGen/unsigned-promotion.c
new file mode 100644
index 0000000..c263c0c
--- /dev/null
+++ b/test/CodeGen/unsigned-promotion.c
@@ -0,0 +1,143 @@
+// Check -fsanitize=signed-integer-overflow and
+// -fsanitize=unsigned-integer-overflow with promoted unsigned types
+//
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
+// RUN: -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=CHECKS
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
+// RUN: -fsanitize=unsigned-integer-overflow | FileCheck %s --check-prefix=CHECKU
+
+unsigned short si, sj, sk;
+unsigned char ci, cj, ck;
+
+extern void opaqueshort(unsigned short);
+extern void opaquechar(unsigned char);
+
+// CHECKS: define void @testshortadd()
+// CHECKU: define void @testshortadd()
+void testshortadd() {
+ // CHECKS: load i16* @sj
+ // CHECKS: load i16* @sk
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_add_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i16* @sj
+ // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i16* @sk
+ // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
+ // CHECKU-NOT: llvm.sadd
+ // CHECKU-NOT: llvm.uadd
+ // CHECKU: [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
+
+ si = sj + sk;
+}
+
+// CHECKS: define void @testshortsub()
+// CHECKU: define void @testshortsub()
+void testshortsub() {
+
+ // CHECKS: load i16* @sj
+ // CHECKS: load i16* @sk
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_sub_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i16* @sj
+ // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i16* @sk
+ // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
+ // CHECKU-NOT: llvm.ssub
+ // CHECKU-NOT: llvm.usub
+ // CHECKU: [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
+
+ si = sj - sk;
+}
+
+// CHECKS: define void @testshortmul()
+// CHECKU: define void @testshortmul()
+void testshortmul() {
+
+ // CHECKS: load i16* @sj
+ // CHECKS: load i16* @sk
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_mul_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i16* @sj
+ // CHECKU: [[T2:%.*]] = zext i16 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i16* @sk
+ // CHECKU: [[T4:%.*]] = zext i16 [[T3]]
+ // CHECKU-NOT: llvm.smul
+ // CHECKU-NOT: llvm.umul
+ // CHECKU: [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
+ si = sj * sk;
+}
+
+// CHECKS: define void @testcharadd()
+// CHECKU: define void @testcharadd()
+void testcharadd() {
+
+ // CHECKS: load i8* @cj
+ // CHECKS: load i8* @ck
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_add_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i8* @cj
+ // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i8* @ck
+ // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
+ // CHECKU-NOT: llvm.sadd
+ // CHECKU-NOT: llvm.uadd
+ // CHECKU: [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
+
+ ci = cj + ck;
+}
+
+// CHECKS: define void @testcharsub()
+// CHECKU: define void @testcharsub()
+void testcharsub() {
+
+ // CHECKS: load i8* @cj
+ // CHECKS: load i8* @ck
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_sub_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i8* @cj
+ // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i8* @ck
+ // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
+ // CHECKU-NOT: llvm.ssub
+ // CHECKU-NOT: llvm.usub
+ // CHECKU: [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
+
+ ci = cj - ck;
+}
+
+// CHECKS: define void @testcharmul()
+// CHECKU: define void @testcharmul()
+void testcharmul() {
+
+ // CHECKS: load i8* @cj
+ // CHECKS: load i8* @ck
+ // CHECKS: [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
+ // CHECKS-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
+ // CHECKS-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
+ // CHECKS: call void @__ubsan_handle_mul_overflow
+ //
+ // CHECKU: [[T1:%.*]] = load i8* @cj
+ // CHECKU: [[T2:%.*]] = zext i8 [[T1]]
+ // CHECKU: [[T3:%.*]] = load i8* @ck
+ // CHECKU: [[T4:%.*]] = zext i8 [[T3]]
+ // CHECKU-NOT: llvm.smul
+ // CHECKU-NOT: llvm.umul
+ // CHECKU: [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
+
+ ci = cj * ck;
+}
OpenPOWER on IntegriCloud