Split the Add, Sub, and Mul instruction opcodes into separate

integer and floating-point opcodes, introducing
FAdd, FSub, and FMul.

For now, the AsmParser, BitcodeReader, and IRBuilder all preserve
backwards compatability, and the Core LLVM APIs preserve backwards
compatibility for IR producers. Most front-ends won't need to change
immediately.

This implements the first step of the plan outlined here:
http://nondot.org/sabre/LLVMNotes/IntegerOverflow.txt


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72897 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman
2009-06-04 22:49:04 +00:00
parent d18e31ae17
commit ae3a0be92e
265 changed files with 2374 additions and 1924 deletions

View File

@@ -704,10 +704,14 @@ public:
/// specify the full Instruction::OPCODE identifier.
///
static Constant *getNeg(Constant *C);
static Constant *getFNeg(Constant *C);
static Constant *getNot(Constant *C);
static Constant *getAdd(Constant *C1, Constant *C2);
static Constant *getFAdd(Constant *C1, Constant *C2);
static Constant *getSub(Constant *C1, Constant *C2);
static Constant *getFSub(Constant *C1, Constant *C2);
static Constant *getMul(Constant *C1, Constant *C2);
static Constant *getFMul(Constant *C1, Constant *C2);
static Constant *getUDiv(Constant *C1, Constant *C2);
static Constant *getSDiv(Constant *C1, Constant *C2);
static Constant *getFDiv(Constant *C1, Constant *C2);

View File

@@ -204,21 +204,30 @@ public:
Instruction *InsertBefore = 0);
static BinaryOperator *CreateNeg(Value *Op, const std::string &Name,
BasicBlock *InsertAtEnd);
static BinaryOperator *CreateFNeg(Value *Op, const std::string &Name = "",
Instruction *InsertBefore = 0);
static BinaryOperator *CreateFNeg(Value *Op, const std::string &Name,
BasicBlock *InsertAtEnd);
static BinaryOperator *CreateNot(Value *Op, const std::string &Name = "",
Instruction *InsertBefore = 0);
static BinaryOperator *CreateNot(Value *Op, const std::string &Name,
BasicBlock *InsertAtEnd);
/// isNeg, isNot - Check if the given Value is a NEG or NOT instruction.
/// isNeg, isFNeg, isNot - Check if the given Value is a
/// NEG, FNeg, or NOT instruction.
///
static bool isNeg(const Value *V);
static bool isFNeg(const Value *V);
static bool isNot(const Value *V);
/// getNegArgument, getNotArgument - Helper functions to extract the
/// unary argument of a NEG or NOT operation implemented via Sub or Xor.
/// unary argument of a NEG, FNEG or NOT operation implemented via
/// Sub, FSub, or Xor.
///
static const Value *getNegArgument(const Value *BinOp);
static Value *getNegArgument( Value *BinOp);
static const Value *getFNegArgument(const Value *BinOp);
static Value *getFNegArgument( Value *BinOp);
static const Value *getNotArgument(const Value *BinOp);
static Value *getNotArgument( Value *BinOp);

View File

@@ -105,71 +105,74 @@ HANDLE_TERM_INST ( 6, Unreachable, UnreachableInst)
// Standard binary operators...
FIRST_BINARY_INST( 7)
HANDLE_BINARY_INST( 7, Add , BinaryOperator)
HANDLE_BINARY_INST( 8, Sub , BinaryOperator)
HANDLE_BINARY_INST( 9, Mul , BinaryOperator)
HANDLE_BINARY_INST(10, UDiv , BinaryOperator)
HANDLE_BINARY_INST(11, SDiv , BinaryOperator)
HANDLE_BINARY_INST(12, FDiv , BinaryOperator)
HANDLE_BINARY_INST(13, URem , BinaryOperator)
HANDLE_BINARY_INST(14, SRem , BinaryOperator)
HANDLE_BINARY_INST(15, FRem , BinaryOperator)
HANDLE_BINARY_INST( 8, FAdd , BinaryOperator)
HANDLE_BINARY_INST( 9, Sub , BinaryOperator)
HANDLE_BINARY_INST(10, FSub , BinaryOperator)
HANDLE_BINARY_INST(11, Mul , BinaryOperator)
HANDLE_BINARY_INST(12, FMul , BinaryOperator)
HANDLE_BINARY_INST(13, UDiv , BinaryOperator)
HANDLE_BINARY_INST(14, SDiv , BinaryOperator)
HANDLE_BINARY_INST(15, FDiv , BinaryOperator)
HANDLE_BINARY_INST(16, URem , BinaryOperator)
HANDLE_BINARY_INST(17, SRem , BinaryOperator)
HANDLE_BINARY_INST(18, FRem , BinaryOperator)
// Logical operators (integer operands)
HANDLE_BINARY_INST(16, Shl , BinaryOperator) // Shift left (logical)
HANDLE_BINARY_INST(17, LShr , BinaryOperator) // Shift right (logical)
HANDLE_BINARY_INST(18, AShr , BinaryOperator) // Shift right (arithmetic)
HANDLE_BINARY_INST(19, And , BinaryOperator)
HANDLE_BINARY_INST(20, Or , BinaryOperator)
HANDLE_BINARY_INST(21, Xor , BinaryOperator)
LAST_BINARY_INST(21)
HANDLE_BINARY_INST(19, Shl , BinaryOperator) // Shift left (logical)
HANDLE_BINARY_INST(20, LShr , BinaryOperator) // Shift right (logical)
HANDLE_BINARY_INST(21, AShr , BinaryOperator) // Shift right (arithmetic)
HANDLE_BINARY_INST(22, And , BinaryOperator)
HANDLE_BINARY_INST(23, Or , BinaryOperator)
HANDLE_BINARY_INST(24, Xor , BinaryOperator)
LAST_BINARY_INST(24)
// Memory operators...
FIRST_MEMORY_INST(22)
HANDLE_MEMORY_INST(22, Malloc, MallocInst) // Heap management instructions
HANDLE_MEMORY_INST(23, Free , FreeInst )
HANDLE_MEMORY_INST(24, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(25, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(26, Store , StoreInst )
HANDLE_MEMORY_INST(27, GetElementPtr, GetElementPtrInst)
LAST_MEMORY_INST(27)
FIRST_MEMORY_INST(25)
HANDLE_MEMORY_INST(25, Malloc, MallocInst) // Heap management instructions
HANDLE_MEMORY_INST(26, Free , FreeInst )
HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(29, Store , StoreInst )
HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
LAST_MEMORY_INST(30)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
FIRST_CAST_INST(28)
HANDLE_CAST_INST(28, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(29, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(30, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(31, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(32, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(33, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(34, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(35, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(36, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(37, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(38, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(39, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(39)
FIRST_CAST_INST(31)
HANDLE_CAST_INST(31, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(32, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(33, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(34, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(35, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(36, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(37, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(38, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(39, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(40, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(41, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(42, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(42)
// Other operators...
FIRST_OTHER_INST(40)
HANDLE_OTHER_INST(40, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(41, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(42, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(43, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(44, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(45, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(46, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(47, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(51, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(52, InsertValue, InsertValueInst) // insert into aggregate
HANDLE_OTHER_INST(53, VICmp , VICmpInst ) // Vec Int comparison instruction.
HANDLE_OTHER_INST(54, VFCmp , VFCmpInst ) // Vec FP point comparison instr.
FIRST_OTHER_INST(43)
HANDLE_OTHER_INST(43, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(44, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(45, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(46, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(47, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(48, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(49, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(50, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(51, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(52, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(53, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(54, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(55, InsertValue, InsertValueInst) // insert into aggregate
HANDLE_OTHER_INST(56, VICmp , VICmpInst ) // Vec Int comparison instruction.
HANDLE_OTHER_INST(57, VFCmp , VFCmpInst ) // Vec FP point comparison instr.
LAST_OTHER_INST(55)
LAST_OTHER_INST(57)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST

View File

@@ -32,12 +32,21 @@ public:
Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getAdd(LHS, RHS);
}
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFAdd(LHS, RHS);
}
Constant *CreateSub(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getSub(LHS, RHS);
}
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFSub(LHS, RHS);
}
Constant *CreateMul(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getMul(LHS, RHS);
}
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getFMul(LHS, RHS);
}
Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
return ConstantExpr::getUDiv(LHS, RHS);
}
@@ -87,6 +96,9 @@ public:
Constant *CreateNeg(Constant *C) const {
return ConstantExpr::getNeg(C);
}
Constant *CreateFNeg(Constant *C) const {
return ConstantExpr::getFNeg(C);
}
Constant *CreateNot(Constant *C) const {
return ConstantExpr::getNot(C);
}

View File

@@ -175,18 +175,36 @@ public:
return Folder.CreateAdd(LC, RC);
return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name);
}
Value *CreateFAdd(Value *LHS, Value *RHS, const char *Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFAdd(LC, RC);
return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name);
}
Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateSub(LC, RC);
return Insert(BinaryOperator::CreateSub(LHS, RHS), Name);
}
Value *CreateFSub(Value *LHS, Value *RHS, const char *Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateFSub(LC, RC);
return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name);
}
Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateMul(LC, RC);
return Insert(BinaryOperator::CreateMul(LHS, RHS), Name);
}
Value *CreateFMul(Value *LHS, Value *RHS, const char *Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))
return Folder.CreateMul(LC, RC);
return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name);
}
Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
if (Constant *LC = dyn_cast<Constant>(LHS))
if (Constant *RC = dyn_cast<Constant>(RHS))

View File

@@ -39,12 +39,21 @@ public:
Value *CreateAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateAdd(LHS, RHS);
}
Value *CreateFAdd(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFAdd(LHS, RHS);
}
Value *CreateSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateSub(LHS, RHS);
}
Value *CreateFSub(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFSub(LHS, RHS);
}
Value *CreateMul(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateMul(LHS, RHS);
}
Value *CreateFMul(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateFMul(LHS, RHS);
}
Value *CreateUDiv(Constant *LHS, Constant *RHS) const {
return BinaryOperator::CreateUDiv(LHS, RHS);
}

View File

@@ -156,18 +156,36 @@ inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
}
template<typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::FAdd> m_FAdd(const LHS &L,
const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
}
template<typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
}
template<typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::FSub> m_FSub(const LHS &L,
const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
}
template<typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
}
template<typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::FMul> m_FMul(const LHS &L,
const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
}
template<typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
const RHS &R) {
@@ -494,6 +512,35 @@ template<typename LHS>
inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
template<typename LHS_t>
struct fneg_match {
LHS_t L;
fneg_match(const LHS_t &LHS) : L(LHS) {}
template<typename OpTy>
bool match(OpTy *V) {
if (Instruction *I = dyn_cast<Instruction>(V))
if (I->getOpcode() == Instruction::FSub)
return matchIfFNeg(I->getOperand(0), I->getOperand(1));
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::FSub)
return matchIfFNeg(CE->getOperand(0), CE->getOperand(1));
if (ConstantFP *CF = dyn_cast<ConstantFP>(V))
return L.match(ConstantExpr::getFNeg(CF));
return false;
}
private:
bool matchIfFNeg(Value *LHS, Value *RHS) {
return LHS == ConstantExpr::getZeroValueForNegationExpr(LHS->getType()) &&
L.match(RHS);
}
};
template<typename LHS>
inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
//===----------------------------------------------------------------------===//
// Matchers for control flow
//

View File

@@ -48,12 +48,21 @@ public:
Constant *CreateAdd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getAdd(LHS, RHS));
}
Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFAdd(LHS, RHS));
}
Constant *CreateSub(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getSub(LHS, RHS));
}
Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFSub(LHS, RHS));
}
Constant *CreateMul(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getMul(LHS, RHS));
}
Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getFMul(LHS, RHS));
}
Constant *CreateUDiv(Constant *LHS, Constant *RHS) const {
return Fold(ConstantExpr::getUDiv(LHS, RHS));
}
@@ -103,6 +112,9 @@ public:
Constant *CreateNeg(Constant *C) const {
return Fold(ConstantExpr::getNeg(C));
}
Constant *CreateFNeg(Constant *C) const {
return Fold(ConstantExpr::getFNeg(C));
}
Constant *CreateNot(Constant *C) const {
return Fold(ConstantExpr::getNot(C));
}