aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-08-07 00:20:46 +0000
committerChris Lattner <sabre@nondot.org>2010-08-07 00:20:46 +0000
commit93a00357f2795404c6709d9e06b4f717c82e6efb (patch)
tree990c220acb334c83f65ada116890dca1677059b7
parent647c8b32c2a6e38ee44dde1782a629e9c03786e2 (diff)
Correct -ftrapv to trap on errors, instead of calling the
__overflow_handler entrypoint that David Chisnall made up. Calling __overflow_handler is not part of the contract of -ftrapv provided by GCC, and should never have been checked in in the first place. According to: http://permalink.gmane.org/gmane.comp.compilers.clang.devel/8699 David is using this for some of arbitrary precision integer stuff or something, which is not an appropriate thing to implement on this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110490 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGExprScalar.cpp53
-rw-r--r--test/CodeGen/trapv.c27
2 files changed, 13 insertions, 67 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index ae073da672..d2ff5623cb 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1548,54 +1548,21 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
// Branch in case of overflow.
- llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
- llvm::BasicBlock *overflowBB =
- CGF.createBasicBlock("overflow", CGF.CurFn);
- llvm::BasicBlock *continueBB =
- CGF.createBasicBlock("overflow.continue", CGF.CurFn);
+ llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
+ llvm::BasicBlock *continueBB = CGF.createBasicBlock("nooverflow", CGF.CurFn);
Builder.CreateCondBr(overflow, overflowBB, continueBB);
- // Handle overflow
-
+ // Handle overflow with llvm.trap.
+ // TODO: it would be better to generate one of these blocks per function.
Builder.SetInsertPoint(overflowBB);
-
- // Handler is:
- // long long *__overflow_handler)(long long a, long long b, char op,
- // char width)
- std::vector<const llvm::Type*> handerArgTypes;
- handerArgTypes.push_back(CGF.Int64Ty);
- handerArgTypes.push_back(CGF.Int64Ty);
- handerArgTypes.push_back(llvm::Type::getInt8Ty(VMContext));
- handerArgTypes.push_back(llvm::Type::getInt8Ty(VMContext));
- llvm::FunctionType *handlerTy =
- llvm::FunctionType::get(CGF.Int64Ty, handerArgTypes, false);
- llvm::Value *handlerFunction =
- CGF.CGM.getModule().getOrInsertGlobal("__overflow_handler",
- llvm::PointerType::getUnqual(handlerTy));
- handlerFunction = Builder.CreateLoad(handlerFunction);
-
- llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.Int64Ty);
- llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.Int64Ty);
-
- llvm::Value *handlerResult =
- Builder.CreateCall4(handlerFunction, lhs, rhs,
- Builder.getInt8(OpID),
- Builder.getInt8(cast<llvm::IntegerType>(opTy)->getBitWidth()));
-
- handlerResult = Builder.CreateTrunc(handlerResult, opTy);
-
- Builder.CreateBr(continueBB);
-
- // Set up the continuation
+ llvm::Function *Trap = CGF.CGM.getIntrinsic(llvm::Intrinsic::trap);
+ Builder.CreateCall(Trap);
+ Builder.CreateUnreachable();
+
+ // Continue on.
Builder.SetInsertPoint(continueBB);
- // Get the correct result
- llvm::PHINode *phi = Builder.CreatePHI(opTy);
- phi->reserveOperandSpace(2);
- phi->addIncoming(result, initialBB);
- phi->addIncoming(handlerResult, overflowBB);
-
- return phi;
+ return result;
}
Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
diff --git a/test/CodeGen/trapv.c b/test/CodeGen/trapv.c
index 46b1c8b14f..7f192c634c 100644
--- a/test/CodeGen/trapv.c
+++ b/test/CodeGen/trapv.c
@@ -20,14 +20,7 @@ void test0() {
// 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
+ // CHECK: call void @llvm.trap()
i = j + k;
}
@@ -41,14 +34,7 @@ void test1() {
// 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: call void @llvm.trap()
}
// CHECK: define void @test2()
@@ -61,12 +47,5 @@ void test2() {
// 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]])
+ // CHECK: call void @llvm.trap()
}