diff options
author | Cameron McInally <cameron.mcinally@nyu.edu> | 2018-11-13 18:15:47 +0000 |
---|---|---|
committer | Cameron McInally <cameron.mcinally@nyu.edu> | 2018-11-13 18:15:47 +0000 |
commit | cbde0d9c7be1991751dc3eb5928294d2e00ef26a (patch) | |
tree | ad839084df9863182687fadb95471920cb15381b /llvm/lib/AsmParser/LLParser.cpp | |
parent | 9d87256d3de67f7a2e8f778ee775e0b6bb309aeb (diff) | |
download | bcm5719-llvm-cbde0d9c7be1991751dc3eb5928294d2e00ef26a.tar.gz bcm5719-llvm-cbde0d9c7be1991751dc3eb5928294d2e00ef26a.zip |
[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
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 5fe1e125d48..856be2fb64a 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3295,7 +3295,31 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { 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(Instruction *&Inst, BasicBlock *BB, 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: @@ -6064,6 +6098,43 @@ bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { } //===----------------------------------------------------------------------===// +// 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. //===----------------------------------------------------------------------===// |