Changes in directory llvm/lib/VMCore:
ConstantFolding.cpp updated: 1.95 -> 1.96 Constants.cpp updated: 1.168 -> 1.169 Instruction.cpp updated: 1.55 -> 1.56 Instructions.cpp updated: 1.44 -> 1.45 --- Log message: For PR950: http://llvm.org/PR950 : Replace the REM instruction with UREM, SREM and FREM. --- Diffs of the changes: (+108 -47) ConstantFolding.cpp | 92 ++++++++++++++++++++++++++++++++-------------------- Constants.cpp | 38 ++++++++++++++++----- Instruction.cpp | 8 +++- Instructions.cpp | 17 ++++++++- 4 files changed, 108 insertions(+), 47 deletions(-) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.95 llvm/lib/VMCore/ConstantFolding.cpp:1.96 --- llvm/lib/VMCore/ConstantFolding.cpp:1.95 Thu Oct 26 01:15:43 2006 +++ llvm/lib/VMCore/ConstantFolding.cpp Wed Nov 1 19:53:58 2006 @@ -40,10 +40,12 @@ virtual Constant *add(const Constant *V1, const Constant *V2) const = 0; virtual Constant *sub(const Constant *V1, const Constant *V2) const = 0; virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0; + virtual Constant *urem(const Constant *V1, const Constant *V2) const = 0; + virtual Constant *srem(const Constant *V1, const Constant *V2) const = 0; + virtual Constant *frem(const Constant *V1, const Constant *V2) const = 0; virtual Constant *udiv(const Constant *V1, const Constant *V2) const = 0; virtual Constant *sdiv(const Constant *V1, const Constant *V2) const = 0; virtual Constant *fdiv(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *rem(const Constant *V1, const Constant *V2) const = 0; virtual Constant *op_and(const Constant *V1, const Constant *V2) const = 0; virtual Constant *op_or (const Constant *V1, const Constant *V2) const = 0; virtual Constant *op_xor(const Constant *V1, const Constant *V2) const = 0; @@ -117,8 +119,14 @@ virtual Constant *fdiv(const Constant *V1, const Constant *V2) const { return SubClassName::FDiv((const ArgType *)V1, (const ArgType *)V2); } - virtual Constant *rem(const Constant *V1, const Constant *V2) const { - return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2); + virtual Constant *urem(const Constant *V1, const Constant *V2) const { + return SubClassName::URem((const ArgType *)V1, (const ArgType *)V2); + } + virtual Constant *srem(const Constant *V1, const Constant *V2) const { + return SubClassName::SRem((const ArgType *)V1, (const ArgType *)V2); + } + virtual Constant *frem(const Constant *V1, const Constant *V2) const { + return SubClassName::FRem((const ArgType *)V1, (const ArgType *)V2); } virtual Constant *op_and(const Constant *V1, const Constant *V2) const { return SubClassName::And((const ArgType *)V1, (const ArgType *)V2); @@ -192,7 +200,9 @@ static Constant *SDiv(const ArgType *V1, const ArgType *V2) { return 0; } static Constant *UDiv(const ArgType *V1, const ArgType *V2) { return 0; } static Constant *FDiv(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *Rem (const ArgType *V1, const ArgType *V2) { return 0; } + static Constant *URem(const ArgType *V1, const ArgType *V2) { return 0; } + static Constant *SRem(const ArgType *V1, const ArgType *V2) { return 0; } + static Constant *FRem(const ArgType *V1, const ArgType *V2) { return 0; } static Constant *And (const ArgType *V1, const ArgType *V2) { return 0; } static Constant *Or (const ArgType *V1, const ArgType *V2) { return 0; } static Constant *Xor (const ArgType *V1, const ArgType *V2) { return 0; } @@ -392,8 +402,14 @@ static Constant *FDiv(const ConstantPacked *V1, const ConstantPacked *V2) { return EvalVectorOp(V1, V2, ConstantExpr::getFDiv); } - static Constant *Rem(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getRem); + static Constant *URem(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getURem); + } + static Constant *SRem(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getSRem); + } + static Constant *FRem(const ConstantPacked *V1, const ConstantPacked *V2) { + return EvalVectorOp(V1, V2, ConstantExpr::getFRem); } static Constant *And(const ConstantPacked *V1, const ConstantPacked *V2) { return EvalVectorOp(V1, V2, ConstantExpr::getAnd); @@ -510,30 +526,36 @@ #undef DEF_CAST static Constant *UDiv(const ConstantInt *V1, const ConstantInt *V2) { - if (V2->isNullValue()) + if (V2->isNullValue()) // X / 0 return 0; BuiltinType R = (BuiltinType)(V1->getZExtValue() / V2->getZExtValue()); return ConstantInt::get(*Ty, R); } static Constant *SDiv(const ConstantInt *V1, const ConstantInt *V2) { - if (V2->isNullValue()) + if (V2->isNullValue()) // X / 0 return 0; if (V2->isAllOnesValue() && // MIN_INT / -1 (BuiltinType)V1->getSExtValue() == -(BuiltinType)V1->getSExtValue()) return 0; - BuiltinType R = - (BuiltinType)(V1->getSExtValue() / V2->getSExtValue()); + BuiltinType R = (BuiltinType)(V1->getSExtValue() / V2->getSExtValue()); return ConstantInt::get(*Ty, R); } - static Constant *Rem(const ConstantInt *V1, const ConstantInt *V2) { + static Constant *URem(const ConstantInt *V1, + const ConstantInt *V2) { if (V2->isNullValue()) return 0; // X / 0 - if (V2->isAllOnesValue() && // MIN_INT / -1 - (BuiltinType)V1->getZExtValue() == -(BuiltinType)V1->getZExtValue()) + BuiltinType R = (BuiltinType)(V1->getZExtValue() % V2->getZExtValue()); + return ConstantInt::get(*Ty, R); + } + + static Constant *SRem(const ConstantInt *V1, + const ConstantInt *V2) { + if (V2->isNullValue()) return 0; // X % 0 + if (V2->isAllOnesValue() && // MIN_INT % -1 + (BuiltinType)V1->getSExtValue() == -(BuiltinType)V1->getSExtValue()) return 0; - BuiltinType R = - (BuiltinType)V1->getZExtValue() % (BuiltinType)V2->getZExtValue(); + BuiltinType R = (BuiltinType)(V1->getSExtValue() % V2->getSExtValue()); return ConstantInt::get(*Ty, R); } @@ -632,7 +654,7 @@ DEF_CAST(Double, ConstantFP , double) #undef DEF_CAST - static Constant *Rem(const ConstantFP *V1, const ConstantFP *V2) { + static Constant *FRem(const ConstantFP *V1, const ConstantFP *V2) { if (V2->isNullValue()) return 0; BuiltinType Result = std::fmod((BuiltinType)V1->getValue(), (BuiltinType)V2->getValue()); @@ -1250,7 +1272,9 @@ case Instruction::UDiv: C = ConstRules::get(V1, V2).udiv(V1, V2); break; case Instruction::SDiv: C = ConstRules::get(V1, V2).sdiv(V1, V2); break; case Instruction::FDiv: C = ConstRules::get(V1, V2).fdiv(V1, V2); break; - case Instruction::Rem: C = ConstRules::get(V1, V2).rem(V1, V2); break; + case Instruction::URem: C = ConstRules::get(V1, V2).urem(V1, V2); break; + case Instruction::SRem: C = ConstRules::get(V1, V2).srem(V1, V2); break; + case Instruction::FRem: C = ConstRules::get(V1, V2).frem(V1, V2); break; case Instruction::And: C = ConstRules::get(V1, V2).op_and(V1, V2); break; case Instruction::Or: C = ConstRules::get(V1, V2).op_or (V1, V2); break; case Instruction::Xor: C = ConstRules::get(V1, V2).op_xor(V1, V2); break; @@ -1335,25 +1359,26 @@ case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: - case Instruction::Rem: - if (!isa<UndefValue>(V2)) // undef/X -> 0 + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: + if (!isa<UndefValue>(V2)) // undef / X -> 0 return Constant::getNullValue(V1->getType()); - return const_cast<Constant*>(V2); // X/undef -> undef - case Instruction::Or: // X|undef -> -1 + return const_cast<Constant*>(V2); // X / undef -> undef + case Instruction::Or: // X | undef -> -1 return ConstantInt::getAllOnesValue(V1->getType()); case Instruction::Shr: - if (!isa<UndefValue>(V2)) { + if (!isa<UndefValue>(V2)) { if (V1->getType()->isSigned()) - return const_cast<Constant*>(V1); // undef >>s X -> undef + return const_cast<Constant*>(V1); // undef >>s X -> undef // undef >>u X -> 0 } else if (isa<UndefValue>(V1)) { - return const_cast<Constant*>(V1); // undef >> undef -> undef + return const_cast<Constant*>(V1); // undef >> undef -> undef } else { if (V1->getType()->isSigned()) - return const_cast<Constant*>(V1); // X >>s undef -> X - // X >>u undef -> 0 + return const_cast<Constant*>(V1); // X >>s undef -> X } - return Constant::getNullValue(V1->getType()); + return Constant::getNullValue(V1->getType());// X >>u undef -> 0 case Instruction::Shl: // undef << X -> 0 X << undef -> 0 @@ -1366,10 +1391,6 @@ // There are many possible foldings we could do here. We should probably // at least fold add of a pointer with an integer into the appropriate // getelementptr. This will improve alias analysis a bit. - - - - } else { // Just implement a couple of simple identities. switch (Opcode) { @@ -1391,10 +1412,11 @@ if (CI->getZExtValue() == 1) return const_cast<Constant*>(V1); // X / 1 == X break; - case Instruction::Rem: + case Instruction::URem: + case Instruction::SRem: if (const ConstantInt *CI = dyn_cast<ConstantInt>(V2)) if (CI->getZExtValue() == 1) - return Constant::getNullValue(CI->getType()); // X % 1 == 0 + return Constant::getNullValue(CI->getType()); // X % 1 == 0 break; case Instruction::And: if (cast<ConstantIntegral>(V2)->isAllOnesValue()) @@ -1450,7 +1472,9 @@ case Instruction::SDiv: case Instruction::UDiv: case Instruction::FDiv: - case Instruction::Rem: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: default: // These instructions cannot be flopped around. break; } Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.168 llvm/lib/VMCore/Constants.cpp:1.169 --- llvm/lib/VMCore/Constants.cpp:1.168 Thu Oct 26 16:48:03 2006 +++ llvm/lib/VMCore/Constants.cpp Wed Nov 1 19:53:58 2006 @@ -78,7 +78,9 @@ case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: - case Instruction::Rem: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: // Div and rem can trap if the RHS is not known to be non-zero. if (!isa<ConstantInt>(getOperand(1)) || getOperand(1)->isNullValue()) return true; @@ -457,8 +459,14 @@ Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) { return get(Instruction::FDiv, C1, C2); } -Constant *ConstantExpr::getRem(Constant *C1, Constant *C2) { - return get(Instruction::Rem, C1, C2); +Constant *ConstantExpr::getURem(Constant *C1, Constant *C2) { + return get(Instruction::URem, C1, C2); +} +Constant *ConstantExpr::getSRem(Constant *C1, Constant *C2) { + return get(Instruction::SRem, C1, C2); +} +Constant *ConstantExpr::getFRem(Constant *C1, Constant *C2) { + return get(Instruction::FRem, C1, C2); } Constant *ConstantExpr::getAnd(Constant *C1, Constant *C2) { return get(Instruction::And, C1, C2); @@ -1362,7 +1370,7 @@ break; default: assert(OldC->getOpcode() >= Instruction::BinaryOpsBegin && - OldC->getOpcode() < Instruction::BinaryOpsEnd); + OldC->getOpcode() < Instruction::BinaryOpsEnd); New = ConstantExpr::getTy(NewTy, OldC->getOpcode(), OldC->getOperand(0), OldC->getOperand(1)); break; @@ -1448,8 +1456,8 @@ if (Opcode == Instruction::Shl || Opcode == Instruction::Shr) return getShiftTy(ReqTy, Opcode, C1, C2); // Check the operands for consistency first - assert((Opcode >= Instruction::BinaryOpsBegin && - Opcode < Instruction::BinaryOpsEnd) && + assert(Opcode >= Instruction::BinaryOpsBegin && + Opcode < Instruction::BinaryOpsEnd && "Invalid opcode in binary constant expression"); assert(C1->getType() == C2->getType() && "Operand types in binary constant expression should match"); @@ -1467,15 +1475,14 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { #ifndef NDEBUG switch (Opcode) { - case Instruction::Add: case Instruction::Sub: + case Instruction::Add: + case Instruction::Sub: case Instruction::Mul: - case Instruction::Rem: assert(C1->getType() == C2->getType() && "Op types should be identical!"); assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint() || isa<PackedType>(C1->getType())) && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; - case Instruction::UDiv: case Instruction::SDiv: assert(C1->getType() == C2->getType() && "Op types should be identical!"); @@ -1489,6 +1496,19 @@ && cast<PackedType>(C1->getType())->getElementType()->isFloatingPoint())) && "Tried to create an arithmetic operation on a non-arithmetic type!"); break; + case Instruction::URem: + case Instruction::SRem: + assert(C1->getType() == C2->getType() && "Op types should be identical!"); + assert((C1->getType()->isInteger() || (isa<PackedType>(C1->getType()) && + cast<PackedType>(C1->getType())->getElementType()->isInteger())) && + "Tried to create an arithmetic operation on a non-arithmetic type!"); + break; + case Instruction::FRem: + assert(C1->getType() == C2->getType() && "Op types should be identical!"); + assert((C1->getType()->isFloatingPoint() || (isa<PackedType>(C1->getType()) + && cast<PackedType>(C1->getType())->getElementType()->isFloatingPoint())) + && "Tried to create an arithmetic operation on a non-arithmetic type!"); + break; case Instruction::And: case Instruction::Or: case Instruction::Xor: Index: llvm/lib/VMCore/Instruction.cpp diff -u llvm/lib/VMCore/Instruction.cpp:1.55 llvm/lib/VMCore/Instruction.cpp:1.56 --- llvm/lib/VMCore/Instruction.cpp:1.55 Thu Oct 26 13:27:26 2006 +++ llvm/lib/VMCore/Instruction.cpp Wed Nov 1 19:53:58 2006 @@ -97,7 +97,9 @@ case UDiv: return "udiv"; case SDiv: return "sdiv"; case FDiv: return "fdiv"; - case Rem: return "rem"; + case URem: return "urem"; + case SRem: return "srem"; + case FRem: return "frem"; // Logical operators... case And: return "and"; @@ -227,7 +229,9 @@ case UDiv: case SDiv: case FDiv: - case Rem: + case URem: + case SRem: + case FRem: case Load: case Store: case Call: Index: llvm/lib/VMCore/Instructions.cpp diff -u llvm/lib/VMCore/Instructions.cpp:1.44 llvm/lib/VMCore/Instructions.cpp:1.45 --- llvm/lib/VMCore/Instructions.cpp:1.44 Thu Oct 26 01:15:43 2006 +++ llvm/lib/VMCore/Instructions.cpp Wed Nov 1 19:53:58 2006 @@ -1023,7 +1023,6 @@ switch (iType) { case Add: case Sub: case Mul: - case Rem: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); assert((getType()->isInteger() || getType()->isFloatingPoint() || @@ -1045,7 +1044,21 @@ cast<PackedType>(getType())->getElementType()->isFloatingPoint())) && "Incorrect operand type (not floating point) for FDIV"); break; - + case URem: + case SRem: + assert(getType() == LHS->getType() && + "Arithmetic operation should return same type as operands!"); + assert((getType()->isInteger() || (isa<PackedType>(getType()) && + cast<PackedType>(getType())->getElementType()->isInteger())) && + "Incorrect operand type (not integer) for S/UREM"); + break; + case FRem: + assert(getType() == LHS->getType() && + "Arithmetic operation should return same type as operands!"); + assert((getType()->isFloatingPoint() || (isa<PackedType>(getType()) && + cast<PackedType>(getType())->getElementType()->isFloatingPoint())) + && "Incorrect operand type (not floating point) for FREM"); + break; case And: case Or: case Xor: assert(getType() == LHS->getType() && _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits