<div dir="ltr"><div>Here is a GDB backtrace of the crasher for you:</div><div><br></div><div>Program received signal SIGSEGV, Segmentation fault.</div><div>llvm::Instruction::getParent (this=0x0) at ../include/llvm/IR/Instruction.h:54</div>
<div>54        inline       BasicBlock *getParent()       { return Parent; }</div><div>(gdb) bt</div><div>#0  llvm::Instruction::getParent (this=0x0) at ../include/llvm/IR/Instruction.h:54</div><div>#1  0x000000000100f5ca in (anonymous namespace)::CodeGenPrepare::OptimizeCallInst (this=0x2809b20, CI=0x27f3418) at ../lib/CodeGen/CodeGenPrepare.cpp:940</div>
<div>#2  0x000000000100ae14 in (anonymous namespace)::CodeGenPrepare::OptimizeInst (this=0x2809b20, I=0x27f3418) at ../lib/CodeGen/CodeGenPrepare.cpp:3294</div><div>#3  0x000000000100a5d9 in (anonymous namespace)::CodeGenPrepare::OptimizeBlock (this=0x2809b20, BB=...) at ../lib/CodeGen/CodeGenPrepare.cpp:3314</div>
<div>#4  0x00000000010095fd in (anonymous namespace)::CodeGenPrepare::runOnFunction (this=0x2809b20, F=...) at ../lib/CodeGen/CodeGenPrepare.cpp:219</div><div>#5  0x00000000013f052b in llvm::FPPassManager::runOnFunction (this=0x2801ef0, F=...) at ../lib/IR/LegacyPassManager.cpp:1540</div>
<div>#6  0x00000000013f0838 in llvm::FPPassManager::runOnModule (this=0x2801ef0, M=...) at ../lib/IR/LegacyPassManager.cpp:1560</div><div>#7  0x00000000013f0efa in (anonymous namespace)::MPPassManager::runOnModule (this=0x27eb860, M=...) at ../lib/IR/LegacyPassManager.cpp:1618</div>
<div>#8  0x00000000013f0aee in llvm::legacy::PassManagerImpl::run (this=0x27eb570, M=...) at ../lib/IR/LegacyPassManager.cpp:1725</div><div>#9  0x00000000013f13a1 in llvm::legacy::PassManager::run (this=0x7fffffffdfc0, M=...) at ../lib/IR/LegacyPassManager.cpp:1760</div>
<div>#10 0x000000000069a4bf in compileModule (argv=0x7fffffffe418, Context=...) at ../tools/llc/llc.cpp:355</div><div>#11 0x0000000000699632 in main (argc=5, argv=0x7fffffffe418) at ../tools/llc/llc.cpp:201</div><div><br>
</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Apr 21, 2014 at 12:13 AM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">This has broken roughly all of the build bots: <a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-debian-fast/builds/14859" target="_blank">http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-debian-fast/builds/14859</a><div>

<br></div><div>I'm going to revert as they've been broken for an hour now.</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Apr 20, 2014 at 10:33 PM, Michael Zolotukhin <span dir="ltr"><<a href="mailto:mzolotukhin@apple.com" target="_blank">mzolotukhin@apple.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mzolotukhin<br>
Date: Mon Apr 21 00:33:09 2014<br>
New Revision: 206732<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=206732&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=206732&view=rev</a><br>
Log:<br>
Implement builtins for safe division: <a href="http://safe.sdiv.iN" target="_blank">safe.sdiv.iN</a>, <a href="http://safe.udiv.iN" target="_blank">safe.udiv.iN</a>, <a href="http://safe.srem.iN" target="_blank">safe.srem.iN</a>,<br>


<a href="http://safe.urem.iN" target="_blank">safe.urem.iN</a> (iN = i8, i16, i32, or i64).<br>
<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll<br>
    llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll<br>
    llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll<br>
    llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics.ll<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/Intrinsics.td<br>
    llvm/trunk/include/llvm/Target/TargetLowering.h<br>
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp<br>
    llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp<br>
    llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Intrinsics.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=206732&r1=206731&r2=206732&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=206732&r1=206731&r2=206732&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)<br>
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Mon Apr 21 00:33:09 2014<br>
@@ -444,6 +444,19 @@ def int_umul_with_overflow : Intrinsic<[<br>
                                        [LLVMMatchType<0>, LLVMMatchType<0>],<br>
                                        [IntrNoMem]>;<br>
<br>
+def int_safe_udiv : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],<br>
+                              [LLVMMatchType<0>, LLVMMatchType<0>],<br>
+                              [IntrNoMem]>;<br>
+def int_safe_urem : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],<br>
+                              [LLVMMatchType<0>, LLVMMatchType<0>],<br>
+                              [IntrNoMem]>;<br>
+def int_safe_sdiv : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],<br>
+                              [LLVMMatchType<0>, LLVMMatchType<0>],<br>
+                              [IntrNoMem]>;<br>
+def int_safe_srem : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],<br>
+                              [LLVMMatchType<0>, LLVMMatchType<0>],<br>
+                              [IntrNoMem]>;<br>
+<br>
 //===------------------------- Memory Use Markers -------------------------===//<br>
 //<br>
 def int_lifetime_start  : Intrinsic<[],<br>
<br>
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=206732&r1=206731&r2=206732&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=206732&r1=206731&r2=206732&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)<br>
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon Apr 21 00:33:09 2014<br>
@@ -218,6 +218,10 @@ public:<br>
   /// Return true if pow2 div is cheaper than a chain of srl/add/sra.<br>
   bool isPow2DivCheap() const { return Pow2DivIsCheap; }<br>
<br>
+  /// Return true if Div never traps, returns 0 when div by 0 and return TMin,<br>
+  /// when sdiv TMin by -1.<br>
+  bool isDivWellDefined() const { return DivIsWellDefined; }<br>
+<br>
   /// Return true if Flow Control is an expensive operation that should be<br>
   /// avoided.<br>
   bool isJumpExpensive() const { return JumpIsExpensive; }<br>
@@ -1026,6 +1030,13 @@ protected:<br>
   /// signed divide by power of two, and let the target handle it.<br>
   void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; }<br>
<br>
+  /// Tells the code-generator that it is safe to execute sdiv/udiv/srem/urem<br>
+  /// even when RHS is 0. It is also safe to execute sdiv/srem when LHS is<br>
+  /// SignedMinValue and RHS is -1.<br>
+  void setDivIsWellDefined (bool isWellDefined = true) {<br>
+    DivIsWellDefined = isWellDefined;<br>
+  }<br>
+<br>
   /// Add the specified register class as an available regclass for the<br>
   /// specified value type. This indicates the selector can handle values of<br>
   /// that class natively.<br>
@@ -1441,6 +1452,11 @@ private:<br>
   /// signed divide by power of two, and let the target handle it.<br>
   bool Pow2DivIsCheap;<br>
<br>
+  /// Tells the code-generator that it is safe to execute sdiv/udiv/srem/urem<br>
+  /// even when RHS is 0. It is also safe to execute sdiv/srem when LHS is<br>
+  /// SignedMinValue and RHS is -1.<br>
+  bool DivIsWellDefined;<br>
+<br>
   /// Tells the code generator that it shouldn't generate extra flow control<br>
   /// instructions and should attempt to combine flow control instructions via<br>
   /// predication.<br>
<br>
Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=206732&r1=206731&r2=206732&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=206732&r1=206731&r2=206732&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Mon Apr 21 00:33:09 2014<br>
@@ -688,6 +688,293 @@ bool CodeGenPrepare::OptimizeCallInst(Ca<br>
     }<br>
     return true;<br>
   }<br>
+  // Lower all uses of llvm.safe.[us]{div|rem}...<br>
+  if (II &&<br>
+      (II->getIntrinsicID() == Intrinsic::safe_sdiv ||<br>
+       II->getIntrinsicID() == Intrinsic::safe_udiv ||<br>
+       II->getIntrinsicID() == Intrinsic::safe_srem ||<br>
+       II->getIntrinsicID() == Intrinsic::safe_urem)) {<br>
+    // Given<br>
+    //   result_struct = type {iN, i1}<br>
+    //   %R = call result_struct <a href="http://llvm.safe.sdiv.iN" target="_blank">llvm.safe.sdiv.iN</a>(iN %x, iN %y)<br>
+    // Expand it to actual IR, which produces result to the same variable %R.<br>
+    // First element of the result %R.1 is the result of division, second<br>
+    // element shows whether the division was correct or not.<br>
+    // If %y is 0, %R.1 is 0, %R.2 is 1.                            (1)<br>
+    // If %x is minSignedValue and %y is -1, %R.1 is %x, %R.2 is 1. (2)<br>
+    // In other cases %R.1 is (sdiv %x, %y), %R.2 is 0.             (3)<br>
+    //<br>
+    // Similar applies to srem, udiv, and urem builtins, except that in unsigned<br>
+    // variants we don't check condition (2).<br>
+<br>
+    bool IsSigned;<br>
+    BinaryOperator::BinaryOps Op;<br>
+    switch (II->getIntrinsicID()) {<br>
+      case Intrinsic::safe_sdiv:<br>
+        IsSigned = true;<br>
+        Op = Instruction::SDiv;<br>
+        break;<br>
+      case Intrinsic::safe_udiv:<br>
+        IsSigned = false;<br>
+        Op = Instruction::UDiv;<br>
+        break;<br>
+      case Intrinsic::safe_srem:<br>
+        IsSigned = true;<br>
+        Op = Instruction::SRem;<br>
+        break;<br>
+      case Intrinsic::safe_urem:<br>
+        IsSigned = false;<br>
+        Op = Instruction::URem;<br>
+        break;<br>
+      default:<br>
+        llvm_unreachable("Only Div/Rem intrinsics are handled here.");<br>
+    }<br>
+<br>
+    Value *LHS = II->getOperand(0), *RHS = II->getOperand(1);<br>
+    bool DivWellDefined = TLI && TLI->isDivWellDefined();<br>
+<br>
+    bool ResultNeeded[2] = {false, false};<br>
+    SmallVector<User*, 1> ResultsUsers[2];<br>
+    bool BadCase = false;<br>
+    for (User *U: II->users()) {<br>
+      ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(U);<br>
+      if (!EVI || EVI->getNumIndices() > 1 || EVI->getIndices()[0] > 1) {<br>
+        BadCase = true;<br>
+        break;<br>
+      }<br>
+      ResultNeeded[EVI->getIndices()[0]] = true;<br>
+      ResultsUsers[EVI->getIndices()[0]].push_back(U);<br>
+    }<br>
+    // Behave conservatively, if there is an unusual user of the results.<br>
+    if (BadCase)<br>
+      ResultNeeded[0] = ResultNeeded[1] = true;<br>
+<br>
+    // Early exit if non of the results is ever used.<br>
+    if (!ResultNeeded[0] && !ResultNeeded[1]) {<br>
+      II->eraseFromParent();<br>
+      return true;<br>
+    }<br>
+<br>
+    // Early exit if the second result (flag) isn't used and target<br>
+    // div-instruction computes exactly what we want to get as the first result<br>
+    // and never traps.<br>
+    if (ResultNeeded[0] && !ResultNeeded[1] && DivWellDefined) {<br>
+      BinaryOperator *Div = BinaryOperator::Create(Op, LHS, RHS);<br>
+      Div->insertAfter(II);<br>
+      for (User *U: ResultsUsers[0]) {<br>
+        Instruction *UserInst = dyn_cast<Instruction>(U);<br>
+        assert(UserInst && "Unexpected null-instruction");<br>
+        UserInst->replaceAllUsesWith(Div);<br>
+        UserInst->eraseFromParent();<br>
+      }<br>
+      II->eraseFromParent();<br>
+      CurInstIterator = Div;<br>
+      ModifiedDT = true;<br>
+      return true;<br>
+    }<br>
+<br>
+    // Check if the flag is used to jump out to a 'trap' block<br>
+    // If it's the case, we want to use this block directly when we create<br>
+    // branches after comparing with 0 and comparing with -1 (signed case).<br>
+    // We can do it only iff we can track all the uses of the flag, i.e. the<br>
+    // only users are EXTRACTVALUE-insns, and their users are conditional<br>
+    // branches, targeting the same 'trap' basic block.<br>
+    BasicBlock *TrapBB = nullptr;<br>
+    bool DoRelinkTrap = true;<br>
+    for (User *FlagU: ResultsUsers[1]) {<br>
+      for (User *U: FlagU->users()) {<br>
+        BranchInst *TrapBranch = dyn_cast<BranchInst>(U);<br>
+        // If the user isn't a branch-insn, or it jumps to another BB, don't<br>
+        // try to use TrapBB in the lowering.<br>
+        if (!TrapBranch || (TrapBB && TrapBB != TrapBranch->getSuccessor(0))) {<br>
+          DoRelinkTrap = false;<br>
+          break;<br>
+        }<br>
+        TrapBB = TrapBranch->getSuccessor(0);<br>
+      }<br>
+    }<br>
+    if (!TrapBB)<br>
+      DoRelinkTrap = false;<br>
+    // We want to reuse TrapBB if possible, because in that case we can avoid<br>
+    // creating new basic blocks and thus overcomplicating the IR. However, if<br>
+    // DIV instruction isn't well defined, we still need those blocks to model<br>
+    // well-defined behaviour. Thus, we can't reuse TrapBB in this case.<br>
+    if (!DivWellDefined)<br>
+      DoRelinkTrap = false;<br>
+<br>
+    Value *MinusOne = Constant::getAllOnesValue(LHS->getType());<br>
+    Value *Zero = Constant::getNullValue(LHS->getType());<br>
+<br>
+    // Split the original BB and create other basic blocks that will be used<br>
+    // for checks.<br>
+    BasicBlock *StartBB = II->getParent();<br>
+    BasicBlock::iterator SplitPt = ++(BasicBlock::iterator(II));<br>
+    BasicBlock *NextBB = StartBB->splitBasicBlock(SplitPt, "div.end");<br>
+<br>
+    BasicBlock *DivByZeroBB;<br>
+    if (!DoRelinkTrap) {<br>
+      DivByZeroBB = BasicBlock::Create(II->getContext(), "div.divz",<br>
+                                       NextBB->getParent(), NextBB);<br>
+      BranchInst::Create(NextBB, DivByZeroBB);<br>
+    }<br>
+    BasicBlock *DivBB = BasicBlock::Create(II->getContext(), "div.div",<br>
+                                           NextBB->getParent(), NextBB);<br>
+    BranchInst::Create(NextBB, DivBB);<br>
+<br>
+    // For signed variants, check the condition (2):<br>
+    // LHS == SignedMinValue, RHS == -1.<br>
+    Value *CmpMinusOne;<br>
+    Value *CmpMinValue;<br>
+    BasicBlock *ChkDivMinBB;<br>
+    BasicBlock *DivMinBB;<br>
+    Value *MinValue;<br>
+    if (IsSigned) {<br>
+      APInt SignedMinValue =<br>
+        APInt::getSignedMinValue(LHS->getType()->getPrimitiveSizeInBits());<br>
+      MinValue = Constant::getIntegerValue(LHS->getType(), SignedMinValue);<br>
+      ChkDivMinBB = BasicBlock::Create(II->getContext(), "div.chkdivmin",<br>
+                                       NextBB->getParent(), NextBB);<br>
+      BranchInst::Create(NextBB, ChkDivMinBB);<br>
+      if (!DoRelinkTrap) {<br>
+        DivMinBB = BasicBlock::Create(II->getContext(), "div.divmin",<br>
+                                      NextBB->getParent(), NextBB);<br>
+        BranchInst::Create(NextBB, DivMinBB);<br>
+      }<br>
+      CmpMinusOne = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ,<br>
+                                    RHS, MinusOne, "cmp.rhs.minus.one",<br>
+                                    ChkDivMinBB->getTerminator());<br>
+      CmpMinValue = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ,<br>
+                                    LHS, MinValue, "cmp.lhs.signed.min",<br>
+                                    ChkDivMinBB->getTerminator());<br>
+      BinaryOperator *CmpSignedOvf = BinaryOperator::Create(Instruction::And,<br>
+                                                            CmpMinusOne,<br>
+                                                            CmpMinValue);<br>
+      // Here we're interested in the case when both %x is TMin and %y is -1.<br>
+      // In this case the result will overflow.<br>
+      // If that's not the case, we can perform usual division. These blocks<br>
+      // will be inserted after DivByZero, so the division will be safe.<br>
+      CmpSignedOvf->insertBefore(ChkDivMinBB->getTerminator());<br>
+      BranchInst::Create(DoRelinkTrap ? TrapBB : DivMinBB, DivBB, CmpSignedOvf,<br>
+                         ChkDivMinBB->getTerminator());<br>
+      ChkDivMinBB->getTerminator()->eraseFromParent();<br>
+    }<br>
+<br>
+    // Check the condition (1):<br>
+    // RHS == 0.<br>
+    Value *CmpDivZero = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ,<br>
+                                        RHS, Zero, "cmp.rhs.zero",<br>
+                                        StartBB->getTerminator());<br>
+<br>
+    // If RHS != 0, we want to check condition (2) in signed case, or proceed<br>
+    // to usual division in unsigned case.<br>
+    BranchInst::Create(DoRelinkTrap ? TrapBB : DivByZeroBB,<br>
+                       IsSigned ? ChkDivMinBB : DivBB, CmpDivZero,<br>
+                       StartBB->getTerminator());<br>
+    StartBB->getTerminator()->eraseFromParent();<br>
+<br>
+    // At the moment we have all the control flow created. We just need to<br>
+    // insert DIV and PHI (if needed) to get the result value.<br>
+    Instruction *DivRes, *FlagRes;<br>
+    Instruction *InsPoint = nullptr;<br>
+    if (ResultNeeded[0]) {<br>
+      BinaryOperator *Div = BinaryOperator::Create(Op, LHS, RHS);<br>
+      if (DivWellDefined) {<br>
+        // The result value is the result of DIV operation placed right at the<br>
+        // original place of the intrinsic.<br>
+        Div->insertAfter(II);<br>
+        DivRes = Div;<br>
+      } else {<br>
+        // The result is a PHI-node.<br>
+        Div->insertBefore(DivBB->getTerminator());<br>
+        PHINode *DivResPN =<br>
+          PHINode::Create(LHS->getType(), IsSigned ? 3 : 2, "div.res.phi",<br>
+                          NextBB->begin());<br>
+        DivResPN->addIncoming(Div, DivBB);<br>
+        DivResPN->addIncoming(Zero, DivByZeroBB);<br>
+        if (IsSigned)<br>
+          DivResPN->addIncoming(MinValue, DivMinBB);<br>
+        DivRes = DivResPN;<br>
+        InsPoint = DivResPN;<br>
+      }<br>
+    }<br>
+<br>
+    // Prepare a value for the second result (flag) if it is needed.<br>
+    if (ResultNeeded[1] && !DoRelinkTrap) {<br>
+      Type *FlagTy = II->getType()->getStructElementType(1);<br>
+      PHINode *FlagResPN =<br>
+        PHINode::Create(FlagTy, IsSigned ? 3 : 2, "div.flag.phi",<br>
+                        NextBB->begin());<br>
+      FlagResPN->addIncoming(Constant::getNullValue(FlagTy), DivBB);<br>
+      FlagResPN->addIncoming(Constant::getAllOnesValue(FlagTy), DivByZeroBB);<br>
+      if (IsSigned)<br>
+        FlagResPN->addIncoming(Constant::getAllOnesValue(FlagTy), DivMinBB);<br>
+      FlagRes = FlagResPN;<br>
+      if (!InsPoint)<br>
+        InsPoint = FlagRes;<br>
+    }<br>
+<br>
+    // If possible, propagate the results to the user. Otherwise, create alloca,<br>
+    // and create a struct with the results on stack.<br>
+    if (!BadCase) {<br>
+      if (ResultNeeded[0]) {<br>
+        for (User *U: ResultsUsers[0]) {<br>
+          Instruction *UserInst = dyn_cast<Instruction>(U);<br>
+          assert(UserInst && "Unexpected null-instruction");<br>
+          UserInst->replaceAllUsesWith(DivRes);<br>
+          UserInst->eraseFromParent();<br>
+        }<br>
+      }<br>
+      if (ResultNeeded[1]) {<br>
+        for (User *FlagU: ResultsUsers[1]) {<br>
+          Instruction *FlagUInst = dyn_cast<Instruction>(FlagU);<br>
+          if (DoRelinkTrap) {<br>
+            // Replace<br>
+            //   %flag = extractvalue %intrinsic.res, 1<br>
+            //   br i1 %flag, label %<a href="http://trap.bb" target="_blank">trap.bb</a>, label %<a href="http://other.bb" target="_blank">other.bb</a><br>
+            // With<br>
+            //   br label %<a href="http://other.bb" target="_blank">other.bb</a><br>
+            // We've already created checks that are pointing to %<a href="http://trap.bb" target="_blank">trap.bb</a>, there<br>
+            // is no need to have the same checks here.<br>
+            for (User *U: FlagUInst->users()) {<br>
+              BranchInst *TrapBranch = dyn_cast<BranchInst>(U);<br>
+              BasicBlock *CurBB = TrapBranch->getParent();<br>
+              BasicBlock *SuccessorBB = TrapBranch->getSuccessor(1);<br>
+              CurBB->getTerminator()->eraseFromParent();<br>
+              BranchInst::Create(SuccessorBB, CurBB);<br>
+            }<br>
+          } else {<br>
+            FlagUInst->replaceAllUsesWith(FlagRes);<br>
+          }<br>
+          dyn_cast<Instruction>(FlagUInst)->eraseFromParent();<br>
+        }<br>
+      }<br>
+    } else {<br>
+      // Create alloca, store our new values to it, and then load the final<br>
+      // result from it.<br>
+      Constant *Idx0 = ConstantInt::get(Type::getInt32Ty(II->getContext()), 0);<br>
+      Constant *Idx1 = ConstantInt::get(Type::getInt32Ty(II->getContext()), 1);<br>
+      Value *Idxs_DivRes[2] = {Idx0, Idx0};<br>
+      Value *Idxs_FlagRes[2] = {Idx0, Idx1};<br>
+      Value *NewRes = new llvm::AllocaInst(II->getType(), 0, "div.res.ptr", II);<br>
+      Instruction *ResDivAddr = GetElementPtrInst::Create(NewRes, Idxs_DivRes);<br>
+      Instruction *ResFlagAddr =<br>
+        GetElementPtrInst::Create(NewRes, Idxs_FlagRes);<br>
+      ResDivAddr->insertAfter(InsPoint);<br>
+      ResFlagAddr->insertAfter(ResDivAddr);<br>
+      StoreInst *StoreResDiv = new StoreInst(DivRes, ResDivAddr);<br>
+      StoreInst *StoreResFlag = new StoreInst(FlagRes, ResFlagAddr);<br>
+      StoreResDiv->insertAfter(ResFlagAddr);<br>
+      StoreResFlag->insertAfter(StoreResDiv);<br>
+      LoadInst *LoadRes = new LoadInst(NewRes, "div.res");<br>
+      LoadRes->insertAfter(StoreResFlag);<br>
+      II->replaceAllUsesWith(LoadRes);<br>
+    }<br>
+<br>
+    II->eraseFromParent();<br>
+    CurInstIterator = StartBB->end();<br>
+    ModifiedDT = true;<br>
+    return true;<br>
+  }<br>
<br>
   if (II && TLI) {<br>
     SmallVector<Value*, 2> PtrOps;<br>
<br>
Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=206732&r1=206731&r2=206732&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=206732&r1=206731&r2=206732&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Mon Apr 21 00:33:09 2014<br>
@@ -682,6 +682,7 @@ TargetLoweringBase::TargetLoweringBase(c<br>
   HasMultipleConditionRegisters = false;<br>
   IntDivIsCheap = false;<br>
   Pow2DivIsCheap = false;<br>
+  DivIsWellDefined = false;<br>
   JumpIsExpensive = false;<br>
   PredictableSelectIsExpensive = false;<br>
   MaskAndBranchFoldingIsLegal = false;<br>
<br>
Modified: llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp?rev=206732&r1=206731&r2=206732&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp?rev=206732&r1=206731&r2=206732&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM64/ARM64ISelLowering.cpp Mon Apr 21 00:33:09 2014<br>
@@ -435,6 +435,8 @@ ARM64TargetLowering::ARM64TargetLowering<br>
<br>
   setMinFunctionAlignment(2);<br>
<br>
+  setDivIsWellDefined(true);<br>
+<br>
   RequireStrictAlign = StrictAlign;<br>
 }<br>
<br>
<br>
Added: llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll?rev=206732&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll?rev=206732&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll (added)<br>
+++ llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll Mon Apr 21 00:33:09 2014<br>
@@ -0,0 +1,112 @@<br>
+; RUN: llc < %s -march=arm64 | FileCheck %s<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+<br>
+%divovf32 = type { i32, i1 }<br>
+<br>
+declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone<br>
+declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone<br>
+<br>
+; CHECK-LABEL: sdiv32_results_unused<br>
+; CHECK: entry<br>
+; CHECK-NEXT: ret<br>
+define void @sdiv32_results_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_div_result_unused<br>
+; CHECK-NOT: sdiv{{[    ]}}<br>
+define i1 @sdiv32_div_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  ret i1 %bit<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_flag_result_unused<br>
+; CHECK-NOT: cb<br>
+; CHECK: sdiv{{[        ]}}<br>
+define i32 @sdiv32_flag_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  ret i32 %div<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_result_returned<br>
+; CHECK: sdiv{{[        ]}}<br>
+define %divovf32 @sdiv32_result_returned(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_trap_relinked<br>
+; CHECK-NOT: %div.divmin<br>
+; CHECK-NOT: %div.divz<br>
+define i32 @sdiv32_trap_relinked(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  br i1 %bit, label %<a href="http://trap.bb" target="_blank">trap.bb</a>, label %<a href="http://ok.bb" target="_blank">ok.bb</a><br>
+<a href="http://trap.bb" target="_blank">trap.bb</a>:<br>
+  ret i32 7<br>
+<a href="http://ok.bb" target="_blank">ok.bb</a>:<br>
+  ret i32 %div<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_results_unused<br>
+; CHECK: entry<br>
+; CHECK-NEXT: ret<br>
+define void @udiv32_results_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_div_result_unused<br>
+; CHECK-NOT: udiv{{[    ]}}<br>
+define i1 @udiv32_div_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  ret i1 %bit<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_flag_result_unused<br>
+; CHECK-NOT: cb<br>
+; CHECK: udiv{{[        ]}}<br>
+define i32 @udiv32_flag_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  ret i32 %div<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_result_returned<br>
+; CHECK: udiv{{[        ]}}<br>
+define %divovf32 @udiv32_result_returned(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_trap_relinked<br>
+; CHECK-NOT: %div.divz<br>
+define i32 @udiv32_trap_relinked(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  br i1 %bit, label %<a href="http://trap.bb" target="_blank">trap.bb</a>, label %<a href="http://ok.bb" target="_blank">ok.bb</a><br>
+<a href="http://trap.bb" target="_blank">trap.bb</a>:<br>
+  ret i32 7<br>
+<a href="http://ok.bb" target="_blank">ok.bb</a>:<br>
+  ret i32 %div<br>
+}<br>
+<br>
+!llvm.ident = !{!0}<br>
+<br>
+!0 = metadata !{metadata !"clang version 3.5.0 "}<br>
<br>
Added: llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll?rev=206732&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll?rev=206732&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll (added)<br>
+++ llvm/trunk/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll Mon Apr 21 00:33:09 2014<br>
@@ -0,0 +1,152 @@<br>
+; RUN: llc < %s -march=arm64 | FileCheck %s<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+<br>
+%divovf8  = type { i8, i1 }<br>
+%divovf16 = type { i16, i1 }<br>
+%divovf32 = type { i32, i1 }<br>
+%divovf64 = type { i64, i1 }<br>
+<br>
+declare %divovf8  @llvm.safe.sdiv.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.sdiv.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.sdiv.i64(i64, i64) nounwind readnone<br>
+<br>
+declare %divovf8  @llvm.safe.srem.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.srem.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.srem.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.srem.i64(i64, i64) nounwind readnone<br>
+<br>
+declare %divovf8  @llvm.safe.udiv.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.udiv.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.udiv.i64(i64, i64) nounwind readnone<br>
+<br>
+declare %divovf8  @llvm.safe.urem.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.urem.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.urem.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.urem.i64(i64, i64) nounwind readnone<br>
+<br>
+; CHECK-LABEL: sdiv8<br>
+; CHECK: sdiv{{[       ]}}<br>
+define %divovf8 @sdiv8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %divr = call %divovf8 @llvm.safe.sdiv.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %divr<br>
+}<br>
+; CHECK-LABEL: sdiv16<br>
+; CHECK: sdiv{{[       ]}}<br>
+define %divovf16 @sdiv16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %divr = call %divovf16 @llvm.safe.sdiv.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %divr<br>
+}<br>
+; CHECK-LABEL: sdiv32<br>
+; CHECK: sdiv{{[       ]}}<br>
+define %divovf32 @sdiv32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+; CHECK-LABEL: sdiv64<br>
+; CHECK: sdiv{{[       ]}}<br>
+define %divovf64 @sdiv64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %divr = call %divovf64 @llvm.safe.sdiv.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %divr<br>
+}<br>
+; CHECK-LABEL: udiv8<br>
+; CHECK: udiv{{[       ]}}<br>
+define %divovf8 @udiv8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %divr = call %divovf8 @llvm.safe.udiv.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %divr<br>
+}<br>
+; CHECK-LABEL: udiv16<br>
+; CHECK: udiv{{[       ]}}<br>
+define %divovf16 @udiv16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %divr = call %divovf16 @llvm.safe.udiv.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %divr<br>
+}<br>
+; CHECK-LABEL: udiv32<br>
+; CHECK: udiv{{[       ]}}<br>
+define %divovf32 @udiv32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+; CHECK-LABEL: udiv64<br>
+; CHECK: udiv{{[       ]}}<br>
+define %divovf64 @udiv64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %divr = call %divovf64 @llvm.safe.udiv.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %divr<br>
+}<br>
+; CHECK-LABEL: srem8<br>
+; CHECK: sdiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf8 @srem8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %remr = call %divovf8 @llvm.safe.srem.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %remr<br>
+}<br>
+; CHECK-LABEL: srem16<br>
+; CHECK: sdiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf16 @srem16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %remr = call %divovf16 @llvm.safe.srem.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %remr<br>
+}<br>
+; CHECK-LABEL: srem32<br>
+; CHECK: sdiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf32 @srem32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %remr = call %divovf32 @llvm.safe.srem.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %remr<br>
+}<br>
+; CHECK-LABEL: srem64<br>
+; CHECK: sdiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf64 @srem64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %remr = call %divovf64 @llvm.safe.srem.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %remr<br>
+}<br>
+; CHECK-LABEL: urem8<br>
+; CHECK: udiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf8 @urem8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %remr = call %divovf8 @llvm.safe.urem.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %remr<br>
+}<br>
+; CHECK-LABEL: urem16<br>
+; CHECK: udiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf16 @urem16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %remr = call %divovf16 @llvm.safe.urem.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %remr<br>
+}<br>
+; CHECK-LABEL: urem32<br>
+; CHECK: udiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf32 @urem32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %remr = call %divovf32 @llvm.safe.urem.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %remr<br>
+}<br>
+; CHECK-LABEL: urem64<br>
+; CHECK: udiv{{[       ]}}<br>
+; CHECK: msub{{[       ]}}<br>
+define %divovf64 @urem64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %remr = call %divovf64 @llvm.safe.urem.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %remr<br>
+}<br>
+<br>
+!llvm.ident = !{!0}<br>
+<br>
+!0 = metadata !{metadata !"clang version 3.5.0 "}<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll?rev=206732&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll?rev=206732&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll Mon Apr 21 00:33:09 2014<br>
@@ -0,0 +1,110 @@<br>
+; RUN: llc < %s | FileCheck %s<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+<br>
+%divovf32 = type { i32, i1 }<br>
+<br>
+declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone<br>
+declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone<br>
+<br>
+; CHECK-LABEL: sdiv32_results_unused<br>
+; CHECK: entry<br>
+; CHECK-NEXT: ret<br>
+define void @sdiv32_results_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_div_result_unused<br>
+; CHECK-NOT: idiv<br>
+define i1 @sdiv32_div_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  ret i1 %bit<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_flag_result_unused<br>
+; CHECK: idiv<br>
+define i32 @sdiv32_flag_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  ret i32 %div<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_result_returned<br>
+; CHECK: idiv<br>
+define %divovf32 @sdiv32_result_returned(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+<br>
+; CHECK-LABEL: sdiv32_trap_relinked<br>
+; CHECK: %div.div{{min|z}}<br>
+define i32 @sdiv32_trap_relinked(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  br i1 %bit, label %<a href="http://trap.bb" target="_blank">trap.bb</a>, label %<a href="http://ok.bb" target="_blank">ok.bb</a><br>
+<a href="http://trap.bb" target="_blank">trap.bb</a>:<br>
+  ret i32 7<br>
+<a href="http://ok.bb" target="_blank">ok.bb</a>:<br>
+  ret i32 %div<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_results_unused<br>
+; CHECK: entry<br>
+; CHECK-NEXT: ret<br>
+define void @udiv32_results_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_div_result_unused<br>
+; CHECK-NOT: udiv{{[    ]}}<br>
+define i1 @udiv32_div_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  ret i1 %bit<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_flag_result_unused<br>
+; CHECK-NOT: cb<br>
+; CHECK: {{[   ]}}div<br>
+define i32 @udiv32_flag_result_unused(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  ret i32 %div<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_result_returned<br>
+; CHECK: {{[   ]}}div<br>
+define %divovf32 @udiv32_result_returned(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+<br>
+; CHECK-LABEL: udiv32_trap_relinked<br>
+; CHECK: %div.divz<br>
+define i32 @udiv32_trap_relinked(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  %div = extractvalue %divovf32 %divr, 0<br>
+  %bit = extractvalue %divovf32 %divr, 1<br>
+  br i1 %bit, label %<a href="http://trap.bb" target="_blank">trap.bb</a>, label %<a href="http://ok.bb" target="_blank">ok.bb</a><br>
+<a href="http://trap.bb" target="_blank">trap.bb</a>:<br>
+  ret i32 7<br>
+<a href="http://ok.bb" target="_blank">ok.bb</a>:<br>
+  ret i32 %div<br>
+}<br>
+<br>
+!llvm.ident = !{!0}<br>
+<br>
+!0 = metadata !{metadata !"clang version 3.5.0 "}<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics.ll?rev=206732&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics.ll?rev=206732&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/SafeDivRemIntrinsics.ll Mon Apr 21 00:33:09 2014<br>
@@ -0,0 +1,144 @@<br>
+; RUN: llc < %s | FileCheck %s<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+<br>
+%divovf8  = type { i8, i1 }<br>
+%divovf16 = type { i16, i1 }<br>
+%divovf32 = type { i32, i1 }<br>
+%divovf64 = type { i64, i1 }<br>
+<br>
+declare %divovf8  @llvm.safe.sdiv.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.sdiv.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.sdiv.i64(i64, i64) nounwind readnone<br>
+<br>
+declare %divovf8  @llvm.safe.srem.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.srem.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.srem.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.srem.i64(i64, i64) nounwind readnone<br>
+<br>
+declare %divovf8  @llvm.safe.udiv.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.udiv.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.udiv.i64(i64, i64) nounwind readnone<br>
+<br>
+declare %divovf8  @llvm.safe.urem.i8(i8, i8) nounwind readnone<br>
+declare %divovf16 @llvm.safe.urem.i16(i16, i16) nounwind readnone<br>
+declare %divovf32 @llvm.safe.urem.i32(i32, i32) nounwind readnone<br>
+declare %divovf64 @llvm.safe.urem.i64(i64, i64) nounwind readnone<br>
+<br>
+; CHECK-LABEL: sdiv8<br>
+; CHECK: idivb{{[      ]}}<br>
+define %divovf8 @sdiv8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %divr = call %divovf8 @llvm.safe.sdiv.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %divr<br>
+}<br>
+; CHECK-LABEL: sdiv16<br>
+; CHECK: idivw{{[      ]}}<br>
+define %divovf16 @sdiv16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %divr = call %divovf16 @llvm.safe.sdiv.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %divr<br>
+}<br>
+; CHECK-LABEL: sdiv32<br>
+; CHECK: idivl{{[      ]}}<br>
+define %divovf32 @sdiv32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+; CHECK-LABEL: sdiv64<br>
+; CHECK: idivq{{[      ]}}<br>
+define %divovf64 @sdiv64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %divr = call %divovf64 @llvm.safe.sdiv.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %divr<br>
+}<br>
+; CHECK-LABEL: udiv8<br>
+; CHECK: {{[   ]}}divb{{[      ]}}<br>
+define %divovf8 @udiv8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %divr = call %divovf8 @llvm.safe.udiv.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %divr<br>
+}<br>
+; CHECK-LABEL: udiv16<br>
+; CHECK: {{[   ]}}divw{{[      ]}}<br>
+define %divovf16 @udiv16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %divr = call %divovf16 @llvm.safe.udiv.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %divr<br>
+}<br>
+; CHECK-LABEL: udiv32<br>
+; CHECK: {{[   ]}}divl{{[      ]}}<br>
+define %divovf32 @udiv32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %divr<br>
+}<br>
+; CHECK-LABEL: udiv64<br>
+; CHECK: {{[   ]}}divq{{[      ]}}<br>
+define %divovf64 @udiv64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %divr = call %divovf64 @llvm.safe.udiv.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %divr<br>
+}<br>
+; CHECK-LABEL: srem8<br>
+; CHECK: idivb{{[      ]}}<br>
+define %divovf8 @srem8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %remr = call %divovf8 @llvm.safe.srem.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %remr<br>
+}<br>
+; CHECK-LABEL: srem16<br>
+; CHECK: idivw{{[      ]}}<br>
+define %divovf16 @srem16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %remr = call %divovf16 @llvm.safe.srem.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %remr<br>
+}<br>
+; CHECK-LABEL: srem32<br>
+; CHECK: idivl{{[      ]}}<br>
+define %divovf32 @srem32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %remr = call %divovf32 @llvm.safe.srem.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %remr<br>
+}<br>
+; CHECK-LABEL: srem64<br>
+; CHECK: idivq{{[      ]}}<br>
+define %divovf64 @srem64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %remr = call %divovf64 @llvm.safe.srem.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %remr<br>
+}<br>
+; CHECK-LABEL: urem8<br>
+; CHECK: {{[   ]}}divb{{[      ]}}<br>
+define %divovf8 @urem8(i8 %x, i8 %y) {<br>
+entry:<br>
+  %remr = call %divovf8 @llvm.safe.urem.i8(i8 %x, i8 %y)<br>
+  ret %divovf8 %remr<br>
+}<br>
+; CHECK-LABEL: urem16<br>
+; CHECK: {{[   ]}}divw{{[      ]}}<br>
+define %divovf16 @urem16(i16 %x, i16 %y) {<br>
+entry:<br>
+  %remr = call %divovf16 @llvm.safe.urem.i16(i16 %x, i16 %y)<br>
+  ret %divovf16 %remr<br>
+}<br>
+; CHECK-LABEL: urem32<br>
+; CHECK: {{[   ]}}divl{{[      ]}}<br>
+define %divovf32 @urem32(i32 %x, i32 %y) {<br>
+entry:<br>
+  %remr = call %divovf32 @llvm.safe.urem.i32(i32 %x, i32 %y)<br>
+  ret %divovf32 %remr<br>
+}<br>
+; CHECK-LABEL: urem64<br>
+; CHECK: {{[   ]}}divq{{[      ]}}<br>
+define %divovf64 @urem64(i64 %x, i64 %y) {<br>
+entry:<br>
+  %remr = call %divovf64 @llvm.safe.urem.i64(i64 %x, i64 %y)<br>
+  ret %divovf64 %remr<br>
+}<br>
+<br>
+!llvm.ident = !{!0}<br>
+<br>
+!0 = metadata !{metadata !"clang version 3.5.0 "}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>