diff options
author | Chris Lattner <sabre@nondot.org> | 2011-02-06 21:44:57 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-02-06 21:44:57 +0000 |
commit | 35bda8914c0d1c02a6f90f42e7810c83150737e1 (patch) | |
tree | b210ccd009a7ac5331c76c6393b5b45d141d12d0 /lib | |
parent | bd75021465e7f8c81785e692cfd3ce559764e46f (diff) | |
download | external_llvm-35bda8914c0d1c02a6f90f42e7810c83150737e1.zip external_llvm-35bda8914c0d1c02a6f90f42e7810c83150737e1.tar.gz external_llvm-35bda8914c0d1c02a6f90f42e7810c83150737e1.tar.bz2 |
enhance vmcore to know that udiv's can be exact, and add a trivial
instcombine xform to exercise this.
Nothing forms exact udivs yet though. This is progress on PR8862
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124992 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 8 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 10 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 7 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 7 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 4 |
7 files changed, 26 insertions, 17 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 8ef4634..6d71c9e 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2304,7 +2304,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (EatIfPresent(lltok::kw_nuw)) NUW = true; } - } else if (Opc == Instruction::SDiv) { + } else if (Opc == Instruction::SDiv || Opc == Instruction::UDiv) { if (EatIfPresent(lltok::kw_exact)) Exact = true; } @@ -2347,7 +2347,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { unsigned Flags = 0; if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap; if (NSW) Flags |= OverflowingBinaryOperator::NoSignedWrap; - if (Exact) Flags |= SDivOperator::IsExact; + if (Exact) Flags |= PossiblyExactOperator::IsExact; Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags); ID.ConstantVal = C; ID.Kind = ValID::t_Constant; @@ -3032,7 +3032,8 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_fsub: case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2); - case lltok::kw_sdiv: { + case lltok::kw_sdiv: + case lltok::kw_udiv: { bool Exact = false; if (EatIfPresent(lltok::kw_exact)) Exact = true; @@ -3043,7 +3044,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, return Result; } - case lltok::kw_udiv: case lltok::kw_urem: case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1); case lltok::kw_fdiv: diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index adcad74..a744d83 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1090,8 +1090,9 @@ bool BitcodeReader::ParseConstants() { Flags |= OverflowingBinaryOperator::NoSignedWrap; if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) Flags |= OverflowingBinaryOperator::NoUnsignedWrap; - } else if (Opc == Instruction::SDiv) { - if (Record[3] & (1 << bitc::SDIV_EXACT)) + } else if (Opc == Instruction::SDiv || + Opc == Instruction::UDiv) { + if (Record[3] & (1 << bitc::PEO_EXACT)) Flags |= SDivOperator::IsExact; } } @@ -1905,8 +1906,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { cast<BinaryOperator>(I)->setHasNoSignedWrap(true); if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true); - } else if (Opc == Instruction::SDiv) { - if (Record[OpNum] & (1 << bitc::SDIV_EXACT)) + } else if (Opc == Instruction::SDiv || + Opc == Instruction::UDiv) { + if (Record[OpNum] & (1 << bitc::PEO_EXACT)) cast<BinaryOperator>(I)->setIsExact(true); } } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 702a611..f8ef8c6 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -470,9 +470,10 @@ static uint64_t GetOptimizationFlags(const Value *V) { Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP; if (OBO->hasNoUnsignedWrap()) Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP; - } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(V)) { - if (Div->isExact()) - Flags |= 1 << bitc::SDIV_EXACT; + } else if (const PossiblyExactOperator *PEO = + dyn_cast<PossiblyExactOperator>(V)) { + if (PEO->isExact()) + Flags |= 1 << bitc::PEO_EXACT; } return Flags; diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 035ee72..559788b 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -135,8 +135,8 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { BO->getOpcode() == Instruction::SDiv)) { Value *Op0BO = BO->getOperand(0), *Op1BO = BO->getOperand(1); - // If the division is exact, X % Y is zero. - if (SDivOperator *SDiv = dyn_cast<SDivOperator>(BO)) + // If the division is exact, X % Y is zero, so we end up with X or -X. + if (PossiblyExactOperator *SDiv = dyn_cast<PossiblyExactOperator>(BO)) if (SDiv->isExact()) { if (Op1BO == Op1C) return ReplaceInstUsesWith(I, Op0BO); diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 1a11d9c..5b56cb5 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -831,7 +831,8 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { Out << " nuw"; if (OBO->hasNoSignedWrap()) Out << " nsw"; - } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) { + } else if (const PossiblyExactOperator *Div = + dyn_cast<PossiblyExactOperator>(U)) { if (Div->isExact()) Out << " exact"; } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) { diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 62117b2..d2359e5 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -683,7 +683,12 @@ Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) { Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) { return getTy(C1->getType(), Instruction::SDiv, C1, C2, - SDivOperator::IsExact); + PossiblyExactOperator::IsExact); +} + +Constant* ConstantExpr::getExactUDiv(Constant* C1, Constant* C2) { + return getTy(C1->getType(), Instruction::UDiv, C1, C2, + PossiblyExactOperator::IsExact); } // Utility function for determining if a ConstantExpr is a CastOp or not. This diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 6b561f3..d129028 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1822,7 +1822,7 @@ void BinaryOperator::setHasNoSignedWrap(bool b) { } void BinaryOperator::setIsExact(bool b) { - cast<SDivOperator>(this)->setIsExact(b); + cast<PossiblyExactOperator>(this)->setIsExact(b); } bool BinaryOperator::hasNoUnsignedWrap() const { @@ -1834,7 +1834,7 @@ bool BinaryOperator::hasNoSignedWrap() const { } bool BinaryOperator::isExact() const { - return cast<SDivOperator>(this)->isExact(); + return cast<PossiblyExactOperator>(this)->isExact(); } //===----------------------------------------------------------------------===// |