<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">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="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">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>