diff options
author | Chris Lattner <sabre@nondot.org> | 2010-08-07 00:20:46 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-08-07 00:20:46 +0000 |
commit | 8139c98cf983be08348ea4c7eb7e24b4016279ee (patch) | |
tree | 301ef6835c9cad5703a110f95b81aa4fac6769a7 /clang/lib/CodeGen/CGExprScalar.cpp | |
parent | 03986077144c2c88b413e3891ee8ee202d56605c (diff) | |
download | bcm5719-llvm-8139c98cf983be08348ea4c7eb7e24b4016279ee.tar.gz bcm5719-llvm-8139c98cf983be08348ea4c7eb7e24b4016279ee.zip |
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.
llvm-svn: 110490
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 53 |
1 files changed, 10 insertions, 43 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index ae073da672a..d2ff5623cbe 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/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) { |