diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2006-10-26 06:15:43 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2006-10-26 06:15:43 +0000 |
commit | 1628cec4d7fce310d9cde0bcc73997e5a71692c4 (patch) | |
tree | 6dff5a70de8406b153e32fdd2d60c782d6202f63 /lib/Transforms | |
parent | 7043d00750c558a518d08a638638ebe4d241f159 (diff) | |
download | external_llvm-1628cec4d7fce310d9cde0bcc73997e5a71692c4.zip external_llvm-1628cec4d7fce310d9cde0bcc73997e5a71692c4.tar.gz external_llvm-1628cec4d7fce310d9cde0bcc73997e5a71692c4.tar.bz2 |
For PR950:
Make necessary changes to support DIV -> [SUF]Div. This changes llvm to
have three division instructions: signed, unsigned, floating point. The
bytecode and assembler are bacwards compatible, however.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31195 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/IPO/SimplifyLibCalls.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 381 | ||||
-rw-r--r-- | lib/Transforms/Scalar/PredicateSimplifier.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Scalar/Reassociate.cpp | 4 |
4 files changed, 256 insertions, 135 deletions
diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp index 23f3352..157ea38 100644 --- a/lib/Transforms/IPO/SimplifyLibCalls.cpp +++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp @@ -1275,7 +1275,7 @@ public: return true; } else if (Op2V == -1.0) { // pow(x,-1.0) -> 1.0/x - BinaryOperator* div_inst= BinaryOperator::createDiv( + BinaryOperator* div_inst= BinaryOperator::createFDiv( ConstantFP::get(Ty,1.0), base, ci->getName()+".pow", ci); ci->replaceAllUsesWith(div_inst); ci->eraseFromParent(); diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index bcb4888..8e7c4b5 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -131,7 +131,11 @@ namespace { Instruction *visitAdd(BinaryOperator &I); Instruction *visitSub(BinaryOperator &I); Instruction *visitMul(BinaryOperator &I); - Instruction *visitDiv(BinaryOperator &I); + Instruction *commonDivTransforms(BinaryOperator &I); + Instruction *commonIDivTransforms(BinaryOperator &I); + Instruction *visitUDiv(BinaryOperator &I); + Instruction *visitSDiv(BinaryOperator &I); + Instruction *visitFDiv(BinaryOperator &I); Instruction *visitRem(BinaryOperator &I); Instruction *visitAnd(BinaryOperator &I); Instruction *visitOr (BinaryOperator &I); @@ -1822,7 +1826,9 @@ FoundSExt: return R; } - // add (cast *A to intptrtype) B -> cast (GEP (cast *A to sbyte*) B) -> intptrtype + // add (cast *A to intptrtype) B -> + // cast (GEP (cast *A to sbyte*) B) -> + // intptrtype { CastInst* CI = dyn_cast<CastInst>(LHS); Value* Other = RHS; @@ -1975,11 +1981,11 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { } // 0 - (X sdiv C) -> (X sdiv -C) - if (Op1I->getOpcode() == Instruction::Div) + if (Op1I->getOpcode() == Instruction::SDiv) if (ConstantInt *CSI = dyn_cast<ConstantInt>(Op0)) - if (CSI->getType()->isSigned() && CSI->isNullValue()) + if (CSI->isNullValue()) if (Constant *DivRHS = dyn_cast<Constant>(Op1I->getOperand(1))) - return BinaryOperator::createDiv(Op1I->getOperand(0), + return BinaryOperator::createSDiv(Op1I->getOperand(0), ConstantExpr::getNeg(DivRHS)); // X - X*C --> X * (1-C) @@ -2156,64 +2162,28 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { return Changed ? &I : 0; } -Instruction *InstCombiner::visitDiv(BinaryOperator &I) { +/// This function implements the transforms on div instructions that work +/// regardless of the kind of div instruction it is (udiv, sdiv, or fdiv). It is +/// used by the visitors to those instructions. +/// @brief Transforms common to all three div instructions +Instruction* InstCombiner::commonDivTransforms(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (isa<UndefValue>(Op0)) // undef / X -> 0 + // undef / X -> 0 + if (isa<UndefValue>(Op0)) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - if (isa<UndefValue>(Op1)) - return ReplaceInstUsesWith(I, Op1); // X / undef -> undef - - if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { - // div X, 1 == X - if (RHS->equalsInt(1)) - return ReplaceInstUsesWith(I, Op0); - - // div X, -1 == -X - if (RHS->isAllOnesValue()) - return BinaryOperator::createNeg(Op0); - - if (Instruction *LHS = dyn_cast<Instruction>(Op0)) - if (LHS->getOpcode() == Instruction::Div) - if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) { - // (X / C1) / C2 -> X / (C1*C2) - return BinaryOperator::createDiv(LHS->getOperand(0), - ConstantExpr::getMul(RHS, LHSRHS)); - } - - // Check to see if this is an unsigned division with an exact power of 2, - // if so, convert to a right shift. - if (ConstantInt *C = dyn_cast<ConstantInt>(RHS)) - if (C->getType()->isUnsigned()) - if (uint64_t Val = C->getZExtValue()) // Don't break X / 0 - if (isPowerOf2_64(Val)) { - uint64_t C = Log2_64(Val); - return new ShiftInst(Instruction::Shr, Op0, - ConstantInt::get(Type::UByteTy, C)); - } - // -X/C -> X/-C - if (RHS->getType()->isSigned()) - if (Value *LHSNeg = dyn_castNegVal(Op0)) - return BinaryOperator::createDiv(LHSNeg, ConstantExpr::getNeg(RHS)); - - if (!RHS->isNullValue()) { - if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) - if (Instruction *R = FoldOpIntoSelect(I, SI, this)) - return R; - if (isa<PHINode>(Op0)) - if (Instruction *NV = FoldOpIntoPhi(I)) - return NV; - } - } + // X / undef -> undef + if (isa<UndefValue>(Op1)) + return ReplaceInstUsesWith(I, Op1); - // Handle div X, Cond?Y:Z + // Handle cases involving: div X, (select Cond, Y, Z) if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) { // div X, (Cond ? 0 : Y) -> div X, Y. If the div and the select are in the - // same basic block, then we replace the select with Y, and the condition of - // the select with false (if the cond value is in the same BB). If the + // same basic block, then we replace the select with Y, and the condition + // of the select with false (if the cond value is in the same BB). If the // select has uses other than the div, this allows them to be simplified - // also. + // also. Note that div X, Y is just as good as div X, 0 (undef) if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1))) if (ST->isNullValue()) { Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0)); @@ -2225,6 +2195,7 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) { UpdateValueUsesWith(SI, SI->getOperand(2)); return &I; } + // Likewise for: div X, (Cond ? Y : 0) -> div X, Y if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2))) if (ST->isNullValue()) { @@ -2237,77 +2208,180 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) { UpdateValueUsesWith(SI, SI->getOperand(1)); return &I; } + } - // If this is 'udiv X, (Cond ? C1, C2)' where C1&C2 are powers of two, - // transform this into: '(Cond ? (udiv X, C1) : (udiv X, C2))'. + return 0; +} + +/// This function implements the transforms common to both integer division +/// instructions (udiv and sdiv). It is called by the visitors to those integer +/// division instructions. +/// @brief Common integer divide transforms +Instruction* InstCombiner::commonIDivTransforms(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + if (Instruction *Common = commonDivTransforms(I)) + return Common; + + if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { + // div X, 1 == X + if (RHS->equalsInt(1)) + return ReplaceInstUsesWith(I, Op0); + + // (X / C1) / C2 -> X / (C1*C2) + if (Instruction *LHS = dyn_cast<Instruction>(Op0)) + if (Instruction::BinaryOps(LHS->getOpcode()) == I.getOpcode()) + if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) { + return BinaryOperator::create(I.getOpcode(), LHS->getOperand(0), + ConstantExpr::getMul(RHS, LHSRHS)); + } + + if (!RHS->isNullValue()) { // avoid X udiv 0 + if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) + return R; + if (isa<PHINode>(Op0)) + if (Instruction *NV = FoldOpIntoPhi(I)) + return NV; + } + } + + // 0 / X == 0, we don't need to preserve faults! + if (ConstantInt *LHS = dyn_cast<ConstantInt>(Op0)) + if (LHS->equalsInt(0)) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + + return 0; +} + +Instruction *InstCombiner::visitUDiv(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + // Handle the integer div common cases + if (Instruction *Common = commonIDivTransforms(I)) + return Common; + + // X udiv C^2 -> X >> C + // Check to see if this is an unsigned division with an exact power of 2, + // if so, convert to a right shift. + if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) { + if (uint64_t Val = C->getZExtValue()) // Don't break X / 0 + if (isPowerOf2_64(Val)) { + uint64_t ShiftAmt = Log2_64(Val); + Value* X = Op0; + const Type* XTy = X->getType(); + bool isSigned = XTy->isSigned(); + if (isSigned) + X = InsertCastBefore(X, XTy->getUnsignedVersion(), I); + Instruction* Result = + new ShiftInst(Instruction::Shr, X, + ConstantInt::get(Type::UByteTy, ShiftAmt)); + if (!isSigned) + return Result; + InsertNewInstBefore(Result, I); + return new CastInst(Result, XTy->getSignedVersion(), I.getName()); + } + } + + // X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2) + if (ShiftInst *RHSI = dyn_cast<ShiftInst>(I.getOperand(1))) { + if (RHSI->getOpcode() == Instruction::Shl && + isa<ConstantInt>(RHSI->getOperand(0))) { + uint64_t C1 = cast<ConstantInt>(RHSI->getOperand(0))->getZExtValue(); + if (isPowerOf2_64(C1)) { + Value *N = RHSI->getOperand(1); + const Type* NTy = N->getType(); + bool isSigned = NTy->isSigned(); + if (uint64_t C2 = Log2_64(C1)) { + if (isSigned) { + NTy = NTy->getUnsignedVersion(); + N = InsertCastBefore(N, NTy, I); + } + Constant *C2V = ConstantInt::get(NTy, C2); + N = InsertNewInstBefore(BinaryOperator::createAdd(N, C2V, "tmp"), I); + } + Instruction* Result = new ShiftInst(Instruction::Shr, Op0, N); + if (!isSigned) + return Result; + InsertNewInstBefore(Result, I); + return new CastInst(Result, NTy->getSignedVersion(), I.getName()); + } + } + } + + // udiv X, (Select Cond, C1, C2) --> Select Cond, (shr X, C1), (shr X, C2) + // where C1&C2 are powers of two. + if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) { if (ConstantInt *STO = dyn_cast<ConstantInt>(SI->getOperand(1))) if (ConstantInt *SFO = dyn_cast<ConstantInt>(SI->getOperand(2))) - if (STO->getType()->isUnsigned() && SFO->getType()->isUnsigned()) { - // STO == 0 and SFO == 0 handled above. + if (!STO->isNullValue() && !STO->isNullValue()) { uint64_t TVA = STO->getZExtValue(), FVA = SFO->getZExtValue(); if (isPowerOf2_64(TVA) && isPowerOf2_64(FVA)) { + // Compute the shift amounts unsigned TSA = Log2_64(TVA), FSA = Log2_64(FVA); + // Make sure we get the unsigned version of X + Value* X = Op0; + const Type* origXTy = X->getType(); + bool isSigned = origXTy->isSigned(); + if (isSigned) + X = InsertCastBefore(X, X->getType()->getUnsignedVersion(), I); + // Construct the "on true" case of the select Constant *TC = ConstantInt::get(Type::UByteTy, TSA); - Instruction *TSI = new ShiftInst(Instruction::Shr, Op0, - TC, SI->getName()+".t"); + Instruction *TSI = + new ShiftInst(Instruction::Shr, X, TC, SI->getName()+".t"); TSI = InsertNewInstBefore(TSI, I); - - Constant *FC = ConstantInt::get(Type::UByteTy, FSA); - Instruction *FSI = new ShiftInst(Instruction::Shr, Op0, - FC, SI->getName()+".f"); + + // Construct the "on false" case of the select + Constant *FC = ConstantInt::get(Type::UByteTy, FSA); + Instruction *FSI = + new ShiftInst(Instruction::Shr, X, FC, SI->getName()+".f"); FSI = InsertNewInstBefore(FSI, I); - return new SelectInst(SI->getOperand(0), TSI, FSI); + + // construct the select instruction and return it. + SelectInst* NewSI = + new SelectInst(SI->getOperand(0), TSI, FSI, SI->getName()); + if (!isSigned) + return NewSI; + InsertNewInstBefore(NewSI, I); + return new CastInst(NewSI, origXTy, NewSI->getName()); } } } + return 0; +} - // 0 / X == 0, we don't need to preserve faults! - if (ConstantInt *LHS = dyn_cast<ConstantInt>(Op0)) - if (LHS->equalsInt(0)) - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); +Instruction *InstCombiner::visitSDiv(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (I.getType()->isSigned()) { - // If the sign bits of both operands are zero (i.e. we can prove they are - // unsigned inputs), turn this into a udiv. + // Handle the integer div common cases + if (Instruction *Common = commonIDivTransforms(I)) + return Common; + + if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { + // sdiv X, -1 == -X + if (RHS->isAllOnesValue()) + return BinaryOperator::createNeg(Op0); + + // -X/C -> X/-C + if (Value *LHSNeg = dyn_castNegVal(Op0)) + return BinaryOperator::createSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); + } + + // If the sign bits of both operands are zero (i.e. we can prove they are + // unsigned inputs), turn this into a udiv. + if (I.getType()->isInteger()) { uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1); if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) { - const Type *NTy = Op0->getType()->getUnsignedVersion(); - Instruction *LHS = new CastInst(Op0, NTy, Op0->getName()); - InsertNewInstBefore(LHS, I); - Value *RHS; - if (Constant *R = dyn_cast<Constant>(Op1)) - RHS = ConstantExpr::getCast(R, NTy); - else - RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I); - Instruction *Div = BinaryOperator::createDiv(LHS, RHS, I.getName()); - InsertNewInstBefore(Div, I); - return new CastInst(Div, I.getType()); - } - } else { - // Known to be an unsigned division. - if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) { - // Turn A / (C1 << N), where C1 is "1<<C2" into A >> (N+C2) [udiv only]. - if (RHSI->getOpcode() == Instruction::Shl && - isa<ConstantInt>(RHSI->getOperand(0)) && - RHSI->getOperand(0)->getType()->isUnsigned()) { - uint64_t C1 = cast<ConstantInt>(RHSI->getOperand(0))->getZExtValue(); - if (isPowerOf2_64(C1)) { - uint64_t C2 = Log2_64(C1); - Value *Add = RHSI->getOperand(1); - if (C2) { - Constant *C2V = ConstantInt::get(Add->getType(), C2); - Add = InsertNewInstBefore(BinaryOperator::createAdd(Add, C2V, - "tmp"), I); - } - return new ShiftInst(Instruction::Shr, Op0, Add); - } - } + return BinaryOperator::createUDiv(Op0, Op1, I.getName()); } - } + } return 0; } +Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { + return commonDivTransforms(I); +} /// GetFactor - If we can prove that the specified value is at least a multiple /// of some factor, return that factor. @@ -2376,13 +2450,12 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) { uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1); if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) { const Type *NTy = Op0->getType()->getUnsignedVersion(); - Instruction *LHS = new CastInst(Op0, NTy, Op0->getName()); - InsertNewInstBefore(LHS, I); + Value *LHS = InsertCastBefore(Op0, NTy, I); Value *RHS; if (Constant *R = dyn_cast<Constant>(Op1)) RHS = ConstantExpr::getCast(R, NTy); else - RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I); + RHS = InsertCastBefore(Op1, NTy, I); Instruction *Rem = BinaryOperator::createRem(LHS, RHS, I.getName()); InsertNewInstBefore(Rem, I); return new CastInst(Rem, I.getType()); @@ -3717,14 +3790,6 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return Changed ? &I : 0; } -/// MulWithOverflow - Compute Result = In1*In2, returning true if the result -/// overflowed for this type. -static bool MulWithOverflow(ConstantInt *&Result, ConstantInt *In1, - ConstantInt *In2) { - Result = cast<ConstantInt>(ConstantExpr::getMul(In1, In2)); - return !In2->isNullValue() && ConstantExpr::getDiv(Result, In2) != In1; -} - static bool isPositive(ConstantInt *C) { return C->getSExtValue() >= 0; } @@ -4126,7 +4191,9 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { } } - + // Since the RHS is a constantInt (CI), if the left hand side is an + // instruction, see if that instruction also has constants so that the + // instruction can be folded into the setcc if (Instruction *LHSI = dyn_cast<Instruction>(Op0)) switch (LHSI->getOpcode()) { case Instruction::And: @@ -4379,27 +4446,60 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { } break; - case Instruction::Div: - // Fold: (div X, C1) op C2 -> range check + case Instruction::SDiv: + case Instruction::UDiv: + // Fold: setcc ([us]div X, C1), C2 -> range test + // Fold this div into the comparison, producing a range check. + // Determine, based on the divide type, what the range is being + // checked. If there is an overflow on the low or high side, remember + // it, otherwise compute the range [low, hi) bounding the new value. + // See: InsertRangeTest above for the kinds of replacements possible. if (ConstantInt *DivRHS = dyn_cast<ConstantInt>(LHSI->getOperand(1))) { - // Fold this div into the comparison, producing a range check. - // Determine, based on the divide type, what the range is being - // checked. If there is an overflow on the low or high side, remember - // it, otherwise compute the range [low, hi) bounding the new value. - bool LoOverflow = false, HiOverflow = 0; - ConstantInt *LoBound = 0, *HiBound = 0; + // FIXME: If the operand types don't match the type of the divide + // then don't attempt this transform. The code below doesn't have the + // logic to deal with a signed divide and an unsigned compare (and + // vice versa). This is because (x /s C1) <s C2 produces different + // results than (x /s C1) <u C2 or (x /u C1) <s C2 or even + // (x /u C1) <u C2. Simply casting the operands and result won't + // work. :( The if statement below tests that condition and bails + // if it finds it. + const Type* DivRHSTy = DivRHS->getType(); + unsigned DivOpCode = LHSI->getOpcode(); + if (I.isEquality() && + ((DivOpCode == Instruction::SDiv && DivRHSTy->isUnsigned()) || + (DivOpCode == Instruction::UDiv && DivRHSTy->isSigned()))) + break; - ConstantInt *Prod; - bool ProdOV = MulWithOverflow(Prod, CI, DivRHS); + // Initialize the variables that will indicate the nature of the + // range check. + bool LoOverflow = false, HiOverflow = false; + ConstantInt *LoBound = 0, *HiBound = 0; + // Compute Prod = CI * DivRHS. We are essentially solving an equation + // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and + // C2 (CI). By solving for X we can turn this into a range check + // instead of computing a divide. + ConstantInt *Prod = + cast<ConstantInt>(ConstantExpr::getMul(CI, DivRHS)); + + // Determine if the product overflows by seeing if the product is + // not equal to the divide. Make sure we do the same kind of divide + // as in the LHS instruction that we're folding. + bool ProdOV = !DivRHS->isNullValue() && + (DivOpCode == Instruction::SDiv ? + ConstantExpr::getSDiv(Prod, DivRHS) : + ConstantExpr::getUDiv(Prod, DivRHS)) != CI; + + // Get the SetCC opcode Instruction::BinaryOps Opcode = I.getOpcode(); - if (DivRHS->isNullValue()) { // Don't hack on divide by zeros. - } else if (LHSI->getType()->isUnsigned()) { // udiv + if (DivRHS->isNullValue()) { + // Don't hack on divide by zeros! + } else if (DivOpCode == Instruction::UDiv) { // udiv LoBound = Prod; LoOverflow = ProdOV; HiOverflow = ProdOV || AddWithOverflow(HiBound, LoBound, DivRHS); - } else if (isPositive(DivRHS)) { // Divisor is > 0. + } else if (isPositive(DivRHS)) { // Divisor is > 0. if (CI->isNullValue()) { // (X / pos) op 0 // Can't overflow. LoBound = cast<ConstantInt>(ConstantExpr::getNeg(SubOne(DivRHS))); @@ -4415,12 +4515,12 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { HiBound = Prod; HiOverflow = ProdOV; } - } else { // Divisor is < 0. + } else { // Divisor is < 0. if (CI->isNullValue()) { // (X / neg) op 0 LoBound = AddOne(DivRHS); HiBound = cast<ConstantInt>(ConstantExpr::getNeg(DivRHS)); if (HiBound == DivRHS) - LoBound = 0; // - INTMIN = INTMIN + LoBound = 0; // - INTMIN = INTMIN } else if (isPositive(CI)) { // (X / neg) op pos HiOverflow = LoOverflow = ProdOV; if (!LoOverflow) @@ -5679,6 +5779,23 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { ConstantInt::get(CI.getType(), 1)); } break; + case Instruction::SDiv: + case Instruction::UDiv: + // If we are just changing the sign, rewrite. + if (DestBitSize == SrcBitSize) { + // Don't insert two casts if they cannot be eliminated. We allow two + // casts to be inserted if the sizes are the same. This could only be + // converting signedness, which is a noop. + if (!ValueRequiresCast(Op1, DestTy,TD) || + !ValueRequiresCast(Op0, DestTy, TD)) { + Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI); + Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI); + return BinaryOperator::create( + cast<BinaryOperator>(SrcI)->getOpcode(), Op0c, Op1c); + } + } + break; + case Instruction::Shl: // Allow changing the sign of the source operand. Do not allow changing // the size of the shift, UNLESS the shift amount is a constant. We diff --git a/lib/Transforms/Scalar/PredicateSimplifier.cpp b/lib/Transforms/Scalar/PredicateSimplifier.cpp index 2602769..c4ffa4e 100644 --- a/lib/Transforms/Scalar/PredicateSimplifier.cpp +++ b/lib/Transforms/Scalar/PredicateSimplifier.cpp @@ -788,7 +788,9 @@ void PredicateSimplifier::Forwards::visitBinaryOperator(BinaryOperator &BO) { Instruction::BinaryOps ops = BO.getOpcode(); switch (ops) { - case Instruction::Div: + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::FDiv: case Instruction::Rem: { Value *Divisor = BO.getOperand(1); KP.addNotEqual(Constant::getNullValue(Divisor->getType()), Divisor); diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 64b7b12..7d71085 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -113,7 +113,9 @@ static bool isUnmovableInstruction(Instruction *I) { I->getOpcode() == Instruction::Malloc || I->getOpcode() == Instruction::Invoke || I->getOpcode() == Instruction::Call || - I->getOpcode() == Instruction::Div || + I->getOpcode() == Instruction::UDiv || + I->getOpcode() == Instruction::SDiv || + I->getOpcode() == Instruction::FDiv || I->getOpcode() == Instruction::Rem) return true; return false; |