]> granicus.if.org Git - clang/commitdiff
Layout the code for trapping arithmetic so that the overflow case comes after
authorBill Wendling <isanbard@gmail.com>
Thu, 7 Jul 2011 21:13:10 +0000 (21:13 +0000)
committerBill Wendling <isanbard@gmail.com>
Thu, 7 Jul 2011 21:13:10 +0000 (21:13 +0000)
the normal case.

Before, for this:

$ cat t.c
int test(int x) { return x * 2; }

We would get this:

   addl  %edi, %edi
   jno   LBB0_2
## BB#1:                                ## %overflow
   ud2
LBB0_2:                                 ## %nooverflow
   movl    %edi, %eax
   popq    %rbp
   ret

Now we get this:

   addl   %edi, %edi
   jo     LBB0_2
## BB#1:                                ## %nooverflow
   movl                                 %edi, %eax
   popq                                 %rbp
   ret
LBB0_2:                                 ## %overflow
   ud2

<rdar://problem/8283919>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134642 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprScalar.cpp

index 84457cbbfea12421bbd1ba108cef38e9bdf31422..9bbc93945c7513c99c052e920ce000a4ff987d3a 100644 (file)
@@ -1677,9 +1677,11 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
                                            const BinOpInfo &Ops, 
                                            llvm::Value *Zero, bool isDiv) {
-  llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
+  llvm::Function::iterator insertPt = Builder.GetInsertBlock();
   llvm::BasicBlock *contBB =
-    CGF.createBasicBlock(isDiv ? "div.cont" : "rem.cont", CGF.CurFn);
+    CGF.createBasicBlock(isDiv ? "div.cont" : "rem.cont", CGF.CurFn,
+                         llvm::next(insertPt));
+  llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
 
   const llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
 
@@ -1709,9 +1711,11 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
     if (Ops.Ty->isIntegerType())
       EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
     else if (Ops.Ty->isRealFloatingType()) {
+      llvm::Function::iterator insertPt = Builder.GetInsertBlock();
+      llvm::BasicBlock *DivCont = CGF.createBasicBlock("div.cont", CGF.CurFn,
+                                                       llvm::next(insertPt));
       llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow",
                                                           CGF.CurFn);
-      llvm::BasicBlock *DivCont = CGF.createBasicBlock("div.cont", CGF.CurFn);
       CGF.Builder.CreateCondBr(Builder.CreateFCmpOEQ(Ops.RHS, Zero), 
                                overflowBB, DivCont);
       EmitOverflowBB(overflowBB);
@@ -1778,8 +1782,10 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
 
   // Branch in case of overflow.
   llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
+  llvm::Function::iterator insertPt = initialBB;
+  llvm::BasicBlock *continueBB = CGF.createBasicBlock("nooverflow", CGF.CurFn,
+                                                      llvm::next(insertPt));
   llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
-  llvm::BasicBlock *continueBB = CGF.createBasicBlock("nooverflow", CGF.CurFn);
 
   Builder.CreateCondBr(overflow, overflowBB, continueBB);