mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[IR] Add a dedicated FNeg IR Instruction
The IEEE-754 Standard makes it clear that fneg(x) and fsub(-0.0, x) are two different operations. The former is a bitwise operation, while the latter is an arithmetic operation. This patch creates a dedicated FNeg IR Instruction to model that behavior. Differential Revision: https://reviews.llvm.org/D53877 llvm-svn: 346774
This commit is contained in:
parent
71947d8d0a
commit
3a2064d3a0
@ -54,6 +54,8 @@ extern "C" {
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/// External users depend on the following values being stable. It is not safe
|
||||||
|
/// to reorder them.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* Terminator Instructions */
|
/* Terminator Instructions */
|
||||||
LLVMRet = 1,
|
LLVMRet = 1,
|
||||||
@ -64,6 +66,9 @@ typedef enum {
|
|||||||
/* removed 6 due to API changes */
|
/* removed 6 due to API changes */
|
||||||
LLVMUnreachable = 7,
|
LLVMUnreachable = 7,
|
||||||
|
|
||||||
|
/* Standard Unary Operators */
|
||||||
|
LLVMFNeg = 66,
|
||||||
|
|
||||||
/* Standard Binary Operators */
|
/* Standard Binary Operators */
|
||||||
LLVMAdd = 8,
|
LLVMAdd = 8,
|
||||||
LLVMFAdd = 9,
|
LLVMFAdd = 9,
|
||||||
|
@ -342,6 +342,7 @@ enum ConstantsCodes {
|
|||||||
CST_CODE_INLINEASM = 23, // INLINEASM: [sideeffect|alignstack|
|
CST_CODE_INLINEASM = 23, // INLINEASM: [sideeffect|alignstack|
|
||||||
// asmdialect,asmstr,conststr]
|
// asmdialect,asmstr,conststr]
|
||||||
CST_CODE_CE_GEP_WITH_INRANGE_INDEX = 24, // [opty, flags, n x operands]
|
CST_CODE_CE_GEP_WITH_INRANGE_INDEX = 24, // [opty, flags, n x operands]
|
||||||
|
CST_CODE_CE_UNOP = 25, // CE_UNOP: [opcode, opval]
|
||||||
};
|
};
|
||||||
|
|
||||||
/// CastOpcodes - These are values used in the bitcode files to encode which
|
/// CastOpcodes - These are values used in the bitcode files to encode which
|
||||||
@ -364,6 +365,14 @@ enum CastOpcodes {
|
|||||||
CAST_ADDRSPACECAST = 12
|
CAST_ADDRSPACECAST = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// UnaryOpcodes - These are values used in the bitcode files to encode which
|
||||||
|
/// unop a CST_CODE_CE_UNOP or a XXX refers to. The values of these enums
|
||||||
|
/// have no fixed relation to the LLVM IR enum values. Changing these will
|
||||||
|
/// break compatibility with old files.
|
||||||
|
enum UnaryOpcodes {
|
||||||
|
UNOP_NEG = 0
|
||||||
|
};
|
||||||
|
|
||||||
/// BinaryOpcodes - These are values used in the bitcode files to encode which
|
/// BinaryOpcodes - These are values used in the bitcode files to encode which
|
||||||
/// binop a CST_CODE_CE_BINOP or a XXX refers to. The values of these enums
|
/// binop a CST_CODE_CE_BINOP or a XXX refers to. The values of these enums
|
||||||
/// have no fixed relation to the LLVM IR enum values. Changing these will
|
/// have no fixed relation to the LLVM IR enum values. Changing these will
|
||||||
@ -524,6 +533,7 @@ enum FunctionCodes {
|
|||||||
// 53 is unused.
|
// 53 is unused.
|
||||||
// 54 is unused.
|
// 54 is unused.
|
||||||
FUNC_CODE_OPERAND_BUNDLE = 55, // OPERAND_BUNDLE: [tag#, value...]
|
FUNC_CODE_OPERAND_BUNDLE = 55, // OPERAND_BUNDLE: [tag#, value...]
|
||||||
|
FUNC_CODE_INST_UNOP = 56, // UNOP: [opcode, ty, opval]
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UseListCodes {
|
enum UseListCodes {
|
||||||
|
@ -300,6 +300,8 @@ private:
|
|||||||
|
|
||||||
bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
|
bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
|
||||||
|
|
||||||
|
bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
|
||||||
|
|
||||||
bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
|
bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
|
||||||
return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
|
return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
|
||||||
}
|
}
|
||||||
|
@ -1114,6 +1114,13 @@ public:
|
|||||||
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2,
|
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2,
|
||||||
Type *OnlyIfReducedTy = nullptr);
|
Type *OnlyIfReducedTy = nullptr);
|
||||||
|
|
||||||
|
/// get - Return a unary operator constant expression,
|
||||||
|
/// folding if possible.
|
||||||
|
///
|
||||||
|
/// \param OnlyIfReducedTy see \a getWithOperands() docs.
|
||||||
|
static Constant *get(unsigned Opcode, Constant *C1, unsigned Flags = 0,
|
||||||
|
Type *OnlyIfReducedTy = nullptr);
|
||||||
|
|
||||||
/// get - Return a binary or shift operator constant expression,
|
/// get - Return a binary or shift operator constant expression,
|
||||||
/// folding if possible.
|
/// folding if possible.
|
||||||
///
|
///
|
||||||
|
@ -263,6 +263,7 @@ public:
|
|||||||
// of instructions...
|
// of instructions...
|
||||||
//
|
//
|
||||||
RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);}
|
RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);}
|
||||||
|
RetTy visitUnaryOperator(UnaryOperator &I) { DELEGATE(UnaryInstruction);}
|
||||||
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);}
|
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);}
|
||||||
RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);}
|
RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);}
|
||||||
RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
|
RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
|
||||||
|
@ -32,6 +32,20 @@
|
|||||||
#define LAST_TERM_INST(num)
|
#define LAST_TERM_INST(num)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FIRST_UNARY_INST
|
||||||
|
#define FIRST_UNARY_INST(num)
|
||||||
|
#endif
|
||||||
|
#ifndef HANDLE_UNARY_INST
|
||||||
|
#ifndef HANDLE_INST
|
||||||
|
#define HANDLE_UNARY_INST(num, opcode, instclass)
|
||||||
|
#else
|
||||||
|
#define HANDLE_UNARY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef LAST_UNARY_INST
|
||||||
|
#define LAST_UNARY_INST(num)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FIRST_BINARY_INST
|
#ifndef FIRST_BINARY_INST
|
||||||
#define FIRST_BINARY_INST(num)
|
#define FIRST_BINARY_INST(num)
|
||||||
#endif
|
#endif
|
||||||
@ -123,87 +137,96 @@ HANDLE_TERM_INST ( 9, CatchRet , CatchReturnInst)
|
|||||||
HANDLE_TERM_INST (10, CatchSwitch , CatchSwitchInst)
|
HANDLE_TERM_INST (10, CatchSwitch , CatchSwitchInst)
|
||||||
LAST_TERM_INST (10)
|
LAST_TERM_INST (10)
|
||||||
|
|
||||||
|
// Standard unary operators...
|
||||||
|
FIRST_UNARY_INST(11)
|
||||||
|
HANDLE_UNARY_INST(11, FNeg , UnaryOperator)
|
||||||
|
LAST_UNARY_INST(11)
|
||||||
|
|
||||||
// Standard binary operators...
|
// Standard binary operators...
|
||||||
FIRST_BINARY_INST(11)
|
FIRST_BINARY_INST(12)
|
||||||
HANDLE_BINARY_INST(11, Add , BinaryOperator)
|
HANDLE_BINARY_INST(12, Add , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(12, FAdd , BinaryOperator)
|
HANDLE_BINARY_INST(13, FAdd , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(13, Sub , BinaryOperator)
|
HANDLE_BINARY_INST(14, Sub , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(14, FSub , BinaryOperator)
|
HANDLE_BINARY_INST(15, FSub , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(15, Mul , BinaryOperator)
|
HANDLE_BINARY_INST(16, Mul , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(16, FMul , BinaryOperator)
|
HANDLE_BINARY_INST(17, FMul , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(17, UDiv , BinaryOperator)
|
HANDLE_BINARY_INST(18, UDiv , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(18, SDiv , BinaryOperator)
|
HANDLE_BINARY_INST(19, SDiv , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(19, FDiv , BinaryOperator)
|
HANDLE_BINARY_INST(20, FDiv , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(20, URem , BinaryOperator)
|
HANDLE_BINARY_INST(21, URem , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(21, SRem , BinaryOperator)
|
HANDLE_BINARY_INST(22, SRem , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(22, FRem , BinaryOperator)
|
HANDLE_BINARY_INST(23, FRem , BinaryOperator)
|
||||||
|
|
||||||
// Logical operators (integer operands)
|
// Logical operators (integer operands)
|
||||||
HANDLE_BINARY_INST(23, Shl , BinaryOperator) // Shift left (logical)
|
HANDLE_BINARY_INST(24, Shl , BinaryOperator) // Shift left (logical)
|
||||||
HANDLE_BINARY_INST(24, LShr , BinaryOperator) // Shift right (logical)
|
HANDLE_BINARY_INST(25, LShr , BinaryOperator) // Shift right (logical)
|
||||||
HANDLE_BINARY_INST(25, AShr , BinaryOperator) // Shift right (arithmetic)
|
HANDLE_BINARY_INST(26, AShr , BinaryOperator) // Shift right (arithmetic)
|
||||||
HANDLE_BINARY_INST(26, And , BinaryOperator)
|
HANDLE_BINARY_INST(27, And , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(27, Or , BinaryOperator)
|
HANDLE_BINARY_INST(28, Or , BinaryOperator)
|
||||||
HANDLE_BINARY_INST(28, Xor , BinaryOperator)
|
HANDLE_BINARY_INST(29, Xor , BinaryOperator)
|
||||||
LAST_BINARY_INST(28)
|
LAST_BINARY_INST(29)
|
||||||
|
|
||||||
// Memory operators...
|
// Memory operators...
|
||||||
FIRST_MEMORY_INST(29)
|
FIRST_MEMORY_INST(30)
|
||||||
HANDLE_MEMORY_INST(29, Alloca, AllocaInst) // Stack management
|
HANDLE_MEMORY_INST(30, Alloca, AllocaInst) // Stack management
|
||||||
HANDLE_MEMORY_INST(30, Load , LoadInst ) // Memory manipulation instrs
|
HANDLE_MEMORY_INST(31, Load , LoadInst ) // Memory manipulation instrs
|
||||||
HANDLE_MEMORY_INST(31, Store , StoreInst )
|
HANDLE_MEMORY_INST(32, Store , StoreInst )
|
||||||
HANDLE_MEMORY_INST(32, GetElementPtr, GetElementPtrInst)
|
HANDLE_MEMORY_INST(33, GetElementPtr, GetElementPtrInst)
|
||||||
HANDLE_MEMORY_INST(33, Fence , FenceInst )
|
HANDLE_MEMORY_INST(34, Fence , FenceInst )
|
||||||
HANDLE_MEMORY_INST(34, AtomicCmpXchg , AtomicCmpXchgInst )
|
HANDLE_MEMORY_INST(35, AtomicCmpXchg , AtomicCmpXchgInst )
|
||||||
HANDLE_MEMORY_INST(35, AtomicRMW , AtomicRMWInst )
|
HANDLE_MEMORY_INST(36, AtomicRMW , AtomicRMWInst )
|
||||||
LAST_MEMORY_INST(35)
|
LAST_MEMORY_INST(36)
|
||||||
|
|
||||||
// Cast operators ...
|
// Cast operators ...
|
||||||
// NOTE: The order matters here because CastInst::isEliminableCastPair
|
// NOTE: The order matters here because CastInst::isEliminableCastPair
|
||||||
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
|
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
|
||||||
FIRST_CAST_INST(36)
|
FIRST_CAST_INST(37)
|
||||||
HANDLE_CAST_INST(36, Trunc , TruncInst ) // Truncate integers
|
HANDLE_CAST_INST(37, Trunc , TruncInst ) // Truncate integers
|
||||||
HANDLE_CAST_INST(37, ZExt , ZExtInst ) // Zero extend integers
|
HANDLE_CAST_INST(38, ZExt , ZExtInst ) // Zero extend integers
|
||||||
HANDLE_CAST_INST(38, SExt , SExtInst ) // Sign extend integers
|
HANDLE_CAST_INST(39, SExt , SExtInst ) // Sign extend integers
|
||||||
HANDLE_CAST_INST(39, FPToUI , FPToUIInst ) // floating point -> UInt
|
HANDLE_CAST_INST(40, FPToUI , FPToUIInst ) // floating point -> UInt
|
||||||
HANDLE_CAST_INST(40, FPToSI , FPToSIInst ) // floating point -> SInt
|
HANDLE_CAST_INST(41, FPToSI , FPToSIInst ) // floating point -> SInt
|
||||||
HANDLE_CAST_INST(41, UIToFP , UIToFPInst ) // UInt -> floating point
|
HANDLE_CAST_INST(42, UIToFP , UIToFPInst ) // UInt -> floating point
|
||||||
HANDLE_CAST_INST(42, SIToFP , SIToFPInst ) // SInt -> floating point
|
HANDLE_CAST_INST(43, SIToFP , SIToFPInst ) // SInt -> floating point
|
||||||
HANDLE_CAST_INST(43, FPTrunc , FPTruncInst ) // Truncate floating point
|
HANDLE_CAST_INST(44, FPTrunc , FPTruncInst ) // Truncate floating point
|
||||||
HANDLE_CAST_INST(44, FPExt , FPExtInst ) // Extend floating point
|
HANDLE_CAST_INST(45, FPExt , FPExtInst ) // Extend floating point
|
||||||
HANDLE_CAST_INST(45, PtrToInt, PtrToIntInst) // Pointer -> Integer
|
HANDLE_CAST_INST(46, PtrToInt, PtrToIntInst) // Pointer -> Integer
|
||||||
HANDLE_CAST_INST(46, IntToPtr, IntToPtrInst) // Integer -> Pointer
|
HANDLE_CAST_INST(47, IntToPtr, IntToPtrInst) // Integer -> Pointer
|
||||||
HANDLE_CAST_INST(47, BitCast , BitCastInst ) // Type cast
|
HANDLE_CAST_INST(48, BitCast , BitCastInst ) // Type cast
|
||||||
HANDLE_CAST_INST(48, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
|
HANDLE_CAST_INST(49, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
|
||||||
LAST_CAST_INST(48)
|
LAST_CAST_INST(49)
|
||||||
|
|
||||||
FIRST_FUNCLETPAD_INST(49)
|
FIRST_FUNCLETPAD_INST(50)
|
||||||
HANDLE_FUNCLETPAD_INST(49, CleanupPad, CleanupPadInst)
|
HANDLE_FUNCLETPAD_INST(50, CleanupPad, CleanupPadInst)
|
||||||
HANDLE_FUNCLETPAD_INST(50, CatchPad , CatchPadInst)
|
HANDLE_FUNCLETPAD_INST(51, CatchPad , CatchPadInst)
|
||||||
LAST_FUNCLETPAD_INST(50)
|
LAST_FUNCLETPAD_INST(51)
|
||||||
|
|
||||||
// Other operators...
|
// Other operators...
|
||||||
FIRST_OTHER_INST(51)
|
FIRST_OTHER_INST(52)
|
||||||
HANDLE_OTHER_INST(51, ICmp , ICmpInst ) // Integer comparison instruction
|
HANDLE_OTHER_INST(52, ICmp , ICmpInst ) // Integer comparison instruction
|
||||||
HANDLE_OTHER_INST(52, FCmp , FCmpInst ) // Floating point comparison instr.
|
HANDLE_OTHER_INST(53, FCmp , FCmpInst ) // Floating point comparison instr.
|
||||||
HANDLE_OTHER_INST(53, PHI , PHINode ) // PHI node instruction
|
HANDLE_OTHER_INST(54, PHI , PHINode ) // PHI node instruction
|
||||||
HANDLE_OTHER_INST(54, Call , CallInst ) // Call a function
|
HANDLE_OTHER_INST(55, Call , CallInst ) // Call a function
|
||||||
HANDLE_OTHER_INST(55, Select , SelectInst ) // select instruction
|
HANDLE_OTHER_INST(56, Select , SelectInst ) // select instruction
|
||||||
HANDLE_USER_INST (56, UserOp1, Instruction) // May be used internally in a pass
|
HANDLE_USER_INST (57, UserOp1, Instruction) // May be used internally in a pass
|
||||||
HANDLE_USER_INST (57, UserOp2, Instruction) // Internal to passes only
|
HANDLE_USER_INST (58, UserOp2, Instruction) // Internal to passes only
|
||||||
HANDLE_OTHER_INST(58, VAArg , VAArgInst ) // vaarg instruction
|
HANDLE_OTHER_INST(59, VAArg , VAArgInst ) // vaarg instruction
|
||||||
HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector
|
HANDLE_OTHER_INST(60, ExtractElement, ExtractElementInst)// extract from vector
|
||||||
HANDLE_OTHER_INST(60, InsertElement, InsertElementInst) // insert into vector
|
HANDLE_OTHER_INST(61, InsertElement, InsertElementInst) // insert into vector
|
||||||
HANDLE_OTHER_INST(61, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
|
HANDLE_OTHER_INST(62, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
|
||||||
HANDLE_OTHER_INST(62, ExtractValue, ExtractValueInst)// extract from aggregate
|
HANDLE_OTHER_INST(63, ExtractValue, ExtractValueInst)// extract from aggregate
|
||||||
HANDLE_OTHER_INST(63, InsertValue, InsertValueInst) // insert into aggregate
|
HANDLE_OTHER_INST(64, InsertValue, InsertValueInst) // insert into aggregate
|
||||||
HANDLE_OTHER_INST(64, LandingPad, LandingPadInst) // Landing pad instruction.
|
HANDLE_OTHER_INST(65, LandingPad, LandingPadInst) // Landing pad instruction.
|
||||||
LAST_OTHER_INST(64)
|
LAST_OTHER_INST(65)
|
||||||
|
|
||||||
#undef FIRST_TERM_INST
|
#undef FIRST_TERM_INST
|
||||||
#undef HANDLE_TERM_INST
|
#undef HANDLE_TERM_INST
|
||||||
#undef LAST_TERM_INST
|
#undef LAST_TERM_INST
|
||||||
|
|
||||||
|
#undef FIRST_UNARY_INST
|
||||||
|
#undef HANDLE_UNARY_INST
|
||||||
|
#undef LAST_UNARY_INST
|
||||||
|
|
||||||
#undef FIRST_BINARY_INST
|
#undef FIRST_BINARY_INST
|
||||||
#undef HANDLE_BINARY_INST
|
#undef HANDLE_BINARY_INST
|
||||||
#undef LAST_BINARY_INST
|
#undef LAST_BINARY_INST
|
||||||
|
@ -127,6 +127,7 @@ public:
|
|||||||
|
|
||||||
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
|
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
|
||||||
bool isTerminator() const { return isTerminator(getOpcode()); }
|
bool isTerminator() const { return isTerminator(getOpcode()); }
|
||||||
|
bool isUnaryOp() const { return isUnaryOp(getOpcode()); }
|
||||||
bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
|
bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
|
||||||
bool isIntDivRem() const { return isIntDivRem(getOpcode()); }
|
bool isIntDivRem() const { return isIntDivRem(getOpcode()); }
|
||||||
bool isShift() { return isShift(getOpcode()); }
|
bool isShift() { return isShift(getOpcode()); }
|
||||||
@ -142,6 +143,9 @@ public:
|
|||||||
return OpCode >= TermOpsBegin && OpCode < TermOpsEnd;
|
return OpCode >= TermOpsBegin && OpCode < TermOpsEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool isUnaryOp(unsigned Opcode) {
|
||||||
|
return Opcode >= UnaryOpsBegin && Opcode < UnaryOpsEnd;
|
||||||
|
}
|
||||||
static inline bool isBinaryOp(unsigned Opcode) {
|
static inline bool isBinaryOp(unsigned Opcode) {
|
||||||
return Opcode >= BinaryOpsBegin && Opcode < BinaryOpsEnd;
|
return Opcode >= BinaryOpsBegin && Opcode < BinaryOpsEnd;
|
||||||
}
|
}
|
||||||
@ -662,6 +666,13 @@ public:
|
|||||||
#include "llvm/IR/Instruction.def"
|
#include "llvm/IR/Instruction.def"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum UnaryOps {
|
||||||
|
#define FIRST_UNARY_INST(N) UnaryOpsBegin = N,
|
||||||
|
#define HANDLE_UNARY_INST(N, OPC, CLASS) OPC = N,
|
||||||
|
#define LAST_UNARY_INST(N) UnaryOpsEnd = N+1
|
||||||
|
#include "llvm/IR/Instruction.def"
|
||||||
|
};
|
||||||
|
|
||||||
enum BinaryOps {
|
enum BinaryOps {
|
||||||
#define FIRST_BINARY_INST(N) BinaryOpsBegin = N,
|
#define FIRST_BINARY_INST(N) BinaryOpsBegin = N,
|
||||||
#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
|
#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
|
||||||
|
@ -1103,6 +1103,71 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
|
|||||||
|
|
||||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
|
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// UnaryOperator Class
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// a unary instruction
|
||||||
|
class UnaryOperator : public UnaryInstruction {
|
||||||
|
void AssertOK();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UnaryOperator(UnaryOps iType, Value *S, Type *Ty,
|
||||||
|
const Twine &Name, Instruction *InsertBefore);
|
||||||
|
UnaryOperator(UnaryOps iType, Value *S, Type *Ty,
|
||||||
|
const Twine &Name, BasicBlock *InsertAtEnd);
|
||||||
|
|
||||||
|
// Note: Instruction needs to be a friend here to call cloneImpl.
|
||||||
|
friend class Instruction;
|
||||||
|
|
||||||
|
UnaryOperator *cloneImpl() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Construct a unary instruction, given the opcode and an operand.
|
||||||
|
/// Optionally (if InstBefore is specified) insert the instruction
|
||||||
|
/// into a BasicBlock right before the specified instruction. The specified
|
||||||
|
/// Instruction is allowed to be a dereferenced end iterator.
|
||||||
|
///
|
||||||
|
static UnaryOperator *Create(UnaryOps Op, Value *S,
|
||||||
|
const Twine &Name = Twine(),
|
||||||
|
Instruction *InsertBefore = nullptr);
|
||||||
|
|
||||||
|
/// Construct a unary instruction, given the opcode and an operand.
|
||||||
|
/// Also automatically insert this instruction to the end of the
|
||||||
|
/// BasicBlock specified.
|
||||||
|
///
|
||||||
|
static UnaryOperator *Create(UnaryOps Op, Value *S,
|
||||||
|
const Twine &Name,
|
||||||
|
BasicBlock *InsertAtEnd);
|
||||||
|
|
||||||
|
/// These methods just forward to Create, and are useful when you
|
||||||
|
/// statically know what type of instruction you're going to create. These
|
||||||
|
/// helpers just save some typing.
|
||||||
|
#define HANDLE_UNARY_INST(N, OPC, CLASS) \
|
||||||
|
static UnaryInstruction *Create##OPC(Value *V, \
|
||||||
|
const Twine &Name = "") {\
|
||||||
|
return Create(Instruction::OPC, V, Name);\
|
||||||
|
}
|
||||||
|
#include "llvm/IR/Instruction.def"
|
||||||
|
#define HANDLE_UNARY_INST(N, OPC, CLASS) \
|
||||||
|
static UnaryInstruction *Create##OPC(Value *V, \
|
||||||
|
const Twine &Name, BasicBlock *BB) {\
|
||||||
|
return Create(Instruction::OPC, V, Name, BB);\
|
||||||
|
}
|
||||||
|
#include "llvm/IR/Instruction.def"
|
||||||
|
#define HANDLE_UNARY_INST(N, OPC, CLASS) \
|
||||||
|
static UnaryInstruction *Create##OPC(Value *V, \
|
||||||
|
const Twine &Name, Instruction *I) {\
|
||||||
|
return Create(Instruction::OPC, V, Name, I);\
|
||||||
|
}
|
||||||
|
#include "llvm/IR/Instruction.def"
|
||||||
|
|
||||||
|
UnaryOps getOpcode() const {
|
||||||
|
return static_cast<UnaryOps>(Instruction::getOpcode());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ICmpInst Class
|
// ICmpInst Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -823,6 +823,8 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||||||
} \
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
INSTKEYWORD(fneg, FNeg);
|
||||||
|
|
||||||
INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd);
|
INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd);
|
||||||
INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub);
|
INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub);
|
||||||
INSTKEYWORD(mul, Mul); INSTKEYWORD(fmul, FMul);
|
INSTKEYWORD(mul, Mul); INSTKEYWORD(fmul, FMul);
|
||||||
|
@ -3295,7 +3295,31 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
|
|||||||
ID.Kind = ValID::t_Constant;
|
ID.Kind = ValID::t_Constant;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unary Operators.
|
||||||
|
case lltok::kw_fneg: {
|
||||||
|
unsigned Opc = Lex.getUIntVal();
|
||||||
|
Constant *Val;
|
||||||
|
Lex.Lex();
|
||||||
|
if (ParseToken(lltok::lparen, "expected '(' in unary constantexpr") ||
|
||||||
|
ParseGlobalTypeAndValue(Val) ||
|
||||||
|
ParseToken(lltok::rparen, "expected ')' in unary constantexpr"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Check that the type is valid for the operator.
|
||||||
|
switch (Opc) {
|
||||||
|
case Instruction::FNeg:
|
||||||
|
if (!Val->getType()->isFPOrFPVectorTy())
|
||||||
|
return Error(ID.Loc, "constexpr requires fp operands");
|
||||||
|
break;
|
||||||
|
default: llvm_unreachable("Unknown unary operator!");
|
||||||
|
}
|
||||||
|
unsigned Flags = 0;
|
||||||
|
Constant *C = ConstantExpr::get(Opc, Val, Flags);
|
||||||
|
ID.ConstantVal = C;
|
||||||
|
ID.Kind = ValID::t_Constant;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Binary Operators.
|
// Binary Operators.
|
||||||
case lltok::kw_add:
|
case lltok::kw_add:
|
||||||
case lltok::kw_fadd:
|
case lltok::kw_fadd:
|
||||||
@ -5492,6 +5516,16 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
|||||||
case lltok::kw_catchswitch: return ParseCatchSwitch(Inst, PFS);
|
case lltok::kw_catchswitch: return ParseCatchSwitch(Inst, PFS);
|
||||||
case lltok::kw_catchpad: return ParseCatchPad(Inst, PFS);
|
case lltok::kw_catchpad: return ParseCatchPad(Inst, PFS);
|
||||||
case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS);
|
case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS);
|
||||||
|
// Unary Operators.
|
||||||
|
case lltok::kw_fneg: {
|
||||||
|
FastMathFlags FMF = EatFastMathFlagsIfPresent();
|
||||||
|
int Res = ParseUnaryOp(Inst, PFS, KeywordVal, 2);
|
||||||
|
if (Res != 0)
|
||||||
|
return Res;
|
||||||
|
if (FMF.any())
|
||||||
|
Inst->setFastMathFlags(FMF);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Binary Operators.
|
// Binary Operators.
|
||||||
case lltok::kw_add:
|
case lltok::kw_add:
|
||||||
case lltok::kw_sub:
|
case lltok::kw_sub:
|
||||||
@ -6063,6 +6097,43 @@ bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Unary Operators.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// ParseUnaryOp
|
||||||
|
/// ::= UnaryOp TypeAndValue ',' Value
|
||||||
|
///
|
||||||
|
/// If OperandType is 0, then any FP or integer operand is allowed. If it is 1,
|
||||||
|
/// then any integer operand is allowed, if it is 2, any fp operand is allowed.
|
||||||
|
bool LLParser::ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS,
|
||||||
|
unsigned Opc, unsigned OperandType) {
|
||||||
|
LocTy Loc; Value *LHS;
|
||||||
|
if (ParseTypeAndValue(LHS, Loc, PFS))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool Valid;
|
||||||
|
switch (OperandType) {
|
||||||
|
default: llvm_unreachable("Unknown operand type!");
|
||||||
|
case 0: // int or FP.
|
||||||
|
Valid = LHS->getType()->isIntOrIntVectorTy() ||
|
||||||
|
LHS->getType()->isFPOrFPVectorTy();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Valid = LHS->getType()->isIntOrIntVectorTy();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Valid = LHS->getType()->isFPOrFPVectorTy();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Valid)
|
||||||
|
return Error(Loc, "invalid operand type for instruction");
|
||||||
|
|
||||||
|
Inst = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Binary Operators.
|
// Binary Operators.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -571,6 +571,8 @@ namespace llvm {
|
|||||||
bool ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS);
|
bool ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS);
|
||||||
bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS);
|
bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS);
|
||||||
|
|
||||||
|
bool ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,
|
||||||
|
unsigned OperandType);
|
||||||
bool ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,
|
bool ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,
|
||||||
unsigned OperandType);
|
unsigned OperandType);
|
||||||
bool ParseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
|
bool ParseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
|
||||||
|
@ -270,6 +270,7 @@ enum Kind {
|
|||||||
kw_umin,
|
kw_umin,
|
||||||
|
|
||||||
// Instruction Opcodes (Opcode in UIntVal).
|
// Instruction Opcodes (Opcode in UIntVal).
|
||||||
|
kw_fneg,
|
||||||
kw_add,
|
kw_add,
|
||||||
kw_fadd,
|
kw_fadd,
|
||||||
kw_sub,
|
kw_sub,
|
||||||
|
@ -964,6 +964,20 @@ static int getDecodedCastOpcode(unsigned Val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int getDecodedUnaryOpcode(unsigned Val, Type *Ty) {
|
||||||
|
bool IsFP = Ty->isFPOrFPVectorTy();
|
||||||
|
// UnOps are only valid for int/fp or vector of int/fp types
|
||||||
|
if (!IsFP && !Ty->isIntOrIntVectorTy())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (Val) {
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
case bitc::UNOP_NEG:
|
||||||
|
return IsFP ? Instruction::FNeg : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int getDecodedBinaryOpcode(unsigned Val, Type *Ty) {
|
static int getDecodedBinaryOpcode(unsigned Val, Type *Ty) {
|
||||||
bool IsFP = Ty->isFPOrFPVectorTy();
|
bool IsFP = Ty->isFPOrFPVectorTy();
|
||||||
// BinOps are only valid for int/fp or vector of int/fp types
|
// BinOps are only valid for int/fp or vector of int/fp types
|
||||||
@ -2317,6 +2331,19 @@ Error BitcodeReader::parseConstants() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case bitc::CST_CODE_CE_UNOP: { // CE_UNOP: [opcode, opval]
|
||||||
|
if (Record.size() < 2)
|
||||||
|
return error("Invalid record");
|
||||||
|
int Opc = getDecodedUnaryOpcode(Record[0], CurTy);
|
||||||
|
if (Opc < 0) {
|
||||||
|
V = UndefValue::get(CurTy); // Unknown unop.
|
||||||
|
} else {
|
||||||
|
Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
|
||||||
|
unsigned Flags = 0;
|
||||||
|
V = ConstantExpr::get(Opc, LHS, Flags);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval]
|
case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval]
|
||||||
if (Record.size() < 3)
|
if (Record.size() < 3)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
@ -3535,7 +3562,27 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|||||||
I = nullptr;
|
I = nullptr;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case bitc::FUNC_CODE_INST_UNOP: { // UNOP: [opval, ty, opcode]
|
||||||
|
unsigned OpNum = 0;
|
||||||
|
Value *LHS;
|
||||||
|
if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
|
||||||
|
OpNum+1 > Record.size())
|
||||||
|
return error("Invalid record");
|
||||||
|
|
||||||
|
int Opc = getDecodedUnaryOpcode(Record[OpNum++], LHS->getType());
|
||||||
|
if (Opc == -1)
|
||||||
|
return error("Invalid record");
|
||||||
|
I = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS);
|
||||||
|
InstructionList.push_back(I);
|
||||||
|
if (OpNum < Record.size()) {
|
||||||
|
if (isa<FPMathOperator>(I)) {
|
||||||
|
FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]);
|
||||||
|
if (FMF.any())
|
||||||
|
I->setFastMathFlags(FMF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
|
case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
|
||||||
unsigned OpNum = 0;
|
unsigned OpNum = 0;
|
||||||
Value *LHS, *RHS;
|
Value *LHS, *RHS;
|
||||||
|
@ -112,6 +112,8 @@ enum {
|
|||||||
|
|
||||||
// FUNCTION_BLOCK abbrev id's.
|
// FUNCTION_BLOCK abbrev id's.
|
||||||
FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
|
FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
|
||||||
|
FUNCTION_INST_UNOP_ABBREV,
|
||||||
|
FUNCTION_INST_UNOP_FLAGS_ABBREV,
|
||||||
FUNCTION_INST_BINOP_ABBREV,
|
FUNCTION_INST_BINOP_ABBREV,
|
||||||
FUNCTION_INST_BINOP_FLAGS_ABBREV,
|
FUNCTION_INST_BINOP_FLAGS_ABBREV,
|
||||||
FUNCTION_INST_CAST_ABBREV,
|
FUNCTION_INST_CAST_ABBREV,
|
||||||
@ -513,6 +515,13 @@ static unsigned getEncodedCastOpcode(unsigned Opcode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned getEncodedUnaryOpcode(unsigned Opcode) {
|
||||||
|
switch (Opcode) {
|
||||||
|
default: llvm_unreachable("Unknown binary instruction!");
|
||||||
|
case Instruction::FNeg: return bitc::UNOP_NEG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned getEncodedBinaryOpcode(unsigned Opcode) {
|
static unsigned getEncodedBinaryOpcode(unsigned Opcode) {
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
default: llvm_unreachable("Unknown binary instruction!");
|
default: llvm_unreachable("Unknown binary instruction!");
|
||||||
@ -2384,6 +2393,16 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
|
|||||||
Record.push_back(Flags);
|
Record.push_back(Flags);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Instruction::FNeg: {
|
||||||
|
assert(CE->getNumOperands() == 1 && "Unknown constant expr!");
|
||||||
|
Code = bitc::CST_CODE_CE_UNOP;
|
||||||
|
Record.push_back(getEncodedUnaryOpcode(CE->getOpcode()));
|
||||||
|
Record.push_back(VE.getValueID(C->getOperand(0)));
|
||||||
|
uint64_t Flags = getOptimizationFlags(CE);
|
||||||
|
if (Flags != 0)
|
||||||
|
Record.push_back(Flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Instruction::GetElementPtr: {
|
case Instruction::GetElementPtr: {
|
||||||
Code = bitc::CST_CODE_CE_GEP;
|
Code = bitc::CST_CODE_CE_GEP;
|
||||||
const auto *GO = cast<GEPOperator>(C);
|
const auto *GO = cast<GEPOperator>(C);
|
||||||
@ -2556,7 +2575,19 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Instruction::FNeg: {
|
||||||
|
Code = bitc::FUNC_CODE_INST_UNOP;
|
||||||
|
if (!pushValueAndType(I.getOperand(0), InstID, Vals))
|
||||||
|
AbbrevToUse = FUNCTION_INST_UNOP_ABBREV;
|
||||||
|
Vals.push_back(getEncodedUnaryOpcode(I.getOpcode()));
|
||||||
|
uint64_t Flags = getOptimizationFlags(&I);
|
||||||
|
if (Flags != 0) {
|
||||||
|
if (AbbrevToUse == FUNCTION_INST_UNOP_ABBREV)
|
||||||
|
AbbrevToUse = FUNCTION_INST_UNOP_FLAGS_ABBREV;
|
||||||
|
Vals.push_back(Flags);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Instruction::GetElementPtr: {
|
case Instruction::GetElementPtr: {
|
||||||
Code = bitc::FUNC_CODE_INST_GEP;
|
Code = bitc::FUNC_CODE_INST_GEP;
|
||||||
AbbrevToUse = FUNCTION_INST_GEP_ABBREV;
|
AbbrevToUse = FUNCTION_INST_GEP_ABBREV;
|
||||||
@ -3217,6 +3248,25 @@ void ModuleBitcodeWriter::writeBlockInfo() {
|
|||||||
FUNCTION_INST_LOAD_ABBREV)
|
FUNCTION_INST_LOAD_ABBREV)
|
||||||
llvm_unreachable("Unexpected abbrev ordering!");
|
llvm_unreachable("Unexpected abbrev ordering!");
|
||||||
}
|
}
|
||||||
|
{ // INST_UNOP abbrev for FUNCTION_BLOCK.
|
||||||
|
auto Abbv = std::make_shared<BitCodeAbbrev>();
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNOP));
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
|
||||||
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
|
||||||
|
FUNCTION_INST_UNOP_ABBREV)
|
||||||
|
llvm_unreachable("Unexpected abbrev ordering!");
|
||||||
|
}
|
||||||
|
{ // INST_UNOP_FLAGS abbrev for FUNCTION_BLOCK.
|
||||||
|
auto Abbv = std::make_shared<BitCodeAbbrev>();
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNOP));
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); // flags
|
||||||
|
if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) !=
|
||||||
|
FUNCTION_INST_UNOP_FLAGS_ABBREV)
|
||||||
|
llvm_unreachable("Unexpected abbrev ordering!");
|
||||||
|
}
|
||||||
{ // INST_BINOP abbrev for FUNCTION_BLOCK.
|
{ // INST_BINOP abbrev for FUNCTION_BLOCK.
|
||||||
auto Abbv = std::make_shared<BitCodeAbbrev>();
|
auto Abbv = std::make_shared<BitCodeAbbrev>();
|
||||||
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
|
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
|
||||||
|
@ -330,6 +330,13 @@ bool IRTranslator::translateFSub(const User &U, MachineIRBuilder &MIRBuilder) {
|
|||||||
return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
|
return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) {
|
||||||
|
MIRBuilder.buildInstr(TargetOpcode::G_FNEG)
|
||||||
|
.addDef(getOrCreateVReg(U))
|
||||||
|
.addUse(getOrCreateVReg(*U.getOperand(1)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool IRTranslator::translateCompare(const User &U,
|
bool IRTranslator::translateCompare(const User &U,
|
||||||
MachineIRBuilder &MIRBuilder) {
|
MachineIRBuilder &MIRBuilder) {
|
||||||
const CmpInst *CI = dyn_cast<CmpInst>(&U);
|
const CmpInst *CI = dyn_cast<CmpInst>(&U);
|
||||||
|
@ -2801,6 +2801,15 @@ static bool isVectorReductionOp(const User *I) {
|
|||||||
return ReduxExtracted;
|
return ReduxExtracted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SelectionDAGBuilder::visitUnary(const User &I, unsigned Opcode) {
|
||||||
|
SDNodeFlags Flags;
|
||||||
|
|
||||||
|
SDValue Op = getValue(I.getOperand(0));
|
||||||
|
SDValue UnNodeValue = DAG.getNode(Opcode, getCurSDLoc(), Op.getValueType(),
|
||||||
|
Op, Flags);
|
||||||
|
setValue(&I, UnNodeValue);
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionDAGBuilder::visitBinary(const User &I, unsigned Opcode) {
|
void SelectionDAGBuilder::visitBinary(const User &I, unsigned Opcode) {
|
||||||
SDNodeFlags Flags;
|
SDNodeFlags Flags;
|
||||||
if (auto *OFBinOp = dyn_cast<OverflowingBinaryOperator>(&I)) {
|
if (auto *OFBinOp = dyn_cast<OverflowingBinaryOperator>(&I)) {
|
||||||
|
@ -854,6 +854,9 @@ private:
|
|||||||
void visitInvoke(const InvokeInst &I);
|
void visitInvoke(const InvokeInst &I);
|
||||||
void visitResume(const ResumeInst &I);
|
void visitResume(const ResumeInst &I);
|
||||||
|
|
||||||
|
void visitUnary(const User &I, unsigned Opcode);
|
||||||
|
void visitFNeg(const User &I) { visitUnary(I, ISD::FNEG); }
|
||||||
|
|
||||||
void visitBinary(const User &I, unsigned Opcode);
|
void visitBinary(const User &I, unsigned Opcode);
|
||||||
void visitShift(const User &I, unsigned Opcode);
|
void visitShift(const User &I, unsigned Opcode);
|
||||||
void visitAdd(const User &I) { visitBinary(I, ISD::ADD); }
|
void visitAdd(const User &I) { visitBinary(I, ISD::ADD); }
|
||||||
|
@ -1451,6 +1451,7 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const {
|
|||||||
case CatchPad: return 0;
|
case CatchPad: return 0;
|
||||||
case CatchSwitch: return 0;
|
case CatchSwitch: return 0;
|
||||||
case CleanupPad: return 0;
|
case CleanupPad: return 0;
|
||||||
|
case FNeg: return ISD::FNEG;
|
||||||
case Add: return ISD::ADD;
|
case Add: return ISD::ADD;
|
||||||
case FAdd: return ISD::FADD;
|
case FAdd: return ISD::FADD;
|
||||||
case Sub: return ISD::SUB;
|
case Sub: return ISD::SUB;
|
||||||
|
@ -1780,6 +1780,36 @@ Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy,
|
|||||||
return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy, OnlyIfReduced);
|
return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy, OnlyIfReduced);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constant *ConstantExpr::get(unsigned Opcode, Constant *C, unsigned Flags,
|
||||||
|
Type *OnlyIfReducedTy) {
|
||||||
|
// Check the operands for consistency first.
|
||||||
|
assert(Instruction::isUnaryOp(Opcode) &&
|
||||||
|
"Invalid opcode in unary constant expression");
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
switch (Opcode) {
|
||||||
|
case Instruction::FNeg:
|
||||||
|
assert(C->getType()->isFPOrFPVectorTy() &&
|
||||||
|
"Tried to create a floating-point operation on a "
|
||||||
|
"non-floating-point type!");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: Try to constant fold operation.
|
||||||
|
|
||||||
|
if (OnlyIfReducedTy == C->getType())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Constant *ArgVec[] = { C };
|
||||||
|
ConstantExprKeyType Key(Opcode, ArgVec, 0, Flags);
|
||||||
|
|
||||||
|
LLVMContextImpl *pImpl = C->getContext().pImpl;
|
||||||
|
return pImpl->ExprConstants.getOrCreate(C->getType(), Key);
|
||||||
|
}
|
||||||
|
|
||||||
Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
|
Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
|
||||||
unsigned Flags, Type *OnlyIfReducedTy) {
|
unsigned Flags, Type *OnlyIfReducedTy) {
|
||||||
// Check the operands for consistency first.
|
// Check the operands for consistency first.
|
||||||
|
@ -529,7 +529,9 @@ struct ConstantExprKeyType {
|
|||||||
ConstantExpr *create(TypeClass *Ty) const {
|
ConstantExpr *create(TypeClass *Ty) const {
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
default:
|
default:
|
||||||
if (Instruction::isCast(Opcode))
|
if (Instruction::isCast(Opcode) ||
|
||||||
|
(Opcode >= Instruction::UnaryOpsBegin &&
|
||||||
|
Opcode < Instruction::UnaryOpsEnd))
|
||||||
return new UnaryConstantExpr(Opcode, Ops[0], Ty);
|
return new UnaryConstantExpr(Opcode, Ops[0], Ty);
|
||||||
if ((Opcode >= Instruction::BinaryOpsBegin &&
|
if ((Opcode >= Instruction::BinaryOpsBegin &&
|
||||||
Opcode < Instruction::BinaryOpsEnd))
|
Opcode < Instruction::BinaryOpsEnd))
|
||||||
|
@ -303,6 +303,9 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
|
|||||||
case CatchPad: return "catchpad";
|
case CatchPad: return "catchpad";
|
||||||
case CatchSwitch: return "catchswitch";
|
case CatchSwitch: return "catchswitch";
|
||||||
|
|
||||||
|
// Standard unary operators...
|
||||||
|
case FNeg: return "fneg";
|
||||||
|
|
||||||
// Standard binary operators...
|
// Standard binary operators...
|
||||||
case Add: return "add";
|
case Add: return "add";
|
||||||
case FAdd: return "fadd";
|
case FAdd: return "fadd";
|
||||||
|
@ -1956,6 +1956,59 @@ Type *ExtractValueInst::getIndexedType(Type *Agg,
|
|||||||
return const_cast<Type*>(Agg);
|
return const_cast<Type*>(Agg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// UnaryOperator Class
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
UnaryOperator::UnaryOperator(UnaryOps iType, Value *S,
|
||||||
|
Type *Ty, const Twine &Name,
|
||||||
|
Instruction *InsertBefore)
|
||||||
|
: UnaryInstruction(Ty, iType, S, InsertBefore) {
|
||||||
|
Op<0>() = S;
|
||||||
|
setName(Name);
|
||||||
|
AssertOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
UnaryOperator::UnaryOperator(UnaryOps iType, Value *S,
|
||||||
|
Type *Ty, const Twine &Name,
|
||||||
|
BasicBlock *InsertAtEnd)
|
||||||
|
: UnaryInstruction(Ty, iType, S, InsertAtEnd) {
|
||||||
|
Op<0>() = S;
|
||||||
|
setName(Name);
|
||||||
|
AssertOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
UnaryOperator *UnaryOperator::Create(UnaryOps Op, Value *S,
|
||||||
|
const Twine &Name,
|
||||||
|
Instruction *InsertBefore) {
|
||||||
|
return new UnaryOperator(Op, S, S->getType(), Name, InsertBefore);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnaryOperator *UnaryOperator::Create(UnaryOps Op, Value *S,
|
||||||
|
const Twine &Name,
|
||||||
|
BasicBlock *InsertAtEnd) {
|
||||||
|
UnaryOperator *Res = Create(Op, S, Name);
|
||||||
|
InsertAtEnd->getInstList().push_back(Res);
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnaryOperator::AssertOK() {
|
||||||
|
Value *LHS = getOperand(0);
|
||||||
|
(void)LHS; // Silence warnings.
|
||||||
|
#ifndef NDEBUG
|
||||||
|
switch (getOpcode()) {
|
||||||
|
case FNeg:
|
||||||
|
assert(getType() == LHS->getType() &&
|
||||||
|
"Unary operation should return same type as operand!");
|
||||||
|
assert(getType()->isFPOrFPVectorTy() &&
|
||||||
|
"Tried to create a floating-point operation on a "
|
||||||
|
"non-floating-point type!");
|
||||||
|
break;
|
||||||
|
default: llvm_unreachable("Invalid opcode provided");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// BinaryOperator Class
|
// BinaryOperator Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -3697,6 +3750,10 @@ GetElementPtrInst *GetElementPtrInst::cloneImpl() const {
|
|||||||
return new (getNumOperands()) GetElementPtrInst(*this);
|
return new (getNumOperands()) GetElementPtrInst(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnaryOperator *UnaryOperator::cloneImpl() const {
|
||||||
|
return Create(getOpcode(), Op<0>());
|
||||||
|
}
|
||||||
|
|
||||||
BinaryOperator *BinaryOperator::cloneImpl() const {
|
BinaryOperator *BinaryOperator::cloneImpl() const {
|
||||||
return Create(getOpcode(), Op<0>(), Op<1>());
|
return Create(getOpcode(), Op<0>(), Op<1>());
|
||||||
}
|
}
|
||||||
|
@ -443,6 +443,7 @@ private:
|
|||||||
void visitBitCastInst(BitCastInst &I);
|
void visitBitCastInst(BitCastInst &I);
|
||||||
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
|
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
|
||||||
void visitPHINode(PHINode &PN);
|
void visitPHINode(PHINode &PN);
|
||||||
|
void visitUnaryOperator(UnaryOperator &U);
|
||||||
void visitBinaryOperator(BinaryOperator &B);
|
void visitBinaryOperator(BinaryOperator &B);
|
||||||
void visitICmpInst(ICmpInst &IC);
|
void visitICmpInst(ICmpInst &IC);
|
||||||
void visitFCmpInst(FCmpInst &FC);
|
void visitFCmpInst(FCmpInst &FC);
|
||||||
@ -2990,6 +2991,28 @@ void Verifier::visitInvokeInst(InvokeInst &II) {
|
|||||||
visitTerminator(II);
|
visitTerminator(II);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// visitUnaryOperator - Check the argument to the unary operator.
|
||||||
|
///
|
||||||
|
void Verifier::visitUnaryOperator(UnaryOperator &U) {
|
||||||
|
Assert(U.getType() == U.getOperand(0)->getType(),
|
||||||
|
"Unary operators must have same type for"
|
||||||
|
"operands and result!",
|
||||||
|
&U);
|
||||||
|
|
||||||
|
switch (U.getOpcode()) {
|
||||||
|
// Check that floating-point arithmetic operators are only used with
|
||||||
|
// floating-point operands.
|
||||||
|
case Instruction::FNeg:
|
||||||
|
Assert(U.getType()->isFPOrFPVectorTy(),
|
||||||
|
"FNeg operator only works with float types!", &U);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unknown UnaryOperator opcode!");
|
||||||
|
}
|
||||||
|
|
||||||
|
visitInstruction(U);
|
||||||
|
}
|
||||||
|
|
||||||
/// visitBinaryOperator - Check that both arguments to the binary operator are
|
/// visitBinaryOperator - Check that both arguments to the binary operator are
|
||||||
/// of the same type!
|
/// of the same type!
|
||||||
///
|
///
|
||||||
|
@ -38,8 +38,12 @@ entry:
|
|||||||
%e = frem float %x, %y
|
%e = frem float %x, %y
|
||||||
; CHECK: %e_vec = frem <3 x float> %vec, %vec
|
; CHECK: %e_vec = frem <3 x float> %vec, %vec
|
||||||
%e_vec = frem <3 x float> %vec, %vec
|
%e_vec = frem <3 x float> %vec, %vec
|
||||||
; CHECK: ret float %e
|
; CHECK: %f = fneg float %x
|
||||||
ret float %e
|
%f = fneg float %x
|
||||||
|
; CHECK: %f_vec = fneg <3 x float> %vec
|
||||||
|
%f_vec = fneg <3 x float> %vec
|
||||||
|
; CHECK: ret float %f
|
||||||
|
ret float %f
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: no_nan
|
; CHECK: no_nan
|
||||||
@ -72,8 +76,12 @@ entry:
|
|||||||
%e = frem nnan float %x, %y
|
%e = frem nnan float %x, %y
|
||||||
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
|
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
|
||||||
%e_vec = frem nnan <3 x float> %vec, %vec
|
%e_vec = frem nnan <3 x float> %vec, %vec
|
||||||
; CHECK: ret float %e
|
; CHECK: %f = fneg nnan float %x
|
||||||
ret float %e
|
%f = fneg nnan float %x
|
||||||
|
; CHECK: %f_vec = fneg nnan <3 x float> %vec
|
||||||
|
%f_vec = fneg nnan <3 x float> %vec
|
||||||
|
; CHECK: ret float %f
|
||||||
|
ret float %f
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: @contract(
|
; CHECK: @contract(
|
||||||
@ -174,6 +182,10 @@ entry:
|
|||||||
%e = frem nnan nsz float %x, %y
|
%e = frem nnan nsz float %x, %y
|
||||||
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
|
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
|
||||||
%e_vec = frem nnan <3 x float> %vec, %vec
|
%e_vec = frem nnan <3 x float> %vec, %vec
|
||||||
; CHECK: ret float %e
|
; CHECK: %f = fneg nnan nsz float %x
|
||||||
ret float %e
|
%f = fneg nnan nsz float %x
|
||||||
|
; CHECK: %f_vec = fneg fast <3 x float> %vec
|
||||||
|
%f_vec = fneg fast <3 x float> %vec
|
||||||
|
; CHECK: ret float %f
|
||||||
|
ret float %f
|
||||||
}
|
}
|
||||||
|
@ -762,7 +762,27 @@ define void @atomics(i32* %word) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
;; Fast Math Flags
|
;; Fast Math Flags
|
||||||
define void @fastmathflags(float %op1, float %op2) {
|
define void @fastmathflags_unop(float %op1) {
|
||||||
|
%f.nnan = fneg nnan float %op1
|
||||||
|
; CHECK: %f.nnan = fneg nnan float %op1
|
||||||
|
%f.ninf = fneg ninf float %op1
|
||||||
|
; CHECK: %f.ninf = fneg ninf float %op1
|
||||||
|
%f.nsz = fneg nsz float %op1
|
||||||
|
; CHECK: %f.nsz = fneg nsz float %op1
|
||||||
|
%f.arcp = fneg arcp float %op1
|
||||||
|
; CHECK: %f.arcp = fneg arcp float %op1
|
||||||
|
%f.contract = fneg contract float %op1
|
||||||
|
; CHECK: %f.contract = fneg contract float %op1
|
||||||
|
%f.afn = fneg afn float %op1
|
||||||
|
; CHECK: %f.afn = fneg afn float %op1
|
||||||
|
%f.reassoc = fneg reassoc float %op1
|
||||||
|
; CHECK: %f.reassoc = fneg reassoc float %op1
|
||||||
|
%f.fast = fneg fast float %op1
|
||||||
|
; CHECK: %f.fast = fneg fast float %op1
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @fastmathflags_binops(float %op1, float %op2) {
|
||||||
%f.nnan = fadd nnan float %op1, %op2
|
%f.nnan = fadd nnan float %op1, %op2
|
||||||
; CHECK: %f.nnan = fadd nnan float %op1, %op2
|
; CHECK: %f.nnan = fadd nnan float %op1, %op2
|
||||||
%f.ninf = fadd ninf float %op1, %op2
|
%f.ninf = fadd ninf float %op1, %op2
|
||||||
@ -997,6 +1017,13 @@ continue:
|
|||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Instructions -- Unary Operations
|
||||||
|
define void @instructions.unops(double %op1) {
|
||||||
|
fneg double %op1
|
||||||
|
; CHECK: fneg double %op1
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
; Instructions -- Binary Operations
|
; Instructions -- Binary Operations
|
||||||
define void @instructions.binops(i8 %op1, i8 %op2) {
|
define void @instructions.binops(i8 %op1, i8 %op2) {
|
||||||
; nuw x nsw
|
; nuw x nsw
|
||||||
|
@ -3,6 +3,15 @@
|
|||||||
; RUN: llvm-as < %s | llvm-bcanalyzer -dump | FileCheck %s
|
; RUN: llvm-as < %s | llvm-bcanalyzer -dump | FileCheck %s
|
||||||
; RUN: verify-uselistorder < %s
|
; RUN: verify-uselistorder < %s
|
||||||
|
|
||||||
|
; CHECK: FUNCTION_BLOCK
|
||||||
|
; CHECK: INST_UNOP {{.*}}op0=1
|
||||||
|
; CHECK: INST_RET {{.*}}op0=1
|
||||||
|
define double @test_float_unops(double %a) nounwind {
|
||||||
|
%1 = fneg double %a
|
||||||
|
ret double %1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
; CHECK: FUNCTION_BLOCK
|
; CHECK: FUNCTION_BLOCK
|
||||||
; CHECK: INST_BINOP {{.*}}op0=1 op1=1
|
; CHECK: INST_BINOP {{.*}}op0=1 op1=1
|
||||||
; CHECK: INST_BINOP {{.*}}op0=1 op1=1
|
; CHECK: INST_BINOP {{.*}}op0=1 op1=1
|
||||||
|
@ -10,6 +10,21 @@ define float @fnegf(float %X) {
|
|||||||
ret float %Y
|
ret float %Y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define double @real_fneg(double %X) {
|
||||||
|
%Y = fneg double %X ; <double> [#uses=1]
|
||||||
|
ret double %Y
|
||||||
|
}
|
||||||
|
|
||||||
|
define double @real_fneg_constant() {
|
||||||
|
%Y = fneg double -2.0 ; <double> [#uses=1]
|
||||||
|
ret double %Y
|
||||||
|
}
|
||||||
|
|
||||||
|
define float @real_fnegf(float %X) {
|
||||||
|
%Y = fneg float %X ; <float> [#uses=1]
|
||||||
|
ret float %Y
|
||||||
|
}
|
||||||
|
|
||||||
declare double @fabs(double)
|
declare double @fabs(double)
|
||||||
|
|
||||||
declare float @fabsf(float)
|
declare float @fabsf(float)
|
||||||
|
@ -127,3 +127,18 @@ define <4 x float> @fsub0_undef_elts_v4f32(<4 x float> %x) {
|
|||||||
ret <4 x float> %r
|
ret <4 x float> %r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define <4 x float> @fneg(<4 x float> %Q) nounwind {
|
||||||
|
; X32-SSE-LABEL: fneg:
|
||||||
|
; X32-SSE: # %bb.0:
|
||||||
|
; X32-SSE-NEXT: xorps {{\.LCPI.*}}, %xmm0
|
||||||
|
; X32-SSE-NEXT: retl
|
||||||
|
;
|
||||||
|
; X64-SSE-LABEL: fneg:
|
||||||
|
; X64-SSE: # %bb.0:
|
||||||
|
; X64-SSE-NEXT: xorps {{.*}}(%rip), %xmm0
|
||||||
|
; X64-SSE-NEXT: retq
|
||||||
|
%tmp = fneg <4 x float> %Q
|
||||||
|
ret <4 x float> %tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,6 +63,14 @@ lpad:
|
|||||||
resume { i8*, i32 } zeroinitializer
|
resume { i8*, i32 } zeroinitializer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i8 @call_with_same_range() {
|
||||||
|
; CHECK-LABEL: @call_with_same_range
|
||||||
|
; CHECK: tail call i8 @call_with_range
|
||||||
|
bitcast i8 0 to i8
|
||||||
|
%out = call i8 @dummy(), !range !0
|
||||||
|
ret i8 %out
|
||||||
|
}
|
||||||
|
|
||||||
define i8 @invoke_with_same_range() personality i8* undef {
|
define i8 @invoke_with_same_range() personality i8* undef {
|
||||||
; CHECK-LABEL: @invoke_with_same_range()
|
; CHECK-LABEL: @invoke_with_same_range()
|
||||||
; CHECK: tail call i8 @invoke_with_range()
|
; CHECK: tail call i8 @invoke_with_range()
|
||||||
@ -76,14 +84,6 @@ lpad:
|
|||||||
resume { i8*, i32 } zeroinitializer
|
resume { i8*, i32 } zeroinitializer
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8 @call_with_same_range() {
|
|
||||||
; CHECK-LABEL: @call_with_same_range
|
|
||||||
; CHECK: tail call i8 @call_with_range
|
|
||||||
bitcast i8 0 to i8
|
|
||||||
%out = call i8 @dummy(), !range !0
|
|
||||||
ret i8 %out
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
declare i8 @dummy();
|
declare i8 @dummy();
|
||||||
|
@ -247,6 +247,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
|
|||||||
STRINGIFY_CODE(CST_CODE, CE_CMP)
|
STRINGIFY_CODE(CST_CODE, CE_CMP)
|
||||||
STRINGIFY_CODE(CST_CODE, INLINEASM)
|
STRINGIFY_CODE(CST_CODE, INLINEASM)
|
||||||
STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX)
|
STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX)
|
||||||
|
STRINGIFY_CODE(CST_CODE, CE_UNOP)
|
||||||
case bitc::CST_CODE_BLOCKADDRESS: return "CST_CODE_BLOCKADDRESS";
|
case bitc::CST_CODE_BLOCKADDRESS: return "CST_CODE_BLOCKADDRESS";
|
||||||
STRINGIFY_CODE(CST_CODE, DATA)
|
STRINGIFY_CODE(CST_CODE, DATA)
|
||||||
}
|
}
|
||||||
@ -267,6 +268,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
|
|||||||
STRINGIFY_CODE(FUNC_CODE, INST_BR)
|
STRINGIFY_CODE(FUNC_CODE, INST_BR)
|
||||||
STRINGIFY_CODE(FUNC_CODE, INST_SWITCH)
|
STRINGIFY_CODE(FUNC_CODE, INST_SWITCH)
|
||||||
STRINGIFY_CODE(FUNC_CODE, INST_INVOKE)
|
STRINGIFY_CODE(FUNC_CODE, INST_INVOKE)
|
||||||
|
STRINGIFY_CODE(FUNC_CODE, INST_UNOP)
|
||||||
STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE)
|
STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE)
|
||||||
STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET)
|
STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET)
|
||||||
STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET)
|
STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user