[cfe-commits] r108943 - in /cfe/trunk: lib/CodeGen/CGExprCXX.cpp test/CodeGenCXX/new.cpp

Chris Lattner sabre at nondot.org
Tue Jul 20 14:55:52 PDT 2010


Author: lattner
Date: Tue Jul 20 16:55:52 2010
New Revision: 108943

URL: http://llvm.org/viewvc/llvm-project?rev=108943&view=rev
Log:
in 'new int[4]', constant fold the 4*4=16 instead of 
doing an overflow check.

Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/new.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=108943&r1=108942&r2=108943&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Tue Jul 20 16:55:52 2010
@@ -431,49 +431,71 @@
   if (!E->isArray())
     return llvm::ConstantInt::get(SizeTy, TypeSize.getQuantity());
 
-  CharUnits CookiePadding = CalculateCookiePadding(CGF.getContext(), E);
-  
   // Emit the array size expression.
   NumElements = CGF.EmitScalarExpr(E->getArraySize());
   
-  // Multiply with the type size.  This multiply can overflow, e.g. in:
-  //   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 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, 
-                                                llvm::ConstantInt::get(SizeTy, 
-                                                    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, 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);
-  
-  llvm::PHINode *PN = CGF.Builder.CreatePHI(V->getType());
-  
-  PN->addIncoming(V, PrevBB);
-  PN->addIncoming(llvm::Constant::getAllOnesValue(V->getType()), OverflowBB);
-  V = PN;
+  llvm::Value *Size = llvm::ConstantInt::get(SizeTy, TypeSize.getQuantity());
   
-  // And add the cookie padding if necessary.
+  // If someone is doing 'new int[42]' there is no need to do a dynamic check.
+  // Don't bloat the -O0 code.
+  if (llvm::ConstantInt *NumElementsC =
+        dyn_cast<llvm::ConstantInt>(NumElements)) {
+    // Determine if there is an overflow here by doing an extended multiply.
+    llvm::APInt NEC = NumElementsC->getValue();
+    NEC.zext(NEC.getBitWidth()*2);
+    
+    llvm::APInt SC = cast<llvm::ConstantInt>(Size)->getValue();
+    SC.zext(SC.getBitWidth()*2);
+    SC *= NEC;
+    
+    if (SC.countLeadingZeros() >= NumElementsC->getValue().getBitWidth()) {
+      SC.trunc(NumElementsC->getValue().getBitWidth());
+      Size = llvm::ConstantInt::get(Size->getContext(), SC);
+    } else {
+      // On overflow, produce a -1 so operator new throws.
+      Size = llvm::Constant::getAllOnesValue(Size->getType());
+    }
+    
+  } else {
+    // Multiply with the type size.  This multiply can overflow, e.g. in:
+    //   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 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, Size);
+    // 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, 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);
+    
+    llvm::PHINode *PN = CGF.Builder.CreatePHI(V->getType());
+    
+    PN->addIncoming(V, PrevBB);
+    PN->addIncoming(llvm::Constant::getAllOnesValue(V->getType()), OverflowBB);
+    Size = PN;
+  }
+  
+  // Add the cookie padding if necessary.
+  CharUnits CookiePadding = CalculateCookiePadding(CGF.getContext(), E);
   if (!CookiePadding.isZero())
-    V = CGF.Builder.CreateAdd(V, 
+    Size = CGF.Builder.CreateAdd(Size, 
         llvm::ConstantInt::get(SizeTy, CookiePadding.getQuantity()));
   
-  return V;
+  return Size;
 }
 
 static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E,

Modified: cfe/trunk/test/CodeGenCXX/new.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/new.cpp?rev=108943&r1=108942&r2=108943&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/new.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/new.cpp Tue Jul 20 16:55:52 2010
@@ -102,6 +102,7 @@
 // We don't need to initialize an empty class.
 void t12() {
   // CHECK: define void @_Z3t12v
+  // CHECK-NOT: br label
   // CHECK: ret void
   (void)new Empty[10];
 }





More information about the cfe-commits mailing list