From: Chris Lattner Date: Sat, 7 Aug 2010 00:20:46 +0000 (+0000) Subject: Correct -ftrapv to trap on errors, instead of calling the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=93a00357f2795404c6709d9e06b4f717c82e6efb;p=clang 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 --- 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 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(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() }