[llvm] r346774 - [IR] Add a dedicated FNeg IR Instruction
Cameron McInally via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 13 10:15:48 PST 2018
Author: mcinally
Date: Tue Nov 13 10:15:47 2018
New Revision: 346774
URL: http://llvm.org/viewvc/llvm-project?rev=346774&view=rev
Log:
[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
Modified:
llvm/trunk/include/llvm-c/Core.h
llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
llvm/trunk/include/llvm/IR/Constants.h
llvm/trunk/include/llvm/IR/InstVisitor.h
llvm/trunk/include/llvm/IR/Instruction.def
llvm/trunk/include/llvm/IR/Instruction.h
llvm/trunk/include/llvm/IR/Instructions.h
llvm/trunk/lib/AsmParser/LLLexer.cpp
llvm/trunk/lib/AsmParser/LLParser.cpp
llvm/trunk/lib/AsmParser/LLParser.h
llvm/trunk/lib/AsmParser/LLToken.h
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
llvm/trunk/lib/IR/Constants.cpp
llvm/trunk/lib/IR/ConstantsContext.h
llvm/trunk/lib/IR/Instruction.cpp
llvm/trunk/lib/IR/Instructions.cpp
llvm/trunk/lib/IR/Verifier.cpp
llvm/trunk/test/Assembler/fast-math-flags.ll
llvm/trunk/test/Bitcode/compatibility.ll
llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll
llvm/trunk/test/CodeGen/Generic/fneg-fabs.ll
llvm/trunk/test/CodeGen/X86/vec_fneg.ll
llvm/trunk/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
Modified: llvm/trunk/include/llvm-c/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Core.h (original)
+++ llvm/trunk/include/llvm-c/Core.h Tue Nov 13 10:15:47 2018
@@ -54,6 +54,8 @@ extern "C" {
* @{
*/
+/// External users depend on the following values being stable. It is not safe
+/// to reorder them.
typedef enum {
/* Terminator Instructions */
LLVMRet = 1,
@@ -64,6 +66,9 @@ typedef enum {
/* removed 6 due to API changes */
LLVMUnreachable = 7,
+ /* Standard Unary Operators */
+ LLVMFNeg = 66,
+
/* Standard Binary Operators */
LLVMAdd = 8,
LLVMFAdd = 9,
Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue Nov 13 10:15:47 2018
@@ -342,6 +342,7 @@ enum ConstantsCodes {
CST_CODE_INLINEASM = 23, // INLINEASM: [sideeffect|alignstack|
// asmdialect,asmstr,conststr]
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
@@ -364,6 +365,14 @@ enum CastOpcodes {
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
/// 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
@@ -524,6 +533,7 @@ enum FunctionCodes {
// 53 is unused.
// 54 is unused.
FUNC_CODE_OPERAND_BUNDLE = 55, // OPERAND_BUNDLE: [tag#, value...]
+ FUNC_CODE_INST_UNOP = 56, // UNOP: [opcode, ty, opval]
};
enum UseListCodes {
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/IRTranslator.h Tue Nov 13 10:15:47 2018
@@ -300,6 +300,8 @@ private:
bool translateFSub(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateFNeg(const User &U, MachineIRBuilder &MIRBuilder);
+
bool translateAdd(const User &U, MachineIRBuilder &MIRBuilder) {
return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
}
Modified: llvm/trunk/include/llvm/IR/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constants.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Constants.h (original)
+++ llvm/trunk/include/llvm/IR/Constants.h Tue Nov 13 10:15:47 2018
@@ -1114,6 +1114,13 @@ public:
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2,
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,
/// folding if possible.
///
Modified: llvm/trunk/include/llvm/IR/InstVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/InstVisitor.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/InstVisitor.h (original)
+++ llvm/trunk/include/llvm/IR/InstVisitor.h Tue Nov 13 10:15:47 2018
@@ -263,6 +263,7 @@ public:
// of instructions...
//
RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitUnaryOperator(UnaryOperator &I) { DELEGATE(UnaryInstruction);}
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);}
RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);}
RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
Modified: llvm/trunk/include/llvm/IR/Instruction.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.def?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.def (original)
+++ llvm/trunk/include/llvm/IR/Instruction.def Tue Nov 13 10:15:47 2018
@@ -32,6 +32,20 @@
#define LAST_TERM_INST(num)
#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
#define FIRST_BINARY_INST(num)
#endif
@@ -123,87 +137,96 @@ HANDLE_TERM_INST ( 9, CatchRet , C
HANDLE_TERM_INST (10, CatchSwitch , CatchSwitchInst)
LAST_TERM_INST (10)
+// Standard unary operators...
+ FIRST_UNARY_INST(11)
+HANDLE_UNARY_INST(11, FNeg , UnaryOperator)
+ LAST_UNARY_INST(11)
+
// Standard binary operators...
- FIRST_BINARY_INST(11)
-HANDLE_BINARY_INST(11, Add , BinaryOperator)
-HANDLE_BINARY_INST(12, FAdd , BinaryOperator)
-HANDLE_BINARY_INST(13, Sub , BinaryOperator)
-HANDLE_BINARY_INST(14, FSub , BinaryOperator)
-HANDLE_BINARY_INST(15, Mul , BinaryOperator)
-HANDLE_BINARY_INST(16, FMul , BinaryOperator)
-HANDLE_BINARY_INST(17, UDiv , BinaryOperator)
-HANDLE_BINARY_INST(18, SDiv , BinaryOperator)
-HANDLE_BINARY_INST(19, FDiv , BinaryOperator)
-HANDLE_BINARY_INST(20, URem , BinaryOperator)
-HANDLE_BINARY_INST(21, SRem , BinaryOperator)
-HANDLE_BINARY_INST(22, FRem , BinaryOperator)
+ FIRST_BINARY_INST(12)
+HANDLE_BINARY_INST(12, Add , BinaryOperator)
+HANDLE_BINARY_INST(13, FAdd , BinaryOperator)
+HANDLE_BINARY_INST(14, Sub , BinaryOperator)
+HANDLE_BINARY_INST(15, FSub , BinaryOperator)
+HANDLE_BINARY_INST(16, Mul , BinaryOperator)
+HANDLE_BINARY_INST(17, FMul , BinaryOperator)
+HANDLE_BINARY_INST(18, UDiv , BinaryOperator)
+HANDLE_BINARY_INST(19, SDiv , BinaryOperator)
+HANDLE_BINARY_INST(20, FDiv , BinaryOperator)
+HANDLE_BINARY_INST(21, URem , BinaryOperator)
+HANDLE_BINARY_INST(22, SRem , BinaryOperator)
+HANDLE_BINARY_INST(23, FRem , BinaryOperator)
// Logical operators (integer operands)
-HANDLE_BINARY_INST(23, Shl , BinaryOperator) // Shift left (logical)
-HANDLE_BINARY_INST(24, LShr , BinaryOperator) // Shift right (logical)
-HANDLE_BINARY_INST(25, AShr , BinaryOperator) // Shift right (arithmetic)
-HANDLE_BINARY_INST(26, And , BinaryOperator)
-HANDLE_BINARY_INST(27, Or , BinaryOperator)
-HANDLE_BINARY_INST(28, Xor , BinaryOperator)
- LAST_BINARY_INST(28)
+HANDLE_BINARY_INST(24, Shl , BinaryOperator) // Shift left (logical)
+HANDLE_BINARY_INST(25, LShr , BinaryOperator) // Shift right (logical)
+HANDLE_BINARY_INST(26, AShr , BinaryOperator) // Shift right (arithmetic)
+HANDLE_BINARY_INST(27, And , BinaryOperator)
+HANDLE_BINARY_INST(28, Or , BinaryOperator)
+HANDLE_BINARY_INST(29, Xor , BinaryOperator)
+ LAST_BINARY_INST(29)
// Memory operators...
- FIRST_MEMORY_INST(29)
-HANDLE_MEMORY_INST(29, Alloca, AllocaInst) // Stack management
-HANDLE_MEMORY_INST(30, Load , LoadInst ) // Memory manipulation instrs
-HANDLE_MEMORY_INST(31, Store , StoreInst )
-HANDLE_MEMORY_INST(32, GetElementPtr, GetElementPtrInst)
-HANDLE_MEMORY_INST(33, Fence , FenceInst )
-HANDLE_MEMORY_INST(34, AtomicCmpXchg , AtomicCmpXchgInst )
-HANDLE_MEMORY_INST(35, AtomicRMW , AtomicRMWInst )
- LAST_MEMORY_INST(35)
+ FIRST_MEMORY_INST(30)
+HANDLE_MEMORY_INST(30, Alloca, AllocaInst) // Stack management
+HANDLE_MEMORY_INST(31, Load , LoadInst ) // Memory manipulation instrs
+HANDLE_MEMORY_INST(32, Store , StoreInst )
+HANDLE_MEMORY_INST(33, GetElementPtr, GetElementPtrInst)
+HANDLE_MEMORY_INST(34, Fence , FenceInst )
+HANDLE_MEMORY_INST(35, AtomicCmpXchg , AtomicCmpXchgInst )
+HANDLE_MEMORY_INST(36, AtomicRMW , AtomicRMWInst )
+ LAST_MEMORY_INST(36)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
- FIRST_CAST_INST(36)
-HANDLE_CAST_INST(36, Trunc , TruncInst ) // Truncate integers
-HANDLE_CAST_INST(37, ZExt , ZExtInst ) // Zero extend integers
-HANDLE_CAST_INST(38, SExt , SExtInst ) // Sign extend integers
-HANDLE_CAST_INST(39, FPToUI , FPToUIInst ) // floating point -> UInt
-HANDLE_CAST_INST(40, FPToSI , FPToSIInst ) // floating point -> SInt
-HANDLE_CAST_INST(41, UIToFP , UIToFPInst ) // UInt -> floating point
-HANDLE_CAST_INST(42, SIToFP , SIToFPInst ) // SInt -> floating point
-HANDLE_CAST_INST(43, FPTrunc , FPTruncInst ) // Truncate floating point
-HANDLE_CAST_INST(44, FPExt , FPExtInst ) // Extend floating point
-HANDLE_CAST_INST(45, PtrToInt, PtrToIntInst) // Pointer -> Integer
-HANDLE_CAST_INST(46, IntToPtr, IntToPtrInst) // Integer -> Pointer
-HANDLE_CAST_INST(47, BitCast , BitCastInst ) // Type cast
-HANDLE_CAST_INST(48, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
- LAST_CAST_INST(48)
-
- FIRST_FUNCLETPAD_INST(49)
-HANDLE_FUNCLETPAD_INST(49, CleanupPad, CleanupPadInst)
-HANDLE_FUNCLETPAD_INST(50, CatchPad , CatchPadInst)
- LAST_FUNCLETPAD_INST(50)
+ FIRST_CAST_INST(37)
+HANDLE_CAST_INST(37, Trunc , TruncInst ) // Truncate integers
+HANDLE_CAST_INST(38, ZExt , ZExtInst ) // Zero extend integers
+HANDLE_CAST_INST(39, SExt , SExtInst ) // Sign extend integers
+HANDLE_CAST_INST(40, FPToUI , FPToUIInst ) // floating point -> UInt
+HANDLE_CAST_INST(41, FPToSI , FPToSIInst ) // floating point -> SInt
+HANDLE_CAST_INST(42, UIToFP , UIToFPInst ) // UInt -> floating point
+HANDLE_CAST_INST(43, SIToFP , SIToFPInst ) // SInt -> floating point
+HANDLE_CAST_INST(44, FPTrunc , FPTruncInst ) // Truncate floating point
+HANDLE_CAST_INST(45, FPExt , FPExtInst ) // Extend floating point
+HANDLE_CAST_INST(46, PtrToInt, PtrToIntInst) // Pointer -> Integer
+HANDLE_CAST_INST(47, IntToPtr, IntToPtrInst) // Integer -> Pointer
+HANDLE_CAST_INST(48, BitCast , BitCastInst ) // Type cast
+HANDLE_CAST_INST(49, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
+ LAST_CAST_INST(49)
+
+ FIRST_FUNCLETPAD_INST(50)
+HANDLE_FUNCLETPAD_INST(50, CleanupPad, CleanupPadInst)
+HANDLE_FUNCLETPAD_INST(51, CatchPad , CatchPadInst)
+ LAST_FUNCLETPAD_INST(51)
// Other operators...
- FIRST_OTHER_INST(51)
-HANDLE_OTHER_INST(51, ICmp , ICmpInst ) // Integer comparison instruction
-HANDLE_OTHER_INST(52, FCmp , FCmpInst ) // Floating point comparison instr.
-HANDLE_OTHER_INST(53, PHI , PHINode ) // PHI node instruction
-HANDLE_OTHER_INST(54, Call , CallInst ) // Call a function
-HANDLE_OTHER_INST(55, Select , SelectInst ) // select instruction
-HANDLE_USER_INST (56, UserOp1, Instruction) // May be used internally in a pass
-HANDLE_USER_INST (57, UserOp2, Instruction) // Internal to passes only
-HANDLE_OTHER_INST(58, VAArg , VAArgInst ) // vaarg instruction
-HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector
-HANDLE_OTHER_INST(60, InsertElement, InsertElementInst) // insert into vector
-HANDLE_OTHER_INST(61, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
-HANDLE_OTHER_INST(62, ExtractValue, ExtractValueInst)// extract from aggregate
-HANDLE_OTHER_INST(63, InsertValue, InsertValueInst) // insert into aggregate
-HANDLE_OTHER_INST(64, LandingPad, LandingPadInst) // Landing pad instruction.
- LAST_OTHER_INST(64)
+ FIRST_OTHER_INST(52)
+HANDLE_OTHER_INST(52, ICmp , ICmpInst ) // Integer comparison instruction
+HANDLE_OTHER_INST(53, FCmp , FCmpInst ) // Floating point comparison instr.
+HANDLE_OTHER_INST(54, PHI , PHINode ) // PHI node instruction
+HANDLE_OTHER_INST(55, Call , CallInst ) // Call a function
+HANDLE_OTHER_INST(56, Select , SelectInst ) // select instruction
+HANDLE_USER_INST (57, UserOp1, Instruction) // May be used internally in a pass
+HANDLE_USER_INST (58, UserOp2, Instruction) // Internal to passes only
+HANDLE_OTHER_INST(59, VAArg , VAArgInst ) // vaarg instruction
+HANDLE_OTHER_INST(60, ExtractElement, ExtractElementInst)// extract from vector
+HANDLE_OTHER_INST(61, InsertElement, InsertElementInst) // insert into vector
+HANDLE_OTHER_INST(62, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
+HANDLE_OTHER_INST(63, ExtractValue, ExtractValueInst)// extract from aggregate
+HANDLE_OTHER_INST(64, InsertValue, InsertValueInst) // insert into aggregate
+HANDLE_OTHER_INST(65, LandingPad, LandingPadInst) // Landing pad instruction.
+ LAST_OTHER_INST(65)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST
#undef LAST_TERM_INST
+#undef FIRST_UNARY_INST
+#undef HANDLE_UNARY_INST
+#undef LAST_UNARY_INST
+
#undef FIRST_BINARY_INST
#undef HANDLE_BINARY_INST
#undef LAST_BINARY_INST
Modified: llvm/trunk/include/llvm/IR/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.h (original)
+++ llvm/trunk/include/llvm/IR/Instruction.h Tue Nov 13 10:15:47 2018
@@ -127,6 +127,7 @@ public:
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
bool isTerminator() const { return isTerminator(getOpcode()); }
+ bool isUnaryOp() const { return isUnaryOp(getOpcode()); }
bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
bool isIntDivRem() const { return isIntDivRem(getOpcode()); }
bool isShift() { return isShift(getOpcode()); }
@@ -142,6 +143,9 @@ public:
return OpCode >= TermOpsBegin && OpCode < TermOpsEnd;
}
+ static inline bool isUnaryOp(unsigned Opcode) {
+ return Opcode >= UnaryOpsBegin && Opcode < UnaryOpsEnd;
+ }
static inline bool isBinaryOp(unsigned Opcode) {
return Opcode >= BinaryOpsBegin && Opcode < BinaryOpsEnd;
}
@@ -662,6 +666,13 @@ public:
#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 {
#define FIRST_BINARY_INST(N) BinaryOpsBegin = N,
#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
Modified: llvm/trunk/include/llvm/IR/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instructions.h (original)
+++ llvm/trunk/include/llvm/IR/Instructions.h Tue Nov 13 10:15:47 2018
@@ -1104,6 +1104,71 @@ GetElementPtrInst::GetElementPtrInst(Typ
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
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Tue Nov 13 10:15:47 2018
@@ -823,6 +823,8 @@ lltok::Kind LLLexer::LexIdentifier() {
} \
} while (false)
+ INSTKEYWORD(fneg, FNeg);
+
INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd);
INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub);
INSTKEYWORD(mul, Mul); INSTKEYWORD(fmul, FMul);
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Nov 13 10:15:47 2018
@@ -3295,7 +3295,31 @@ bool LLParser::ParseValID(ValID &ID, Per
ID.Kind = ValID::t_Constant;
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.
case lltok::kw_add:
case lltok::kw_fadd:
@@ -5492,6 +5516,16 @@ int LLParser::ParseInstruction(Instructi
case lltok::kw_catchswitch: return ParseCatchSwitch(Inst, PFS);
case lltok::kw_catchpad: return ParseCatchPad(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.
case lltok::kw_add:
case lltok::kw_sub:
@@ -6063,6 +6097,43 @@ bool LLParser::ParseCleanupPad(Instructi
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.
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Tue Nov 13 10:15:47 2018
@@ -571,6 +571,8 @@ namespace llvm {
bool ParseCatchPad(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,
unsigned OperandType);
bool ParseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc);
Modified: llvm/trunk/lib/AsmParser/LLToken.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLToken.h (original)
+++ llvm/trunk/lib/AsmParser/LLToken.h Tue Nov 13 10:15:47 2018
@@ -270,6 +270,7 @@ enum Kind {
kw_umin,
// Instruction Opcodes (Opcode in UIntVal).
+ kw_fneg,
kw_add,
kw_fadd,
kw_sub,
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Nov 13 10:15:47 2018
@@ -964,6 +964,20 @@ static int getDecodedCastOpcode(unsigned
}
}
+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) {
bool IsFP = Ty->isFPOrFPVectorTy();
// BinOps are only valid for int/fp or vector of int/fp types
@@ -2317,6 +2331,19 @@ Error BitcodeReader::parseConstants() {
}
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]
if (Record.size() < 3)
return error("Invalid record");
@@ -3535,7 +3562,27 @@ Error BitcodeReader::parseFunctionBody(F
I = nullptr;
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]
unsigned OpNum = 0;
Value *LHS, *RHS;
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Nov 13 10:15:47 2018
@@ -112,6 +112,8 @@ enum {
// FUNCTION_BLOCK abbrev id's.
FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
+ FUNCTION_INST_UNOP_ABBREV,
+ FUNCTION_INST_UNOP_FLAGS_ABBREV,
FUNCTION_INST_BINOP_ABBREV,
FUNCTION_INST_BINOP_FLAGS_ABBREV,
FUNCTION_INST_CAST_ABBREV,
@@ -513,6 +515,13 @@ static unsigned getEncodedCastOpcode(uns
}
}
+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) {
switch (Opcode) {
default: llvm_unreachable("Unknown binary instruction!");
@@ -2384,6 +2393,16 @@ void ModuleBitcodeWriter::writeConstants
Record.push_back(Flags);
}
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: {
Code = bitc::CST_CODE_CE_GEP;
const auto *GO = cast<GEPOperator>(C);
@@ -2556,7 +2575,19 @@ void ModuleBitcodeWriter::writeInstructi
}
}
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: {
Code = bitc::FUNC_CODE_INST_GEP;
AbbrevToUse = FUNCTION_INST_GEP_ABBREV;
@@ -3217,6 +3248,25 @@ void ModuleBitcodeWriter::writeBlockInfo
FUNCTION_INST_LOAD_ABBREV)
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.
auto Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP));
Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Tue Nov 13 10:15:47 2018
@@ -330,6 +330,13 @@ bool IRTranslator::translateFSub(const U
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,
MachineIRBuilder &MIRBuilder) {
const CmpInst *CI = dyn_cast<CmpInst>(&U);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Nov 13 10:15:47 2018
@@ -2801,6 +2801,15 @@ static bool isVectorReductionOp(const Us
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) {
SDNodeFlags Flags;
if (auto *OFBinOp = dyn_cast<OverflowingBinaryOperator>(&I)) {
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Tue Nov 13 10:15:47 2018
@@ -854,6 +854,9 @@ private:
void visitInvoke(const InvokeInst &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 visitShift(const User &I, unsigned Opcode);
void visitAdd(const User &I) { visitBinary(I, ISD::ADD); }
Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Tue Nov 13 10:15:47 2018
@@ -1451,6 +1451,7 @@ int TargetLoweringBase::InstructionOpcod
case CatchPad: return 0;
case CatchSwitch: return 0;
case CleanupPad: return 0;
+ case FNeg: return ISD::FNEG;
case Add: return ISD::ADD;
case FAdd: return ISD::FADD;
case Sub: return ISD::SUB;
Modified: llvm/trunk/lib/IR/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Constants.cpp (original)
+++ llvm/trunk/lib/IR/Constants.cpp Tue Nov 13 10:15:47 2018
@@ -1780,6 +1780,36 @@ Constant *ConstantExpr::getAddrSpaceCast
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,
unsigned Flags, Type *OnlyIfReducedTy) {
// Check the operands for consistency first.
Modified: llvm/trunk/lib/IR/ConstantsContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantsContext.h?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantsContext.h (original)
+++ llvm/trunk/lib/IR/ConstantsContext.h Tue Nov 13 10:15:47 2018
@@ -529,7 +529,9 @@ struct ConstantExprKeyType {
ConstantExpr *create(TypeClass *Ty) const {
switch (Opcode) {
default:
- if (Instruction::isCast(Opcode))
+ if (Instruction::isCast(Opcode) ||
+ (Opcode >= Instruction::UnaryOpsBegin &&
+ Opcode < Instruction::UnaryOpsEnd))
return new UnaryConstantExpr(Opcode, Ops[0], Ty);
if ((Opcode >= Instruction::BinaryOpsBegin &&
Opcode < Instruction::BinaryOpsEnd))
Modified: llvm/trunk/lib/IR/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instruction.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instruction.cpp (original)
+++ llvm/trunk/lib/IR/Instruction.cpp Tue Nov 13 10:15:47 2018
@@ -303,6 +303,9 @@ const char *Instruction::getOpcodeName(u
case CatchPad: return "catchpad";
case CatchSwitch: return "catchswitch";
+ // Standard unary operators...
+ case FNeg: return "fneg";
+
// Standard binary operators...
case Add: return "add";
case FAdd: return "fadd";
Modified: llvm/trunk/lib/IR/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instructions.cpp (original)
+++ llvm/trunk/lib/IR/Instructions.cpp Tue Nov 13 10:15:47 2018
@@ -1957,6 +1957,59 @@ Type *ExtractValueInst::getIndexedType(T
}
//===----------------------------------------------------------------------===//
+// 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
//===----------------------------------------------------------------------===//
@@ -3697,6 +3750,10 @@ GetElementPtrInst *GetElementPtrInst::cl
return new (getNumOperands()) GetElementPtrInst(*this);
}
+UnaryOperator *UnaryOperator::cloneImpl() const {
+ return Create(getOpcode(), Op<0>());
+}
+
BinaryOperator *BinaryOperator::cloneImpl() const {
return Create(getOpcode(), Op<0>(), Op<1>());
}
Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Tue Nov 13 10:15:47 2018
@@ -443,6 +443,7 @@ private:
void visitBitCastInst(BitCastInst &I);
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
void visitPHINode(PHINode &PN);
+ void visitUnaryOperator(UnaryOperator &U);
void visitBinaryOperator(BinaryOperator &B);
void visitICmpInst(ICmpInst &IC);
void visitFCmpInst(FCmpInst &FC);
@@ -2990,6 +2991,28 @@ void Verifier::visitInvokeInst(InvokeIns
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
/// of the same type!
///
Modified: llvm/trunk/test/Assembler/fast-math-flags.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/fast-math-flags.ll?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/fast-math-flags.ll (original)
+++ llvm/trunk/test/Assembler/fast-math-flags.ll Tue Nov 13 10:15:47 2018
@@ -38,8 +38,12 @@ entry:
%e = frem float %x, %y
; CHECK: %e_vec = frem <3 x float> %vec, %vec
%e_vec = frem <3 x float> %vec, %vec
-; CHECK: ret float %e
- ret float %e
+; CHECK: %f = fneg float %x
+ %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
@@ -72,8 +76,12 @@ entry:
%e = frem nnan float %x, %y
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
%e_vec = frem nnan <3 x float> %vec, %vec
-; CHECK: ret float %e
- ret float %e
+; CHECK: %f = fneg nnan float %x
+ %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(
@@ -174,6 +182,10 @@ entry:
%e = frem nnan nsz float %x, %y
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
%e_vec = frem nnan <3 x float> %vec, %vec
-; CHECK: ret float %e
- ret float %e
+; CHECK: %f = fneg nnan nsz float %x
+ %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
}
Modified: llvm/trunk/test/Bitcode/compatibility.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility.ll?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/test/Bitcode/compatibility.ll (original)
+++ llvm/trunk/test/Bitcode/compatibility.ll Tue Nov 13 10:15:47 2018
@@ -762,7 +762,27 @@ define void @atomics(i32* %word) {
}
;; 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
; CHECK: %f.nnan = fadd nnan float %op1, %op2
%f.ninf = fadd ninf float %op1, %op2
@@ -997,6 +1017,13 @@ continue:
ret i32 0
}
+; Instructions -- Unary Operations
+define void @instructions.unops(double %op1) {
+ fneg double %op1
+ ; CHECK: fneg double %op1
+ ret void
+}
+
; Instructions -- Binary Operations
define void @instructions.binops(i8 %op1, i8 %op2) {
; nuw x nsw
Modified: llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll (original)
+++ llvm/trunk/test/Bitcode/function-encoding-rel-operands.ll Tue Nov 13 10:15:47 2018
@@ -4,6 +4,15 @@
; 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: INST_BINOP {{.*}}op0=1 op1=1
; CHECK: INST_BINOP {{.*}}op0=1 op1=1
; CHECK: INST_BINOP {{.*}}op0=1 op1=1
Modified: llvm/trunk/test/CodeGen/Generic/fneg-fabs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/fneg-fabs.ll?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Generic/fneg-fabs.ll (original)
+++ llvm/trunk/test/CodeGen/Generic/fneg-fabs.ll Tue Nov 13 10:15:47 2018
@@ -10,6 +10,21 @@ define float @fnegf(float %X) {
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 float @fabsf(float)
Modified: llvm/trunk/test/CodeGen/X86/vec_fneg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_fneg.ll?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/vec_fneg.ll (original)
+++ llvm/trunk/test/CodeGen/X86/vec_fneg.ll Tue Nov 13 10:15:47 2018
@@ -127,3 +127,18 @@ define <4 x float> @fsub0_undef_elts_v4f
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
+}
+
+
Modified: llvm/trunk/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll (original)
+++ llvm/trunk/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll Tue Nov 13 10:15:47 2018
@@ -63,6 +63,14 @@ lpad:
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 {
; CHECK-LABEL: @invoke_with_same_range()
; CHECK: tail call i8 @invoke_with_range()
@@ -76,14 +84,6 @@ lpad:
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();
Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=346774&r1=346773&r2=346774&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original)
+++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Tue Nov 13 10:15:47 2018
@@ -247,6 +247,7 @@ static const char *GetCodeName(unsigned
STRINGIFY_CODE(CST_CODE, CE_CMP)
STRINGIFY_CODE(CST_CODE, INLINEASM)
STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX)
+ STRINGIFY_CODE(CST_CODE, CE_UNOP)
case bitc::CST_CODE_BLOCKADDRESS: return "CST_CODE_BLOCKADDRESS";
STRINGIFY_CODE(CST_CODE, DATA)
}
@@ -267,6 +268,7 @@ static const char *GetCodeName(unsigned
STRINGIFY_CODE(FUNC_CODE, INST_BR)
STRINGIFY_CODE(FUNC_CODE, INST_SWITCH)
STRINGIFY_CODE(FUNC_CODE, INST_INVOKE)
+ STRINGIFY_CODE(FUNC_CODE, INST_UNOP)
STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE)
STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET)
STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET)
More information about the llvm-commits
mailing list