aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-07-20 21:07:09 +0000
committerChris Lattner <sabre@nondot.org>2010-07-20 21:07:09 +0000
commit83252dcfe61aaebcb6bc117e71dc12968729513f (patch)
treea303b42463464aef9a146dbc5678a70d0c0bfe31 /lib/CodeGen/CGExprCXX.cpp
parent021a7a63984f0f912dc9e9dae2a1b3e1509a40ce (diff)
Follow the implementation approach suggested by PR6687,
which generates more efficient and more obviously conformant code. We now test for overflow of the multiply then force the result to -1 if so. On X86, this generates nice code like this: __Z4testl: ## @_Z4testl ## BB#0: ## %entry subl $12, %esp movl $4, %eax mull 16(%esp) testl %edx, %edx movl $-1, %ecx cmovel %eax, %ecx movl %ecx, (%esp) call __Znam addl $12, %esp ret git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108927 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--lib/CodeGen/CGExprCXX.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index cc34b3d75c..d3e7919224 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -440,7 +440,7 @@ static llvm::Value *EmitCXXNewAllocSize(ASTContext &Context,
// new double[n]
// where n is 2^30 on a 32-bit machine or 2^62 on a 64-bit machine. Because
// of this, we need to detect the overflow and ensure that an exception is
- // called by invoking std::__throw_length_error.
+ // called by forcing the size to -1 on overflow.
llvm::Value *UMulF = CGF.CGM.getIntrinsic(llvm::Intrinsic::umul_with_overflow,
&SizeTy, 1);
llvm::Value *MulRes = CGF.Builder.CreateCall2(UMulF, NumElements,
@@ -448,15 +448,26 @@ static llvm::Value *EmitCXXNewAllocSize(ASTContext &Context,
TypeSize.getQuantity()));
// Branch on the overflow bit to the overflow block, which is lazily created.
llvm::Value *DidOverflow = CGF.Builder.CreateExtractValue(MulRes, 1);
+ // Get the normal result of the multiplication.
+ llvm::Value *V = CGF.Builder.CreateExtractValue(MulRes, 0);
llvm::BasicBlock *NormalBB = CGF.createBasicBlock("no_overflow");
+ llvm::BasicBlock *OverflowBB = CGF.createBasicBlock("overflow");
- CGF.Builder.CreateCondBr(DidOverflow, CGF.getThrowLengthErrorBB(), NormalBB);
+ CGF.Builder.CreateCondBr(DidOverflow, OverflowBB, NormalBB);
+
+ llvm::BasicBlock *PrevBB = CGF.Builder.GetInsertBlock();
+
+ // We just need the overflow block to build a PHI node.
+ CGF.EmitBlock(OverflowBB);
CGF.EmitBlock(NormalBB);
- // Get the normal result of the multiplication.
- llvm::Value *V = CGF.Builder.CreateExtractValue(MulRes, 0);
-
+ llvm::PHINode *PN = CGF.Builder.CreatePHI(V->getType());
+
+ PN->addIncoming(V, PrevBB);
+ PN->addIncoming(llvm::Constant::getAllOnesValue(V->getType()), OverflowBB);
+ V = PN;
+
// And add the cookie padding if necessary.
if (!CookiePadding.isZero())
V = CGF.Builder.CreateAdd(V,