From: Michael Zolotukhin Date: Sat, 26 Apr 2014 09:56:41 +0000 (+0000) Subject: Revert r206749 till a final decision about the intrinsics is made. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=abd7ca070636a7132344165db834f1d006554e4a Revert r206749 till a final decision about the intrinsics is made. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207313 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index c65b86f5b70..6a48f173935 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -444,19 +444,6 @@ def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; -def int_safe_udiv : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem]>; -def int_safe_urem : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem]>; -def int_safe_sdiv : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem]>; -def int_safe_srem : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], - [LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem]>; - //===------------------------- Memory Use Markers -------------------------===// // def int_lifetime_start : Intrinsic<[], diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index c17416dfee9..8dba94fc272 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -221,10 +221,6 @@ public: /// Return true if pow2 div is cheaper than a chain of srl/add/sra. bool isPow2DivCheap() const { return Pow2DivIsCheap; } - /// Return true if Div never traps, returns 0 when div by 0 and return TMin, - /// when sdiv TMin by -1. - bool isDivWellDefined() const { return DivIsWellDefined; } - /// Return true if Flow Control is an expensive operation that should be /// avoided. bool isJumpExpensive() const { return JumpIsExpensive; } @@ -1041,13 +1037,6 @@ protected: /// signed divide by power of two, and let the target handle it. void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; } - /// Tells the code-generator that it is safe to execute sdiv/udiv/srem/urem - /// even when RHS is 0. It is also safe to execute sdiv/srem when LHS is - /// SignedMinValue and RHS is -1. - void setDivIsWellDefined (bool isWellDefined = true) { - DivIsWellDefined = isWellDefined; - } - /// Add the specified register class as an available regclass for the /// specified value type. This indicates the selector can handle values of /// that class natively. @@ -1469,11 +1458,6 @@ private: /// signed divide by power of two, and let the target handle it. bool Pow2DivIsCheap; - /// Tells the code-generator that it is safe to execute sdiv/udiv/srem/urem - /// even when RHS is 0. It is also safe to execute sdiv/srem when LHS is - /// SignedMinValue and RHS is -1. - bool DivIsWellDefined; - /// Tells the code generator that it shouldn't generate extra flow control /// instructions and should attempt to combine flow control instructions via /// predication. diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index 875615c4c3e..ff2459df87e 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/lib/CodeGen/CodeGenPrepare.cpp @@ -870,242 +870,6 @@ bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) { } return true; } - // Lower all uses of llvm.safe.[us]{div|rem}... - if (II && - (II->getIntrinsicID() == Intrinsic::safe_sdiv || - II->getIntrinsicID() == Intrinsic::safe_udiv || - II->getIntrinsicID() == Intrinsic::safe_srem || - II->getIntrinsicID() == Intrinsic::safe_urem)) { - // Given - // result_struct = type {iN, i1} - // %R = call result_struct llvm.safe.sdiv.iN(iN %x, iN %y) - // Expand it to actual IR, which produces result to the same variable %R. - // First element of the result %R.1 is the result of division, second - // element shows whether the division was correct or not. - // If %y is 0, %R.1 is 0, %R.2 is 1. (1) - // If %x is minSignedValue and %y is -1, %R.1 is %x, %R.2 is 1. (2) - // In other cases %R.1 is (sdiv %x, %y), %R.2 is 0. (3) - // - // Similar applies to srem, udiv, and urem builtins, except that in unsigned - // variants we don't check condition (2). - - bool IsSigned; - BinaryOperator::BinaryOps Op; - switch (II->getIntrinsicID()) { - case Intrinsic::safe_sdiv: - IsSigned = true; - Op = Instruction::SDiv; - break; - case Intrinsic::safe_udiv: - IsSigned = false; - Op = Instruction::UDiv; - break; - case Intrinsic::safe_srem: - IsSigned = true; - Op = Instruction::SRem; - break; - case Intrinsic::safe_urem: - IsSigned = false; - Op = Instruction::URem; - break; - default: - llvm_unreachable("Only Div/Rem intrinsics are handled here."); - } - - Value *LHS = II->getOperand(0), *RHS = II->getOperand(1); - bool DivWellDefined = TLI && TLI->isDivWellDefined(); - - bool ResultNeeded[2] = {false, false}; - SmallVector ResultsUsers[2]; - bool BadCase = false; - for (User *U: II->users()) { - ExtractValueInst *EVI = dyn_cast(U); - if (!EVI || EVI->getNumIndices() > 1 || EVI->getIndices()[0] > 1) { - BadCase = true; - break; - } - ResultNeeded[EVI->getIndices()[0]] = true; - ResultsUsers[EVI->getIndices()[0]].push_back(U); - } - // Behave conservatively, if there is an unusual user of the results. - if (BadCase) - ResultNeeded[0] = ResultNeeded[1] = true; - - // Early exit if non of the results is ever used. - if (!ResultNeeded[0] && !ResultNeeded[1]) { - II->eraseFromParent(); - return true; - } - - // Early exit if the second result (flag) isn't used and target - // div-instruction computes exactly what we want to get as the first result - // and never traps. - if (ResultNeeded[0] && !ResultNeeded[1] && DivWellDefined) { - BinaryOperator *Div = BinaryOperator::Create(Op, LHS, RHS); - Div->insertAfter(II); - for (User *U: ResultsUsers[0]) { - Instruction *UserInst = dyn_cast(U); - assert(UserInst && "Unexpected null-instruction"); - UserInst->replaceAllUsesWith(Div); - UserInst->eraseFromParent(); - } - II->eraseFromParent(); - CurInstIterator = Div; - ModifiedDT = true; - return true; - } - - Value *MinusOne = Constant::getAllOnesValue(LHS->getType()); - Value *Zero = Constant::getNullValue(LHS->getType()); - - // Split the original BB and create other basic blocks that will be used - // for checks. - BasicBlock *StartBB = II->getParent(); - BasicBlock::iterator SplitPt = ++(BasicBlock::iterator(II)); - BasicBlock *NextBB = StartBB->splitBasicBlock(SplitPt, "div.end"); - - BasicBlock *DivByZeroBB; - DivByZeroBB = BasicBlock::Create(II->getContext(), "div.divz", - NextBB->getParent(), NextBB); - BranchInst::Create(NextBB, DivByZeroBB); - BasicBlock *DivBB = BasicBlock::Create(II->getContext(), "div.div", - NextBB->getParent(), NextBB); - BranchInst::Create(NextBB, DivBB); - - // For signed variants, check the condition (2): - // LHS == SignedMinValue, RHS == -1. - Value *CmpMinusOne; - Value *CmpMinValue; - BasicBlock *ChkDivMinBB; - BasicBlock *DivMinBB; - Value *MinValue; - if (IsSigned) { - APInt SignedMinValue = - APInt::getSignedMinValue(LHS->getType()->getPrimitiveSizeInBits()); - MinValue = Constant::getIntegerValue(LHS->getType(), SignedMinValue); - ChkDivMinBB = BasicBlock::Create(II->getContext(), "div.chkdivmin", - NextBB->getParent(), NextBB); - BranchInst::Create(NextBB, ChkDivMinBB); - DivMinBB = BasicBlock::Create(II->getContext(), "div.divmin", - NextBB->getParent(), NextBB); - BranchInst::Create(NextBB, DivMinBB); - CmpMinusOne = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, - RHS, MinusOne, "cmp.rhs.minus.one", - ChkDivMinBB->getTerminator()); - CmpMinValue = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, - LHS, MinValue, "cmp.lhs.signed.min", - ChkDivMinBB->getTerminator()); - BinaryOperator *CmpSignedOvf = BinaryOperator::Create(Instruction::And, - CmpMinusOne, - CmpMinValue); - // Here we're interested in the case when both %x is TMin and %y is -1. - // In this case the result will overflow. - // If that's not the case, we can perform usual division. These blocks - // will be inserted after DivByZero, so the division will be safe. - CmpSignedOvf->insertBefore(ChkDivMinBB->getTerminator()); - BranchInst::Create(DivMinBB, DivBB, CmpSignedOvf, - ChkDivMinBB->getTerminator()); - ChkDivMinBB->getTerminator()->eraseFromParent(); - } - - // Check the condition (1): - // RHS == 0. - Value *CmpDivZero = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, - RHS, Zero, "cmp.rhs.zero", - StartBB->getTerminator()); - - // If RHS != 0, we want to check condition (2) in signed case, or proceed - // to usual division in unsigned case. - BranchInst::Create(DivByZeroBB, IsSigned ? ChkDivMinBB : DivBB, CmpDivZero, - StartBB->getTerminator()); - StartBB->getTerminator()->eraseFromParent(); - - // At the moment we have all the control flow created. We just need to - // insert DIV and PHI (if needed) to get the result value. - Instruction *DivRes, *FlagRes; - Instruction *InsPoint = nullptr; - if (ResultNeeded[0]) { - BinaryOperator *Div = BinaryOperator::Create(Op, LHS, RHS); - if (DivWellDefined) { - // The result value is the result of DIV operation placed right at the - // original place of the intrinsic. - Div->insertAfter(II); - DivRes = Div; - } else { - // The result is a PHI-node. - Div->insertBefore(DivBB->getTerminator()); - PHINode *DivResPN = - PHINode::Create(LHS->getType(), IsSigned ? 3 : 2, "div.res.phi", - NextBB->begin()); - DivResPN->addIncoming(Div, DivBB); - DivResPN->addIncoming(Zero, DivByZeroBB); - if (IsSigned) - DivResPN->addIncoming(MinValue, DivMinBB); - DivRes = DivResPN; - InsPoint = DivResPN; - } - } - - // Prepare a value for the second result (flag) if it is needed. - if (ResultNeeded[1]) { - Type *FlagTy = II->getType()->getStructElementType(1); - PHINode *FlagResPN = - PHINode::Create(FlagTy, IsSigned ? 3 : 2, "div.flag.phi", - NextBB->begin()); - FlagResPN->addIncoming(Constant::getNullValue(FlagTy), DivBB); - FlagResPN->addIncoming(Constant::getAllOnesValue(FlagTy), DivByZeroBB); - if (IsSigned) - FlagResPN->addIncoming(Constant::getAllOnesValue(FlagTy), DivMinBB); - FlagRes = FlagResPN; - if (!InsPoint) - InsPoint = FlagRes; - } - - // If possible, propagate the results to the user. Otherwise, create alloca, - // and create a struct with the results on stack. - if (!BadCase) { - if (ResultNeeded[0]) { - for (User *U: ResultsUsers[0]) { - Instruction *UserInst = dyn_cast(U); - assert(UserInst && "Unexpected null-instruction"); - UserInst->replaceAllUsesWith(DivRes); - UserInst->eraseFromParent(); - } - } - if (ResultNeeded[1]) { - for (User *FlagU: ResultsUsers[1]) { - Instruction *FlagUInst = dyn_cast(FlagU); - FlagUInst->replaceAllUsesWith(FlagRes); - FlagUInst->eraseFromParent(); - } - } - } else { - // Create alloca, store our new values to it, and then load the final - // result from it. - Constant *Idx0 = ConstantInt::get(Type::getInt32Ty(II->getContext()), 0); - Constant *Idx1 = ConstantInt::get(Type::getInt32Ty(II->getContext()), 1); - Value *Idxs_DivRes[2] = {Idx0, Idx0}; - Value *Idxs_FlagRes[2] = {Idx0, Idx1}; - Value *NewRes = new llvm::AllocaInst(II->getType(), 0, "div.res.ptr", II); - Instruction *ResDivAddr = GetElementPtrInst::Create(NewRes, Idxs_DivRes); - Instruction *ResFlagAddr = - GetElementPtrInst::Create(NewRes, Idxs_FlagRes); - ResDivAddr->insertAfter(InsPoint); - ResFlagAddr->insertAfter(ResDivAddr); - StoreInst *StoreResDiv = new StoreInst(DivRes, ResDivAddr); - StoreInst *StoreResFlag = new StoreInst(FlagRes, ResFlagAddr); - StoreResDiv->insertAfter(ResFlagAddr); - StoreResFlag->insertAfter(StoreResDiv); - LoadInst *LoadRes = new LoadInst(NewRes, "div.res"); - LoadRes->insertAfter(StoreResFlag); - II->replaceAllUsesWith(LoadRes); - } - - II->eraseFromParent(); - CurInstIterator = StartBB->end(); - ModifiedDT = true; - return true; - } if (II && TLI) { SmallVector PtrOps; diff --git a/lib/CodeGen/TargetLoweringBase.cpp b/lib/CodeGen/TargetLoweringBase.cpp index a34e0036769..47ee2b0988f 100644 --- a/lib/CodeGen/TargetLoweringBase.cpp +++ b/lib/CodeGen/TargetLoweringBase.cpp @@ -683,7 +683,6 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm, HasExtractBitsInsn = false; IntDivIsCheap = false; Pow2DivIsCheap = false; - DivIsWellDefined = false; JumpIsExpensive = false; PredictableSelectIsExpensive = false; MaskAndBranchFoldingIsLegal = false; diff --git a/lib/Target/ARM64/ARM64ISelLowering.cpp b/lib/Target/ARM64/ARM64ISelLowering.cpp index 3cdd2db4ea5..d295dd18127 100644 --- a/lib/Target/ARM64/ARM64ISelLowering.cpp +++ b/lib/Target/ARM64/ARM64ISelLowering.cpp @@ -370,8 +370,6 @@ ARM64TargetLowering::ARM64TargetLowering(ARM64TargetMachine &TM) setMinFunctionAlignment(2); - setDivIsWellDefined(true); - RequireStrictAlign = StrictAlign; setHasExtractBitsInsn(true); diff --git a/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll b/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll deleted file mode 100644 index c5ab2935031..00000000000 --- a/test/CodeGen/ARM64/SafeDivRemIntrinsics-Opts.ll +++ /dev/null @@ -1,83 +0,0 @@ -; RUN: llc < %s -march=arm64 | FileCheck %s -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" - -%divovf32 = type { i32, i1 } - -declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone -declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone - -; CHECK-LABEL: sdiv32_results_unused -; CHECK: entry -; CHECK-NEXT: ret -define void @sdiv32_results_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - ret void -} - -; CHECK-LABEL: sdiv32_div_result_unused -; CHECK-NOT: sdiv{{[ ]}} -define i1 @sdiv32_div_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - %bit = extractvalue %divovf32 %divr, 1 - ret i1 %bit -} - -; CHECK-LABEL: sdiv32_flag_result_unused -; CHECK-NOT: cb -; CHECK: sdiv{{[ ]}} -define i32 @sdiv32_flag_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - %div = extractvalue %divovf32 %divr, 0 - ret i32 %div -} - -; CHECK-LABEL: sdiv32_result_returned -; CHECK: sdiv{{[ ]}} -define %divovf32 @sdiv32_result_returned(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} - -; CHECK-LABEL: udiv32_results_unused -; CHECK: entry -; CHECK-NEXT: ret -define void @udiv32_results_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - ret void -} - -; CHECK-LABEL: udiv32_div_result_unused -; CHECK-NOT: udiv{{[ ]}} -define i1 @udiv32_div_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - %bit = extractvalue %divovf32 %divr, 1 - ret i1 %bit -} - -; CHECK-LABEL: udiv32_flag_result_unused -; CHECK-NOT: cb -; CHECK: udiv{{[ ]}} -define i32 @udiv32_flag_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - %div = extractvalue %divovf32 %divr, 0 - ret i32 %div -} - -; CHECK-LABEL: udiv32_result_returned -; CHECK: udiv{{[ ]}} -define %divovf32 @udiv32_result_returned(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} - -!llvm.ident = !{!0} - -!0 = metadata !{metadata !"clang version 3.5.0 "} diff --git a/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll b/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll deleted file mode 100644 index 0abbbfb99d7..00000000000 --- a/test/CodeGen/ARM64/SafeDivRemIntrinsics.ll +++ /dev/null @@ -1,152 +0,0 @@ -; RUN: llc < %s -march=arm64 | FileCheck %s -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" - -%divovf8 = type { i8, i1 } -%divovf16 = type { i16, i1 } -%divovf32 = type { i32, i1 } -%divovf64 = type { i64, i1 } - -declare %divovf8 @llvm.safe.sdiv.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.sdiv.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.sdiv.i64(i64, i64) nounwind readnone - -declare %divovf8 @llvm.safe.srem.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.srem.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.srem.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.srem.i64(i64, i64) nounwind readnone - -declare %divovf8 @llvm.safe.udiv.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.udiv.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.udiv.i64(i64, i64) nounwind readnone - -declare %divovf8 @llvm.safe.urem.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.urem.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.urem.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.urem.i64(i64, i64) nounwind readnone - -; CHECK-LABEL: sdiv8 -; CHECK: sdiv{{[ ]}} -define %divovf8 @sdiv8(i8 %x, i8 %y) { -entry: - %divr = call %divovf8 @llvm.safe.sdiv.i8(i8 %x, i8 %y) - ret %divovf8 %divr -} -; CHECK-LABEL: sdiv16 -; CHECK: sdiv{{[ ]}} -define %divovf16 @sdiv16(i16 %x, i16 %y) { -entry: - %divr = call %divovf16 @llvm.safe.sdiv.i16(i16 %x, i16 %y) - ret %divovf16 %divr -} -; CHECK-LABEL: sdiv32 -; CHECK: sdiv{{[ ]}} -define %divovf32 @sdiv32(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} -; CHECK-LABEL: sdiv64 -; CHECK: sdiv{{[ ]}} -define %divovf64 @sdiv64(i64 %x, i64 %y) { -entry: - %divr = call %divovf64 @llvm.safe.sdiv.i64(i64 %x, i64 %y) - ret %divovf64 %divr -} -; CHECK-LABEL: udiv8 -; CHECK: udiv{{[ ]}} -define %divovf8 @udiv8(i8 %x, i8 %y) { -entry: - %divr = call %divovf8 @llvm.safe.udiv.i8(i8 %x, i8 %y) - ret %divovf8 %divr -} -; CHECK-LABEL: udiv16 -; CHECK: udiv{{[ ]}} -define %divovf16 @udiv16(i16 %x, i16 %y) { -entry: - %divr = call %divovf16 @llvm.safe.udiv.i16(i16 %x, i16 %y) - ret %divovf16 %divr -} -; CHECK-LABEL: udiv32 -; CHECK: udiv{{[ ]}} -define %divovf32 @udiv32(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} -; CHECK-LABEL: udiv64 -; CHECK: udiv{{[ ]}} -define %divovf64 @udiv64(i64 %x, i64 %y) { -entry: - %divr = call %divovf64 @llvm.safe.udiv.i64(i64 %x, i64 %y) - ret %divovf64 %divr -} -; CHECK-LABEL: srem8 -; CHECK: sdiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf8 @srem8(i8 %x, i8 %y) { -entry: - %remr = call %divovf8 @llvm.safe.srem.i8(i8 %x, i8 %y) - ret %divovf8 %remr -} -; CHECK-LABEL: srem16 -; CHECK: sdiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf16 @srem16(i16 %x, i16 %y) { -entry: - %remr = call %divovf16 @llvm.safe.srem.i16(i16 %x, i16 %y) - ret %divovf16 %remr -} -; CHECK-LABEL: srem32 -; CHECK: sdiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf32 @srem32(i32 %x, i32 %y) { -entry: - %remr = call %divovf32 @llvm.safe.srem.i32(i32 %x, i32 %y) - ret %divovf32 %remr -} -; CHECK-LABEL: srem64 -; CHECK: sdiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf64 @srem64(i64 %x, i64 %y) { -entry: - %remr = call %divovf64 @llvm.safe.srem.i64(i64 %x, i64 %y) - ret %divovf64 %remr -} -; CHECK-LABEL: urem8 -; CHECK: udiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf8 @urem8(i8 %x, i8 %y) { -entry: - %remr = call %divovf8 @llvm.safe.urem.i8(i8 %x, i8 %y) - ret %divovf8 %remr -} -; CHECK-LABEL: urem16 -; CHECK: udiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf16 @urem16(i16 %x, i16 %y) { -entry: - %remr = call %divovf16 @llvm.safe.urem.i16(i16 %x, i16 %y) - ret %divovf16 %remr -} -; CHECK-LABEL: urem32 -; CHECK: udiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf32 @urem32(i32 %x, i32 %y) { -entry: - %remr = call %divovf32 @llvm.safe.urem.i32(i32 %x, i32 %y) - ret %divovf32 %remr -} -; CHECK-LABEL: urem64 -; CHECK: udiv{{[ ]}} -; CHECK: msub{{[ ]}} -define %divovf64 @urem64(i64 %x, i64 %y) { -entry: - %remr = call %divovf64 @llvm.safe.urem.i64(i64 %x, i64 %y) - ret %divovf64 %remr -} - -!llvm.ident = !{!0} - -!0 = metadata !{metadata !"clang version 3.5.0 "} diff --git a/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll b/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll deleted file mode 100644 index 3b9ce43be49..00000000000 --- a/test/CodeGen/X86/SafeDivRemIntrinsics-Opts.ll +++ /dev/null @@ -1,82 +0,0 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" - -%divovf32 = type { i32, i1 } - -declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone -declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone - -; CHECK-LABEL: sdiv32_results_unused -; CHECK: entry -; CHECK-NEXT: ret -define void @sdiv32_results_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - ret void -} - -; CHECK-LABEL: sdiv32_div_result_unused -; CHECK-NOT: idiv -define i1 @sdiv32_div_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - %bit = extractvalue %divovf32 %divr, 1 - ret i1 %bit -} - -; CHECK-LABEL: sdiv32_flag_result_unused -; CHECK: idiv -define i32 @sdiv32_flag_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - %div = extractvalue %divovf32 %divr, 0 - ret i32 %div -} - -; CHECK-LABEL: sdiv32_result_returned -; CHECK: idiv -define %divovf32 @sdiv32_result_returned(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} - -; CHECK-LABEL: udiv32_results_unused -; CHECK: entry -; CHECK-NEXT: ret -define void @udiv32_results_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - ret void -} - -; CHECK-LABEL: udiv32_div_result_unused -; CHECK-NOT: udiv{{[ ]}} -define i1 @udiv32_div_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - %bit = extractvalue %divovf32 %divr, 1 - ret i1 %bit -} - -; CHECK-LABEL: udiv32_flag_result_unused -; CHECK-NOT: cb -; CHECK: {{[ ]}}div -define i32 @udiv32_flag_result_unused(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - %div = extractvalue %divovf32 %divr, 0 - ret i32 %div -} - -; CHECK-LABEL: udiv32_result_returned -; CHECK: {{[ ]}}div -define %divovf32 @udiv32_result_returned(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} - -!llvm.ident = !{!0} - -!0 = metadata !{metadata !"clang version 3.5.0 "} diff --git a/test/CodeGen/X86/SafeDivRemIntrinsics.ll b/test/CodeGen/X86/SafeDivRemIntrinsics.ll deleted file mode 100644 index f71705fa7bc..00000000000 --- a/test/CodeGen/X86/SafeDivRemIntrinsics.ll +++ /dev/null @@ -1,144 +0,0 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" - -%divovf8 = type { i8, i1 } -%divovf16 = type { i16, i1 } -%divovf32 = type { i32, i1 } -%divovf64 = type { i64, i1 } - -declare %divovf8 @llvm.safe.sdiv.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.sdiv.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.sdiv.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.sdiv.i64(i64, i64) nounwind readnone - -declare %divovf8 @llvm.safe.srem.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.srem.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.srem.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.srem.i64(i64, i64) nounwind readnone - -declare %divovf8 @llvm.safe.udiv.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.udiv.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.udiv.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.udiv.i64(i64, i64) nounwind readnone - -declare %divovf8 @llvm.safe.urem.i8(i8, i8) nounwind readnone -declare %divovf16 @llvm.safe.urem.i16(i16, i16) nounwind readnone -declare %divovf32 @llvm.safe.urem.i32(i32, i32) nounwind readnone -declare %divovf64 @llvm.safe.urem.i64(i64, i64) nounwind readnone - -; CHECK-LABEL: sdiv8 -; CHECK: idivb{{[ ]}} -define %divovf8 @sdiv8(i8 %x, i8 %y) { -entry: - %divr = call %divovf8 @llvm.safe.sdiv.i8(i8 %x, i8 %y) - ret %divovf8 %divr -} -; CHECK-LABEL: sdiv16 -; CHECK: idivw{{[ ]}} -define %divovf16 @sdiv16(i16 %x, i16 %y) { -entry: - %divr = call %divovf16 @llvm.safe.sdiv.i16(i16 %x, i16 %y) - ret %divovf16 %divr -} -; CHECK-LABEL: sdiv32 -; CHECK: idivl{{[ ]}} -define %divovf32 @sdiv32(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.sdiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} -; CHECK-LABEL: sdiv64 -; CHECK: idivq{{[ ]}} -define %divovf64 @sdiv64(i64 %x, i64 %y) { -entry: - %divr = call %divovf64 @llvm.safe.sdiv.i64(i64 %x, i64 %y) - ret %divovf64 %divr -} -; CHECK-LABEL: udiv8 -; CHECK: {{[ ]}}divb{{[ ]}} -define %divovf8 @udiv8(i8 %x, i8 %y) { -entry: - %divr = call %divovf8 @llvm.safe.udiv.i8(i8 %x, i8 %y) - ret %divovf8 %divr -} -; CHECK-LABEL: udiv16 -; CHECK: {{[ ]}}divw{{[ ]}} -define %divovf16 @udiv16(i16 %x, i16 %y) { -entry: - %divr = call %divovf16 @llvm.safe.udiv.i16(i16 %x, i16 %y) - ret %divovf16 %divr -} -; CHECK-LABEL: udiv32 -; CHECK: {{[ ]}}divl{{[ ]}} -define %divovf32 @udiv32(i32 %x, i32 %y) { -entry: - %divr = call %divovf32 @llvm.safe.udiv.i32(i32 %x, i32 %y) - ret %divovf32 %divr -} -; CHECK-LABEL: udiv64 -; CHECK: {{[ ]}}divq{{[ ]}} -define %divovf64 @udiv64(i64 %x, i64 %y) { -entry: - %divr = call %divovf64 @llvm.safe.udiv.i64(i64 %x, i64 %y) - ret %divovf64 %divr -} -; CHECK-LABEL: srem8 -; CHECK: idivb{{[ ]}} -define %divovf8 @srem8(i8 %x, i8 %y) { -entry: - %remr = call %divovf8 @llvm.safe.srem.i8(i8 %x, i8 %y) - ret %divovf8 %remr -} -; CHECK-LABEL: srem16 -; CHECK: idivw{{[ ]}} -define %divovf16 @srem16(i16 %x, i16 %y) { -entry: - %remr = call %divovf16 @llvm.safe.srem.i16(i16 %x, i16 %y) - ret %divovf16 %remr -} -; CHECK-LABEL: srem32 -; CHECK: idivl{{[ ]}} -define %divovf32 @srem32(i32 %x, i32 %y) { -entry: - %remr = call %divovf32 @llvm.safe.srem.i32(i32 %x, i32 %y) - ret %divovf32 %remr -} -; CHECK-LABEL: srem64 -; CHECK: idivq{{[ ]}} -define %divovf64 @srem64(i64 %x, i64 %y) { -entry: - %remr = call %divovf64 @llvm.safe.srem.i64(i64 %x, i64 %y) - ret %divovf64 %remr -} -; CHECK-LABEL: urem8 -; CHECK: {{[ ]}}divb{{[ ]}} -define %divovf8 @urem8(i8 %x, i8 %y) { -entry: - %remr = call %divovf8 @llvm.safe.urem.i8(i8 %x, i8 %y) - ret %divovf8 %remr -} -; CHECK-LABEL: urem16 -; CHECK: {{[ ]}}divw{{[ ]}} -define %divovf16 @urem16(i16 %x, i16 %y) { -entry: - %remr = call %divovf16 @llvm.safe.urem.i16(i16 %x, i16 %y) - ret %divovf16 %remr -} -; CHECK-LABEL: urem32 -; CHECK: {{[ ]}}divl{{[ ]}} -define %divovf32 @urem32(i32 %x, i32 %y) { -entry: - %remr = call %divovf32 @llvm.safe.urem.i32(i32 %x, i32 %y) - ret %divovf32 %remr -} -; CHECK-LABEL: urem64 -; CHECK: {{[ ]}}divq{{[ ]}} -define %divovf64 @urem64(i64 %x, i64 %y) { -entry: - %remr = call %divovf64 @llvm.safe.urem.i64(i64 %x, i64 %y) - ret %divovf64 %remr -} - -!llvm.ident = !{!0} - -!0 = metadata !{metadata !"clang version 3.5.0 "}