[cfe-commits] r163451 - in /cfe/trunk: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/trapv.c

Richard Smith richard-llvm at metafoo.co.uk
Fri Sep 7 19:08:37 PDT 2012


Author: rsmith
Date: Fri Sep  7 21:08:36 2012
New Revision: 163451

URL: http://llvm.org/viewvc/llvm-project?rev=163451&view=rev
Log:
-fcatch-undefined-behavior: Factor emission of the creation of, and branch to,
the trap BB out of the individual checks and into a common function, to prepare
for making this code call into a runtime library. Rename the existing EmitCheck
to EmitTypeCheck to clarify it and to move it out of the way of the new
EmitCheck.

Modified:
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGen/trapv.c

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=163451&r1=163450&r2=163451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Fri Sep  7 21:08:36 2012
@@ -404,7 +404,7 @@
   }
   case Builtin::BI__builtin_unreachable: {
     if (CatchUndefined)
-      EmitBranch(getTrapBB());
+      EmitCheck(Builder.getFalse());
     else
       Builder.CreateUnreachable();
 

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=163451&r1=163450&r2=163451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Sep  7 21:08:36 2012
@@ -493,7 +493,7 @@
     //   storage of suitable size and alignment to contain an object of the
     //   reference's type, the behavior is undefined.
     QualType Ty = E->getType();
-    EmitCheck(CT_ReferenceBinding, Value, Ty);
+    EmitTypeCheck(TCK_ReferenceBinding, Value, Ty);
   }
   if (!ReferenceTemporaryDtor && ObjCARCReferenceLifetimeType.isNull())
     return RValue::get(Value);
@@ -558,14 +558,14 @@
       ->getZExtValue();
 }
 
-void CodeGenFunction::EmitCheck(CheckType CT, llvm::Value *Address, QualType Ty,
-                                CharUnits Alignment) {
+void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, llvm::Value *Address,
+                                    QualType Ty, CharUnits Alignment) {
   if (!CatchUndefined)
     return;
 
   llvm::Value *Cond = 0;
 
-  if (CT != CT_Load && CT != CT_Store) {
+  if (TCK != TCK_Load && TCK != TCK_Store) {
     // The glvalue must not be an empty glvalue. Don't bother checking this for
     // loads and stores, because we will get a segfault anyway (if the operation
     // isn't optimized out).
@@ -600,11 +600,8 @@
         Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)));
   }
 
-  if (Cond) {
-    llvm::BasicBlock *Cont = createBasicBlock();
-    Builder.CreateCondBr(Cond, Cont, getTrapBB());
-    EmitBlock(Cont);
-  }
+  if (Cond)
+    EmitCheck(Cond);
 }
 
 
@@ -681,10 +678,10 @@
   return MakeAddrLValue(llvm::UndefValue::get(Ty), E->getType());
 }
 
-LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, CheckType CT) {
+LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {
   LValue LV = EmitLValue(E);
   if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
-    EmitCheck(CT, LV.getAddress(), E->getType(), LV.getAlignment());
+    EmitTypeCheck(TCK, LV.getAddress(), E->getType(), LV.getAlignment());
   return LV;
 }
 
@@ -1927,33 +1924,33 @@
   }
 }
 
-llvm::BasicBlock *CodeGenFunction::getTrapBB() {
+void CodeGenFunction::EmitCheck(llvm::Value *Checked) {
   const CodeGenOptions &GCO = CGM.getCodeGenOpts();
 
+  llvm::BasicBlock *Cont = createBasicBlock("cont");
+
   // If we are not optimzing, don't collapse all calls to trap in the function
   // to the same call, that way, in the debugger they can see which operation
   // did in fact fail.  If we are optimizing, we collapse all calls to trap down
   // to just one per function to save on codesize.
-  if (GCO.OptimizationLevel && TrapBB)
-    return TrapBB;
+  bool NeedNewTrapBB = !GCO.OptimizationLevel || !TrapBB;
+
+  if (NeedNewTrapBB)
+    TrapBB = createBasicBlock("trap");
+
+  Builder.CreateCondBr(Checked, Cont, TrapBB);
+
+  if (NeedNewTrapBB) {
+    EmitBlock(TrapBB);
+
+    llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap);
+    llvm::CallInst *TrapCall = Builder.CreateCall(F);
+    TrapCall->setDoesNotReturn();
+    TrapCall->setDoesNotThrow();
+    Builder.CreateUnreachable();
+  }
 
-  llvm::BasicBlock *Cont = 0;
-  if (HaveInsertPoint()) {
-    Cont = createBasicBlock("cont");
-    EmitBranch(Cont);
-  }
-  TrapBB = createBasicBlock("trap");
-  EmitBlock(TrapBB);
-
-  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::trap);
-  llvm::CallInst *TrapCall = Builder.CreateCall(F);
-  TrapCall->setDoesNotReturn();
-  TrapCall->setDoesNotThrow();
-  Builder.CreateUnreachable();
-
-  if (Cont)
-    EmitBlock(Cont);
-  return TrapBB;
+  EmitBlock(Cont);
 }
 
 /// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an
@@ -2156,10 +2153,10 @@
   if (E->isArrow()) {
     llvm::Value *Ptr = EmitScalarExpr(BaseExpr);
     QualType PtrTy = BaseExpr->getType()->getPointeeType();
-    EmitCheck(CT_MemberAccess, Ptr, PtrTy);
+    EmitTypeCheck(TCK_MemberAccess, Ptr, PtrTy);
     BaseLV = MakeNaturalAlignAddrLValue(Ptr, PtrTy);
   } else
-    BaseLV = EmitCheckedLValue(BaseExpr, CT_MemberAccess);
+    BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);
 
   NamedDecl *ND = E->getMemberDecl();
   if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) {

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=163451&r1=163450&r2=163451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Fri Sep  7 21:08:36 2012
@@ -552,7 +552,7 @@
     // FIXME: Can this actually happen? We have no test coverage for it.
     assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
     LValue LV = CGF.EmitCheckedLValue(E->getSubExpr(),
-                                      CodeGenFunction::CT_Load);
+                                      CodeGenFunction::TCK_Load);
     // FIXME: Do we also need to handle property references here?
     if (LV.isSimple())
       CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=163451&r1=163450&r2=163451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Fri Sep  7 21:08:36 2012
@@ -36,7 +36,8 @@
   // C++11 [class.mfct.non-static]p2:
   //   If a non-static member function of a class X is called for an object that
   //   is not of type X, or of a type derived from X, the behavior is undefined.
-  EmitCheck(CT_MemberCall, This, getContext().getRecordType(MD->getParent()));
+  EmitTypeCheck(TCK_MemberCall, This,
+                getContext().getRecordType(MD->getParent()));
 
   CallArgList Args;
 
@@ -342,7 +343,7 @@
   else 
     This = EmitLValue(BaseExpr).getAddress();
 
-  EmitCheck(CT_MemberCall, This, QualType(MPT->getClass(), 0));
+  EmitTypeCheck(TCK_MemberCall, This, QualType(MPT->getClass(), 0));
 
   // Ask the ABI to load the callee.  Note that This is modified.
   llvm::Value *Callee =

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=163451&r1=163450&r2=163451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Fri Sep  7 21:08:36 2012
@@ -80,8 +80,8 @@
 
   llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
   LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
-  LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::CheckType CT) {
-    return CGF.EmitCheckedLValue(E, CT);
+  LValue EmitCheckedLValue(const Expr *E, CodeGenFunction::TypeCheckKind TCK) {
+    return CGF.EmitCheckedLValue(E, TCK);
   }
 
   Value *EmitLoadOfLValue(LValue LV) {
@@ -92,7 +92,7 @@
   /// value l-value, this method emits the address of the l-value, then loads
   /// and returns the result.
   Value *EmitLoadOfLValue(const Expr *E) {
-    return EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::CT_Load));
+    return EmitLoadOfLValue(EmitCheckedLValue(E, CodeGenFunction::TCK_Load));
   }
 
   /// EmitConversionToBool - Convert the specified expression value to a
@@ -416,13 +416,7 @@
   /// Create a binary op that checks for overflow.
   /// Currently only supports +, - and *.
   Value *EmitOverflowCheckedBinOp(const BinOpInfo &Ops);
-  // Emit the overflow BB when -ftrapv option is activated. 
-  void EmitOverflowBB(llvm::BasicBlock *overflowBB) {
-    Builder.SetInsertPoint(overflowBB);
-    llvm::Function *Trap = CGF.CGM.getIntrinsic(llvm::Intrinsic::trap);
-    Builder.CreateCall(Trap);
-    Builder.CreateUnreachable();
-  }
+
   // Check for undefined division and modulus behaviors.
   void EmitUndefinedBehaviorIntegerDivAndRemCheck(const BinOpInfo &Ops, 
                                                   llvm::Value *Zero,bool isDiv);
@@ -1688,7 +1682,7 @@
   OpInfo.Opcode = E->getOpcode();
   OpInfo.E = E;
   // Load/convert the LHS.
-  LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::CT_Store);
+  LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
   OpInfo.LHS = EmitLoadOfLValue(LHSLV);
 
   llvm::PHINode *atomicPHI = 0;
@@ -1760,14 +1754,7 @@
 }
 
 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
-     					    const BinOpInfo &Ops, 
-				     	    llvm::Value *Zero, bool isDiv) {
-  llvm::Function::iterator insertPt = Builder.GetInsertBlock();
-  llvm::BasicBlock *contBB =
-    CGF.createBasicBlock(isDiv ? "div.cont" : "rem.cont", CGF.CurFn,
-                         llvm::next(insertPt));
-  llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
-
+    const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
   llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
 
   if (Ops.Ty->hasSignedIntegerRepresentation()) {
@@ -1775,37 +1762,24 @@
       Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
     llvm::Value *NegOne = llvm::ConstantInt::get(Ty, -1ULL);
 
-    llvm::Value *Cond1 = Builder.CreateICmpEQ(Ops.RHS, Zero);
-    llvm::Value *LHSCmp = Builder.CreateICmpEQ(Ops.LHS, IntMin);
-    llvm::Value *RHSCmp = Builder.CreateICmpEQ(Ops.RHS, NegOne);
-    llvm::Value *Cond2 = Builder.CreateAnd(LHSCmp, RHSCmp, "and");
-    Builder.CreateCondBr(Builder.CreateOr(Cond1, Cond2, "or"), 
-                         overflowBB, contBB);
+    llvm::Value *Cond1 = Builder.CreateICmpNE(Ops.RHS, Zero);
+    llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
+    llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
+    llvm::Value *Cond2 = Builder.CreateOr(LHSCmp, RHSCmp, "or");
+    CGF.EmitCheck(Builder.CreateAnd(Cond1, Cond2, "and"));
   } else {
-    CGF.Builder.CreateCondBr(Builder.CreateICmpEQ(Ops.RHS, Zero), 
-                             overflowBB, contBB);
+    CGF.EmitCheck(Builder.CreateICmpNE(Ops.RHS, Zero));
   }
-  EmitOverflowBB(overflowBB);
-  Builder.SetInsertPoint(contBB);
 }
 
 Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
-  if (isTrapvOverflowBehavior()) { 
+  if (isTrapvOverflowBehavior()) {
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
 
     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);
-      CGF.Builder.CreateCondBr(Builder.CreateFCmpOEQ(Ops.RHS, Zero), 
-                               overflowBB, DivCont);
-      EmitOverflowBB(overflowBB);
-      Builder.SetInsertPoint(DivCont);
-    }
+    else if (Ops.Ty->isRealFloatingType())
+      CGF.EmitCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero));
   }
   if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
     llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
@@ -1874,6 +1848,14 @@
   Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
   Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
 
+  // Handle overflow with llvm.trap if no custom handler has been specified.
+  const std::string *handlerName =
+    &CGF.getContext().getLangOpts().OverflowHandler;
+  if (handlerName->empty()) {
+    CGF.EmitCheck(Builder.CreateNot(overflow));
+    return result;
+  }
+
   // Branch in case of overflow.
   llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
   llvm::Function::iterator insertPt = initialBB;
@@ -1883,15 +1865,6 @@
 
   Builder.CreateCondBr(overflow, overflowBB, continueBB);
 
-  // Handle overflow with llvm.trap.
-  const std::string *handlerName = 
-    &CGF.getContext().getLangOpts().OverflowHandler;
-  if (handlerName->empty()) {
-    EmitOverflowBB(overflowBB);
-    Builder.SetInsertPoint(continueBB);
-    return result;
-  }
-
   // If an overflow handler is set, then we want to call it and then use its
   // result, if it returns.
   Builder.SetInsertPoint(overflowBB);
@@ -2122,18 +2095,13 @@
 
   if (CGF.CatchUndefined && isa<llvm::IntegerType>(Ops.LHS->getType())) {
     unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
-    llvm::BasicBlock *Cont = CGF.createBasicBlock("shl.cont");
-    llvm::BasicBlock *Trap = CGF.getTrapBB();
     llvm::Value *WidthMinusOne =
       llvm::ConstantInt::get(RHS->getType(), Width - 1);
-    CGF.Builder.CreateCondBr(Builder.CreateICmpULE(RHS, WidthMinusOne),
-                             Cont, Trap);
-    CGF.EmitBlock(Cont);
+    CGF.EmitCheck(Builder.CreateICmpULE(RHS, WidthMinusOne));
 
     if (Ops.Ty->hasSignedIntegerRepresentation()) {
       // Check whether we are shifting any non-zero bits off the top of the
       // integer.
-      Cont = CGF.createBasicBlock("shl.ok");
       llvm::Value *BitsShiftedOff =
         Builder.CreateLShr(Ops.LHS,
                            Builder.CreateSub(WidthMinusOne, RHS, "shl.zeros",
@@ -2148,9 +2116,7 @@
         BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
       }
       llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
-      Builder.CreateCondBr(Builder.CreateICmpEQ(BitsShiftedOff, Zero),
-                           Cont, Trap);
-      CGF.EmitBlock(Cont);
+      CGF.EmitCheck(Builder.CreateICmpEQ(BitsShiftedOff, Zero));
     }
   }
 
@@ -2166,11 +2132,8 @@
 
   if (CGF.CatchUndefined && isa<llvm::IntegerType>(Ops.LHS->getType())) {
     unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth();
-    llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
-    CGF.Builder.CreateCondBr(Builder.CreateICmpULT(RHS,
-                                 llvm::ConstantInt::get(RHS->getType(), Width)),
-                             Cont, CGF.getTrapBB());
-    CGF.EmitBlock(Cont);
+    llvm::Value *WidthVal = llvm::ConstantInt::get(RHS->getType(), Width);
+    CGF.EmitCheck(Builder.CreateICmpULT(RHS, WidthVal));
   }
 
   if (Ops.Ty->hasUnsignedIntegerRepresentation())
@@ -2361,7 +2324,7 @@
 
   case Qualifiers::OCL_Weak:
     RHS = Visit(E->getRHS());
-    LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::CT_Store);
+    LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
     RHS = CGF.EmitARCStoreWeak(LHS.getAddress(), RHS, Ignore);
     break;
 
@@ -2371,7 +2334,7 @@
     // __block variables need to have the rhs evaluated first, plus
     // this should improve codegen just a little.
     RHS = Visit(E->getRHS());
-    LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::CT_Store);
+    LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
 
     // Store the value into the LHS.  Bit-fields are handled specially
     // because the result is altered by the store, i.e., [C99 6.5.16p1]

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=163451&r1=163450&r2=163451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Sep  7 21:08:36 2012
@@ -1835,27 +1835,27 @@
 
   /// \brief Situations in which we might emit a check for the suitability of a
   ///        pointer or glvalue.
-  enum CheckType {
+  enum TypeCheckKind {
     /// Checking the operand of a load. Must be suitably sized and aligned.
-    CT_Load,
+    TCK_Load,
     /// Checking the destination of a store. Must be suitably sized and aligned.
-    CT_Store,
+    TCK_Store,
     /// Checking the bound value in a reference binding. Must be suitably sized
     /// and aligned, but is not required to refer to an object (until the
     /// reference is used), per core issue 453.
-    CT_ReferenceBinding,
+    TCK_ReferenceBinding,
     /// Checking the object expression in a non-static data member access. Must
     /// be an object within its lifetime.
-    CT_MemberAccess,
+    TCK_MemberAccess,
     /// Checking the 'this' pointer for a call to a non-static member function.
     /// Must be an object within its lifetime.
-    CT_MemberCall
+    TCK_MemberCall
   };
 
-  /// EmitCheck - Emit a check that \p V is the address of storage of the
+  /// \brief Emit a check that \p V is the address of storage of the
   /// appropriate size and alignment for an object of type \p Type.
-  void EmitCheck(CheckType CT, llvm::Value *V,
-                 QualType Type, CharUnits Alignment = CharUnits::Zero());
+  void EmitTypeCheck(TypeCheckKind TCK, llvm::Value *V,
+                     QualType Type, CharUnits Alignment = CharUnits::Zero());
 
   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
                                        bool isInc, bool isPre);
@@ -2053,11 +2053,10 @@
   ///
   LValue EmitLValue(const Expr *E);
 
-  /// EmitCheckedLValue - Same as EmitLValue but additionally we generate
-  /// checking code to guard against undefined behavior.  This is only
-  /// suitable when we know that the address will be used to access the
-  /// object.
-  LValue EmitCheckedLValue(const Expr *E, CheckType CT);
+  /// \brief Same as EmitLValue but additionally we generate checking code to
+  /// guard against undefined behavior.  This is only suitable when we know
+  /// that the address will be used to access the object.
+  LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK);
 
   /// EmitToMemory - Change a scalar value from its value
   /// representation to its in-memory representation.
@@ -2536,9 +2535,9 @@
   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
                             llvm::BasicBlock *FalseBlock);
 
-  /// getTrapBB - Create a basic block that will call the trap intrinsic.  We'll
-  /// generate a branch around the created basic block as necessary.
-  llvm::BasicBlock *getTrapBB();
+  /// \brief Create a basic block that will call the trap intrinsic, and emit a
+  /// conditional branch to it.
+  void EmitCheck(llvm::Value *Checked);
 
   /// EmitCallArg - Emit a single call argument.
   void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);

Modified: cfe/trunk/test/CodeGen/trapv.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/trapv.c?rev=163451&r1=163450&r2=163451&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/trapv.c (original)
+++ cfe/trunk/test/CodeGen/trapv.c Fri Sep  7 21:08:36 2012
@@ -18,7 +18,8 @@
   // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 [[T2]])
   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0
   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1
-  // CHECK-NEXT: br i1 [[T5]]
+  // CHECK-NEXT: [[T6:%.*]] = xor i1 [[T5]], true
+  // CHECK-NEXT: br i1 [[T6]]
   // CHECK:      call void @llvm.trap()
   i = j + k;
 }
@@ -32,7 +33,8 @@
   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1)
   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
-  // CHECK-NEXT: br i1 [[T4]]
+  // CHECK-NEXT: [[T5:%.*]] = xor i1 [[T4]], true
+  // CHECK-NEXT: br i1 [[T5]]
   // CHECK:      call void @llvm.trap()
 }
 
@@ -45,6 +47,7 @@
   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1)
   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0
   // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1
-  // CHECK-NEXT: br i1 [[T4]]
+  // CHECK-NEXT: [[T5:%.*]] = xor i1 [[T4]], true
+  // CHECK-NEXT: br i1 [[T5]]
   // CHECK:      call void @llvm.trap()
 }





More information about the cfe-commits mailing list