diff options
author | Ed Schouten <ed@FreeBSD.org> | 2009-06-06 08:20:29 +0000 |
---|---|---|
committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-06 08:20:29 +0000 |
commit | f4fe016fa15f703fe9c1b932d1e81e2c718521db (patch) | |
tree | 8a1bbd1a5b838080d31e5c93a1817006b8c62318 /lib/VMCore | |
parent | 68eb509bdc5c7007520d5231cd92de28106236df (diff) |
Notes
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/Attributes.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 23 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 49 | ||||
-rw-r--r-- | lib/VMCore/Instruction.cpp | 19 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 70 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 48 |
6 files changed, 164 insertions, 49 deletions
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 5a8fad9cd326..8dfbd1d50216 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -59,6 +59,10 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "ssp "; if (Attrs & Attribute::StackProtectReq) Result += "sspreq "; + if (Attrs & Attribute::NoRedZone) + Result += "noredzone "; + if (Attrs & Attribute::NoImplicitFloat) + Result += "noimplicitfloat "; if (Attrs & Attribute::Alignment) { Result += "align "; Result += utostr(Attribute::getAlignmentFromAttrs(Attrs)); diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 7e4902fd5635..1d293ccbd44d 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -602,10 +602,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, return Constant::getNullValue(C1->getType()); case Instruction::UDiv: case Instruction::SDiv: - case Instruction::FDiv: case Instruction::URem: case Instruction::SRem: - case Instruction::FRem: if (!isa<UndefValue>(C2)) // undef / X -> 0 return Constant::getNullValue(C1->getType()); return const_cast<Constant*>(C2); // X / undef -> undef @@ -783,13 +781,13 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, switch (Opcode) { default: break; - case Instruction::Add: + case Instruction::FAdd: (void)C3V.add(C2V, APFloat::rmNearestTiesToEven); return ConstantFP::get(C3V); - case Instruction::Sub: + case Instruction::FSub: (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven); return ConstantFP::get(C3V); - case Instruction::Mul: + case Instruction::FMul: (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven); return ConstantFP::get(C3V); case Instruction::FDiv: @@ -808,12 +806,18 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, switch (Opcode) { default: break; - case Instruction::Add: + case Instruction::Add: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAdd); - case Instruction::Sub: + case Instruction::FAdd: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFAdd); + case Instruction::Sub: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSub); - case Instruction::Mul: + case Instruction::FSub: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFSub); + case Instruction::Mul: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getMul); + case Instruction::FMul: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFMul); case Instruction::UDiv: return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getUDiv); case Instruction::SDiv: @@ -851,7 +855,9 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, // other way if possible. switch (Opcode) { case Instruction::Add: + case Instruction::FAdd: case Instruction::Mul: + case Instruction::FMul: case Instruction::And: case Instruction::Or: case Instruction::Xor: @@ -862,6 +868,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, case Instruction::LShr: case Instruction::AShr: case Instruction::Sub: + case Instruction::FSub: case Instruction::SDiv: case Instruction::UDiv: case Instruction::FDiv: diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 97f3ac9c270a..69c503dff956 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -775,26 +775,46 @@ const SmallVector<unsigned, 4> &ConstantExpr::getIndices() const { /// specify the full Instruction::OPCODE identifier. /// Constant *ConstantExpr::getNeg(Constant *C) { + // API compatibility: Adjust integer opcodes to floating-point opcodes. + if (C->getType()->isFPOrFPVector()) + return getFNeg(C); + assert(C->getType()->isIntOrIntVector() && + "Cannot NEG a nonintegral value!"); return get(Instruction::Sub, ConstantExpr::getZeroValueForNegationExpr(C->getType()), C); } +Constant *ConstantExpr::getFNeg(Constant *C) { + assert(C->getType()->isFPOrFPVector() && + "Cannot FNEG a non-floating-point value!"); + return get(Instruction::FSub, + ConstantExpr::getZeroValueForNegationExpr(C->getType()), + C); +} Constant *ConstantExpr::getNot(Constant *C) { - assert((isa<IntegerType>(C->getType()) || - cast<VectorType>(C->getType())->getElementType()->isInteger()) && - "Cannot NOT a nonintegral value!"); + assert(C->getType()->isIntOrIntVector() && + "Cannot NOT a nonintegral value!"); return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType())); } Constant *ConstantExpr::getAdd(Constant *C1, Constant *C2) { return get(Instruction::Add, C1, C2); } +Constant *ConstantExpr::getFAdd(Constant *C1, Constant *C2) { + return get(Instruction::FAdd, C1, C2); +} Constant *ConstantExpr::getSub(Constant *C1, Constant *C2) { return get(Instruction::Sub, C1, C2); } +Constant *ConstantExpr::getFSub(Constant *C1, Constant *C2) { + return get(Instruction::FSub, C1, C2); +} Constant *ConstantExpr::getMul(Constant *C1, Constant *C2) { return get(Instruction::Mul, C1, C2); } +Constant *ConstantExpr::getFMul(Constant *C1, Constant *C2) { + return get(Instruction::FMul, C1, C2); +} Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2) { return get(Instruction::UDiv, C1, C2); } @@ -2142,15 +2162,28 @@ Constant *ConstantExpr::getCompareTy(unsigned short predicate, } Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { + // API compatibility: Adjust integer opcodes to floating-point opcodes. + if (C1->getType()->isFPOrFPVector()) { + if (Opcode == Instruction::Add) Opcode = Instruction::FAdd; + else if (Opcode == Instruction::Sub) Opcode = Instruction::FSub; + else if (Opcode == Instruction::Mul) Opcode = Instruction::FMul; + } #ifndef NDEBUG switch (Opcode) { - case Instruction::Add: + case Instruction::Add: case Instruction::Sub: - case Instruction::Mul: + case Instruction::Mul: assert(C1->getType() == C2->getType() && "Op types should be identical!"); - assert((C1->getType()->isInteger() || C1->getType()->isFloatingPoint() || - isa<VectorType>(C1->getType())) && - "Tried to create an arithmetic operation on a non-arithmetic type!"); + assert(C1->getType()->isIntOrIntVector() && + "Tried to create an integer operation on a non-integer type!"); + break; + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + assert(C1->getType() == C2->getType() && "Op types should be identical!"); + assert(C1->getType()->isFPOrFPVector() && + "Tried to create a floating-point operation on a " + "non-floating-point type!"); break; case Instruction::UDiv: case Instruction::SDiv: diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 9e030b78e9e5..7556b8ebe760 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -101,8 +101,11 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { // Standard binary operators... case Add: return "add"; + case FAdd: return "fadd"; case Sub: return "sub"; + case FSub: return "fsub"; case Mul: return "mul"; + case FMul: return "fmul"; case UDiv: return "udiv"; case SDiv: return "sdiv"; case FDiv: return "fdiv"; @@ -330,19 +333,13 @@ bool Instruction::mayThrow() const { /// isAssociative - Return true if the instruction is associative: /// -/// Associative operators satisfy: x op (y op z) === (x op y) op z) +/// Associative operators satisfy: x op (y op z) === (x op y) op z /// -/// In LLVM, the Add, Mul, And, Or, and Xor operators are associative, when not -/// applied to floating point types. +/// In LLVM, the Add, Mul, And, Or, and Xor operators are associative. /// bool Instruction::isAssociative(unsigned Opcode, const Type *Ty) { - if (Opcode == And || Opcode == Or || Opcode == Xor) - return true; - - // Add/Mul reassociate unless they are FP or FP vectors. - if (Opcode == Add || Opcode == Mul) - return !Ty->isFPOrFPVector(); - return 0; + return Opcode == And || Opcode == Or || Opcode == Xor || + Opcode == Add || Opcode == Mul; } /// isCommutative - Return true if the instruction is commutative: @@ -355,7 +352,9 @@ bool Instruction::isAssociative(unsigned Opcode, const Type *Ty) { bool Instruction::isCommutative(unsigned op) { switch (op) { case Add: + case FAdd: case Mul: + case FMul: case And: case Or: case Xor: diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index fe30271f8445..4c228fe81c0a 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1502,29 +1502,43 @@ const Type* ExtractValueInst::getIndexedType(const Type *Agg, // BinaryOperator Class //===----------------------------------------------------------------------===// +/// AdjustIType - Map Add, Sub, and Mul to FAdd, FSub, and FMul when the +/// type is floating-point, to help provide compatibility with an older API. +/// +static BinaryOperator::BinaryOps AdjustIType(BinaryOperator::BinaryOps iType, + const Type *Ty) { + // API compatibility: Adjust integer opcodes to floating-point opcodes. + if (Ty->isFPOrFPVector()) { + if (iType == BinaryOperator::Add) iType = BinaryOperator::FAdd; + else if (iType == BinaryOperator::Sub) iType = BinaryOperator::FSub; + else if (iType == BinaryOperator::Mul) iType = BinaryOperator::FMul; + } + return iType; +} + BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, const std::string &Name, Instruction *InsertBefore) - : Instruction(Ty, iType, + : Instruction(Ty, AdjustIType(iType, Ty), OperandTraits<BinaryOperator>::op_begin(this), OperandTraits<BinaryOperator>::operands(this), InsertBefore) { Op<0>() = S1; Op<1>() = S2; - init(iType); + init(AdjustIType(iType, Ty)); setName(Name); } BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(Ty, iType, + : Instruction(Ty, AdjustIType(iType, Ty), OperandTraits<BinaryOperator>::op_begin(this), OperandTraits<BinaryOperator>::operands(this), InsertAtEnd) { Op<0>() = S1; Op<1>() = S2; - init(iType); + init(AdjustIType(iType, Ty)); setName(Name); } @@ -1537,12 +1551,19 @@ void BinaryOperator::init(BinaryOps iType) { #ifndef NDEBUG switch (iType) { case Add: case Sub: - case Mul: + case Mul: + assert(getType() == LHS->getType() && + "Arithmetic operation should return same type as operands!"); + assert(getType()->isIntOrIntVector() && + "Tried to create an integer operation on a non-integer type!"); + break; + case FAdd: case FSub: + case FMul: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); - assert((getType()->isInteger() || getType()->isFloatingPoint() || - isa<VectorType>(getType())) && - "Tried to create an arithmetic operation on a non-arithmetic type!"); + assert(getType()->isFPOrFPVector() && + "Tried to create a floating-point operation on a " + "non-floating-point type!"); break; case UDiv: case SDiv: @@ -1631,6 +1652,22 @@ BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const std::string &Name, Op->getType(), Name, InsertAtEnd); } +BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name, + Instruction *InsertBefore) { + Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType()); + return new BinaryOperator(Instruction::FSub, + zero, Op, + Op->getType(), Name, InsertBefore); +} + +BinaryOperator *BinaryOperator::CreateFNeg(Value *Op, const std::string &Name, + BasicBlock *InsertAtEnd) { + Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType()); + return new BinaryOperator(Instruction::FSub, + zero, Op, + Op->getType(), Name, InsertAtEnd); +} + BinaryOperator *BinaryOperator::CreateNot(Value *Op, const std::string &Name, Instruction *InsertBefore) { Constant *C; @@ -1679,6 +1716,14 @@ bool BinaryOperator::isNeg(const Value *V) { return false; } +bool BinaryOperator::isFNeg(const Value *V) { + if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V)) + if (Bop->getOpcode() == Instruction::FSub) + return Bop->getOperand(0) == + ConstantExpr::getZeroValueForNegationExpr(Bop->getType()); + return false; +} + bool BinaryOperator::isNot(const Value *V) { if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V)) return (Bop->getOpcode() == Instruction::Xor && @@ -1696,6 +1741,15 @@ const Value *BinaryOperator::getNegArgument(const Value *BinOp) { return getNegArgument(const_cast<Value*>(BinOp)); } +Value *BinaryOperator::getFNegArgument(Value *BinOp) { + assert(isFNeg(BinOp) && "getFNegArgument from non-'fneg' instruction!"); + return cast<BinaryOperator>(BinOp)->getOperand(1); +} + +const Value *BinaryOperator::getFNegArgument(const Value *BinOp) { + return getFNegArgument(const_cast<Value*>(BinOp)); +} + Value *BinaryOperator::getNotArgument(Value *BinOp) { assert(isNot(BinOp) && "getNotArgument on non-'not' instruction!"); BinaryOperator *BO = cast<BinaryOperator>(BinOp); diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 59ec3bee715a..b047d0c9fb6d 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1069,13 +1069,40 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { "Both operands to a binary operator are not of the same type!", &B); switch (B.getOpcode()) { + // Check that integer arithmetic operators are only used with + // integral operands. + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + case Instruction::SDiv: + case Instruction::UDiv: + case Instruction::SRem: + case Instruction::URem: + Assert1(B.getType()->isIntOrIntVector(), + "Integer arithmetic operators only work with integral types!", &B); + Assert1(B.getType() == B.getOperand(0)->getType(), + "Integer arithmetic operators must have same type " + "for operands and result!", &B); + break; + // Check that floating-point arithmetic operators are only used with + // floating-point operands. + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: + case Instruction::FRem: + Assert1(B.getType()->isFPOrFPVector(), + "Floating-point arithmetic operators only work with " + "floating-point types!", &B); + Assert1(B.getType() == B.getOperand(0)->getType(), + "Floating-point arithmetic operators must have same type " + "for operands and result!", &B); + break; // Check that logical operators are only used with integral operands. case Instruction::And: case Instruction::Or: case Instruction::Xor: - Assert1(B.getType()->isInteger() || - (isa<VectorType>(B.getType()) && - cast<VectorType>(B.getType())->getElementType()->isInteger()), + Assert1(B.getType()->isIntOrIntVector(), "Logical operators only work with integral types!", &B); Assert1(B.getType() == B.getOperand(0)->getType(), "Logical operators must have same type for operands and result!", @@ -1084,22 +1111,13 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: - Assert1(B.getType()->isInteger() || - (isa<VectorType>(B.getType()) && - cast<VectorType>(B.getType())->getElementType()->isInteger()), + Assert1(B.getType()->isIntOrIntVector(), "Shifts only work with integral types!", &B); Assert1(B.getType() == B.getOperand(0)->getType(), "Shift return type must be same as operands!", &B); - /* FALL THROUGH */ - default: - // Arithmetic operators only work on integer or fp values - Assert1(B.getType() == B.getOperand(0)->getType(), - "Arithmetic operators must have same type for operands and result!", - &B); - Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint() || - isa<VectorType>(B.getType()), - "Arithmetic operators must have integer, fp, or vector type!", &B); break; + default: + assert(0 && "Unknown BinaryOperator opcode!"); } visitInstruction(B); |