diff options
author | John McCall <rjmccall@apple.com> | 2010-08-05 17:39:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-05 17:39:44 +0000 |
commit | a9731a41796617623afb795564971d9b808ee331 (patch) | |
tree | c5fc178ebc54a69e0a162e07f045580978f7b80e | |
parent | 0f8ccc49382e1df00227214d6e05775d43576eb8 (diff) | |
download | bcm5719-llvm-a9731a41796617623afb795564971d9b808ee331.tar.gz bcm5719-llvm-a9731a41796617623afb795564971d9b808ee331.zip |
Fix a major bug with -ftrapv and ++/--. Patch by David Keaton!
llvm-svn: 110347
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/trapv.c | 68 |
2 files changed, 67 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index fb277c6f0e2..8d28b2485f2 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1193,7 +1193,8 @@ EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, BinOp.Ty = E->getType(); BinOp.Opcode = BinaryOperator::Add; BinOp.E = E; - return EmitOverflowCheckedBinOp(BinOp); + NextVal = EmitOverflowCheckedBinOp(BinOp); + break; } } } else { diff --git a/clang/test/CodeGen/trapv.c b/clang/test/CodeGen/trapv.c index d10d6176bf9..46b1c8b14f8 100644 --- a/clang/test/CodeGen/trapv.c +++ b/clang/test/CodeGen/trapv.c @@ -1,10 +1,72 @@ -// RUN: %clang_cc1 -ftrapv %s -emit-llvm -o %t -// RUN: grep "__overflow_handler" %t | count 2 +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -ftrapv %s -emit-llvm -o - | FileCheck %s + +// CHECK: [[I32O:%.*]] = type { i32, i1 } unsigned int ui, uj, uk; int i, j, k; -void foo() { +// CHECK: define void @test0() +void test0() { + // -ftrapv doesn't affect unsigned arithmetic. + // CHECK: [[T1:%.*]] = load i32* @uj + // CHECK-NEXT: [[T2:%.*]] = load i32* @uk + // CHECK-NEXT: [[T3:%.*]] = add i32 [[T1]], [[T2]] + // CHECK-NEXT: store i32 [[T3]], i32* @ui ui = uj + uk; + + // CHECK: [[T1:%.*]] = load i32* @j + // CHECK-NEXT: [[T2:%.*]] = load i32* @k + // CHECK-NEXT: [[T3:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue [[I32O]] [[T3]], 1 + // CHECK-NEXT: br i1 [[T5]] + // CHECK: [[F:%.*]] = load i64 (i64, i64, i8, i8)** @__overflow_handler + // CHECK-NEXT: [[T6:%.*]] = sext i32 [[T1]] to i64 + // CHECK-NEXT: [[T7:%.*]] = sext i32 [[T2]] to i64 + // CHECK-NEXT: [[T8:%.*]] = call i64 [[F]](i64 [[T6]], i64 [[T7]], i8 3, i8 32) + // CHECK-NEXT: [[T9:%.*]] = trunc i64 [[T8]] to i32 + // CHECK-NEXT: br label + // CHECK: [[T10:%.*]] = phi i32 [ [[T4]], {{.*}} ], [ [[T9]], {{.*}} ] + // CHECK-NEXT: store i32 [[T10]], i32* @i i = j + k; } + +// CHECK: define void @test1() +void test1() { + extern void opaque(int); + opaque(i++); + + // CHECK: [[T1:%.*]] = load i32* @i + // CHECK-NEXT: [[T2:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue [[I32O]] [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T2]], 1 + // CHECK-NEXT: br i1 [[T4]] + // CHECK: [[F:%.*]] = load i64 (i64, i64, i8, i8)** @__overflow_handler + // CHECK-NEXT: [[T5:%.*]] = sext i32 [[T1]] to i64 + // CHECK-NEXT: [[T6:%.*]] = call i64 [[F]](i64 [[T5]], i64 1, i8 3, i8 32) + // CHECK-NEXT: [[T7:%.*]] = trunc i64 [[T6]] to i32 + // CHECK-NEXT: br label + // CHECK: [[T8:%.*]] = phi i32 [ [[T3]], {{.*}} ], [ [[T7]], {{.*}} ] + // CHECK-NEXT: store i32 [[T8]], i32* @i + // CHECK-NEXT: call void @opaque(i32 [[T1]]) +} + +// CHECK: define void @test2() +void test2() { + extern void opaque(int); + opaque(++i); + + // CHECK: [[T1:%.*]] = load i32* @i + // CHECK-NEXT: [[T2:%.*]] = call [[I32O]] @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue [[I32O]] [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue [[I32O]] [[T2]], 1 + // CHECK-NEXT: br i1 [[T4]] + // CHECK: [[F:%.*]] = load i64 (i64, i64, i8, i8)** @__overflow_handler + // CHECK-NEXT: [[T5:%.*]] = sext i32 [[T1]] to i64 + // CHECK-NEXT: [[T6:%.*]] = call i64 [[F]](i64 [[T5]], i64 1, i8 3, i8 32) + // CHECK-NEXT: [[T7:%.*]] = trunc i64 [[T6]] to i32 + // CHECK-NEXT: br label + // CHECK: [[T8:%.*]] = phi i32 [ [[T3]], {{.*}} ], [ [[T7]], {{.*}} ] + // CHECK-NEXT: store i32 [[T8]], i32* @i + // CHECK-NEXT: call void @opaque(i32 [[T8]]) +} |