diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 25 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 1 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 3 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 50 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 2 | ||||
| -rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 65 | ||||
| -rw-r--r-- | llvm/lib/IR/Core.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/IR/Instruction.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/IR/Instructions.cpp | 23 | ||||
| -rw-r--r-- | llvm/lib/IR/Verifier.cpp | 3 |
13 files changed, 127 insertions, 86 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 847ca0430e6..d96b5e0bff5 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -839,7 +839,6 @@ lltok::Kind LLLexer::LexIdentifier() { } while (false) INSTKEYWORD(fneg, FNeg); - INSTKEYWORD(freeze, Freeze); INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd); INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub); @@ -896,6 +895,8 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(catchpad, CatchPad); INSTKEYWORD(cleanuppad, CleanupPad); + INSTKEYWORD(freeze, Freeze); + #undef INSTKEYWORD #define DWKEYWORD(TYPE, TOKEN) \ diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index bb2c65f6d9a..fc14e5e1e1f 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3418,8 +3418,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { } // Unary Operators. - case lltok::kw_fneg: - case lltok::kw_freeze: { + case lltok::kw_fneg: { unsigned Opc = Lex.getUIntVal(); Constant *Val; Lex.Lex(); @@ -3434,8 +3433,6 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (!Val->getType()->isFPOrFPVectorTy()) return Error(ID.Loc, "constexpr requires fp operands"); break; - case Instruction::Freeze: - break; default: llvm_unreachable("Unknown unary operator!"); } unsigned Flags = 0; @@ -5729,7 +5726,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, Inst->setFastMathFlags(FMF); return false; } - case lltok::kw_freeze: return ParseUnaryOp(Inst, PFS, KeywordVal, false); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -5833,6 +5829,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, return 0; } case lltok::kw_landingpad: return ParseLandingPad(Inst, PFS); + case lltok::kw_freeze: return ParseFreeze(Inst, PFS); // Call. case lltok::kw_call: return ParseCall(Inst, PFS, CallInst::TCK_None); case lltok::kw_tail: return ParseCall(Inst, PFS, CallInst::TCK_Tail); @@ -6333,14 +6330,16 @@ bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { /// ParseUnaryOp /// ::= UnaryOp TypeAndValue ',' Value /// -/// If IsFP is true, then fp operand is only allowed. +/// If IsFP is false, then any integer operand is allowed, if it is true, any fp +/// operand is allowed. bool LLParser::ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc, bool IsFP) { LocTy Loc; Value *LHS; if (ParseTypeAndValue(LHS, Loc, PFS)) return true; - bool Valid = !IsFP || LHS->getType()->isFPOrFPVectorTy(); + bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy() + : LHS->getType()->isIntOrIntVectorTy(); if (!Valid) return Error(Loc, "invalid operand type for instruction"); @@ -6754,6 +6753,18 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { return false; } +/// ParseFreeze +/// ::= 'freeze' Type Value +bool LLParser::ParseFreeze(Instruction *&Inst, PerFunctionState &PFS) { + LocTy Loc; + Value *Op; + if (ParseTypeAndValue(Op, Loc, PFS)) + return true; + + Inst = new FreezeInst(Op); + return false; +} + /// ParseCall /// ::= 'call' OptionalFastMathFlags OptionalCallingConv /// OptionalAttrs Type Value ParameterList OptionalAttrs diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index abc423b4e3c..cf2121dcc70 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -600,6 +600,7 @@ namespace llvm { int ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS); int ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS); int ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS); + bool ParseFreeze(Instruction *&I, PerFunctionState &PFS); // Use-list order directives. bool ParseUseListOrder(PerFunctionState *PFS = nullptr); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 9029e15af9f..e430e0f6faa 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -280,7 +280,6 @@ enum Kind { // Instruction Opcodes (Opcode in UIntVal). kw_fneg, - kw_freeze, kw_add, kw_fadd, kw_sub, @@ -355,6 +354,8 @@ enum Kind { kw_insertvalue, kw_blockaddress, + kw_freeze, + // Metadata types. kw_distinct, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 92c3e1d2dd8..b99ade6a785 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1056,13 +1056,16 @@ 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_FNEG: - return Ty->isFPOrFPVectorTy() ? Instruction::FNeg : -1; - case bitc::UNOP_FREEZE: - return Instruction::Freeze; + return IsFP ? Instruction::FNeg : -1; } } @@ -3863,7 +3866,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_UNOP: { // UNOP: [opval, ty, opcode] unsigned OpNum = 0; Value *LHS; - if (getValueTypePair(Record, OpNum, NextValueNo, LHS, &FullTy) || + if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || OpNum+1 > Record.size()) return error("Invalid record"); @@ -5116,6 +5119,19 @@ Error BitcodeReader::parseFunctionBody(Function *F) { OperandBundles.emplace_back(BundleTags[Record[0]], std::move(Inputs)); continue; } + + case bitc::FUNC_CODE_INST_FREEZE: { // FREEZE: [opty,opval] + unsigned OpNum = 0; + Value *Op = nullptr; + if (getValueTypePair(Record, OpNum, NextValueNo, Op, &FullTy)) + return error("Invalid record"); + if (OpNum != Record.size()) + return error("Invalid record"); + + I = new FreezeInst(Op); + InstructionList.push_back(I); + break; + } } // Add instruction to end of current BB. If there is no current BB, reject diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index c3531a7ecac..6defe3ae7a0 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -521,7 +521,6 @@ static unsigned getEncodedUnaryOpcode(unsigned Opcode) { switch (Opcode) { default: llvm_unreachable("Unknown binary instruction!"); case Instruction::FNeg: return bitc::UNOP_FNEG; - case Instruction::Freeze: return bitc::UNOP_FREEZE; } } @@ -2435,17 +2434,6 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); Record.push_back(VE.getValueID(C->getOperand(0))); AbbrevToUse = CONSTANTS_CE_CAST_Abbrev; - } else if (Instruction::isUnaryOp(CE->getOpcode())) { - 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) { - assert(CE->getOpcode() == Instruction::FNeg); - Record.push_back(Flags); - } - break; } else { assert(CE->getNumOperands() == 2 && "Unknown constant expr!"); Code = bitc::CST_CODE_CE_BINOP; @@ -2457,6 +2445,16 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, 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); @@ -2614,17 +2612,6 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, AbbrevToUse = FUNCTION_INST_CAST_ABBREV; Vals.push_back(VE.getTypeID(I.getType())); Vals.push_back(getEncodedCastOpcode(I.getOpcode())); - } else if (isa<UnaryOperator>(I)) { - 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); - } } else { assert(isa<BinaryOperator>(I) && "Unknown instruction!"); Code = bitc::FUNC_CODE_INST_BINOP; @@ -2640,6 +2627,19 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, } } 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; @@ -3034,6 +3034,10 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, pushValue(I.getOperand(0), InstID, Vals); // valist. Vals.push_back(VE.getTypeID(I.getType())); // restype. break; + case Instruction::Freeze: + Code = bitc::FUNC_CODE_INST_FREEZE; + pushValueAndType(I.getOperand(0), InstID, Vals); + break; } Stream.EmitRecord(Code, Vals, AbbrevToUse); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 914edad0b8b..18fef7db9c7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10593,7 +10593,7 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { } } -void SelectionDAGBuilder::visitFreeze(const User &I) { +void SelectionDAGBuilder::visitFreeze(const FreezeInst &I) { SDValue N = getValue(I.getOperand(0)); setValue(&I, N); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index c288a4f6908..1579ef3ad75 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -668,7 +668,6 @@ private: void visitUnary(const User &I, unsigned Opcode); void visitFNeg(const User &I) { visitUnary(I, ISD::FNEG); } - void visitFreeze(const User &I); void visitBinary(const User &I, unsigned Opcode); void visitShift(const User &I, unsigned Opcode); @@ -743,6 +742,7 @@ private: void visitAtomicStore(const StoreInst &I); void visitLoadFromSwiftError(const LoadInst &I); void visitStoreToSwiftError(const StoreInst &I); + void visitFreeze(const FreezeInst &I); void visitInlineAsm(ImmutableCallSite CS); void visitIntrinsicCall(const CallInst &I, unsigned Intrinsic); diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 84f86523de5..a6cd8331008 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -941,50 +941,43 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) { assert(Instruction::isUnaryOp(Opcode) && "Non-unary instruction detected"); - switch (static_cast<Instruction::UnaryOps>(Opcode)) { - case Instruction::FNeg: { - // Handle scalar UndefValue. Vectors are always evaluated per element. - bool HasScalarUndef = !C->getType()->isVectorTy() && isa<UndefValue>(C); + // Handle scalar UndefValue. Vectors are always evaluated per element. + bool HasScalarUndef = !C->getType()->isVectorTy() && isa<UndefValue>(C); - if (HasScalarUndef) { + if (HasScalarUndef) { + switch (static_cast<Instruction::UnaryOps>(Opcode)) { + case Instruction::FNeg: return C; // -undef -> undef + case Instruction::UnaryOpsEnd: + llvm_unreachable("Invalid UnaryOp"); } + } - // Constant should not be UndefValue, unless these are vector constants. - assert(!HasScalarUndef && "Unexpected UndefValue"); - assert(!isa<ConstantInt>(C) && "Unexpected Integer UnaryOp"); + // Constant should not be UndefValue, unless these are vector constants. + assert(!HasScalarUndef && "Unexpected UndefValue"); + // We only have FP UnaryOps right now. + assert(!isa<ConstantInt>(C) && "Unexpected Integer UnaryOp"); - if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { - const APFloat &CV = CFP->getValueAPF(); + if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { + const APFloat &CV = CFP->getValueAPF(); + switch (Opcode) { + default: + break; + case Instruction::FNeg: return ConstantFP::get(C->getContext(), neg(CV)); - } else if (VectorType *VTy = dyn_cast<VectorType>(C->getType())) { - // Fold each element and create a vector constant from those constants. - SmallVector<Constant*, 16> Result; - Type *Ty = IntegerType::get(VTy->getContext(), 32); - for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { - Constant *ExtractIdx = ConstantInt::get(Ty, i); - Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx); - - Result.push_back(ConstantExpr::get(Opcode, Elt)); - } - - return ConstantVector::get(Result); } - break; - } - case Instruction::Freeze: { - if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { - return CFP; - } else if (ConstantInt *CINT = dyn_cast<ConstantInt>(C)) { - return CINT; - } else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { - // A global variable is neither undef nor poison. - return GV; + } else if (VectorType *VTy = dyn_cast<VectorType>(C->getType())) { + // Fold each element and create a vector constant from those constants. + SmallVector<Constant*, 16> Result; + Type *Ty = IntegerType::get(VTy->getContext(), 32); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + Constant *ExtractIdx = ConstantInt::get(Ty, i); + Constant *Elt = ConstantExpr::getExtractElement(C, ExtractIdx); + + Result.push_back(ConstantExpr::get(Opcode, Elt)); } - break; - } - case Instruction::UnaryOpsEnd: - llvm_unreachable("Invalid UnaryOp"); + + return ConstantVector::get(Result); } // We don't know how to fold this. diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 78ae36c9018..d7b86d33a3d 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -3410,11 +3410,6 @@ LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateFNeg(unwrap(V), Name)); } -LLVMValueRef LLVMBuildFreeze(LLVMBuilderRef B, LLVMValueRef V, - const char *Name) { - return wrap(unwrap(B)->CreateFreeze(unwrap(V), Name)); -} - LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { return wrap(unwrap(B)->CreateNot(unwrap(V), Name)); } @@ -3902,6 +3897,11 @@ LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef B, LLVMValueRef AggVal, Index, Name)); } +LLVMValueRef LLVMBuildFreeze(LLVMBuilderRef B, LLVMValueRef Val, + const char *Name) { + return wrap(unwrap(B)->CreateFreeze(unwrap(Val), Name)); +} + LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef B, LLVMValueRef Val, const char *Name) { return wrap(unwrap(B)->CreateIsNull(unwrap(Val), Name)); diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 2e9310c1173..7da16971289 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -307,7 +307,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { // Standard unary operators... case FNeg: return "fneg"; - case Freeze: return "freeze"; // Standard binary operators... case Add: return "add"; @@ -369,6 +368,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case InsertValue: return "insertvalue"; case LandingPad: return "landingpad"; case CleanupPad: return "cleanuppad"; + case Freeze: return "freeze"; default: return "<Invalid operator> "; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 9db6d87ba78..2a49a758a46 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -2232,9 +2232,6 @@ void UnaryOperator::AssertOK() { "Tried to create a floating-point operation on a " "non-floating-point type!"); break; - case Freeze: - // Freeze can take any type as an argument. - break; default: llvm_unreachable("Invalid opcode provided"); } #endif @@ -4095,6 +4092,22 @@ void IndirectBrInst::removeDestination(unsigned idx) { } //===----------------------------------------------------------------------===// +// FreezeInst Implementation +//===----------------------------------------------------------------------===// + +FreezeInst::FreezeInst(Value *S, + const Twine &Name, Instruction *InsertBefore) + : UnaryInstruction(S->getType(), Freeze, S, InsertBefore) { + setName(Name); +} + +FreezeInst::FreezeInst(Value *S, + const Twine &Name, BasicBlock *InsertAtEnd) + : UnaryInstruction(S->getType(), Freeze, S, InsertAtEnd) { + setName(Name); +} + +//===----------------------------------------------------------------------===// // cloneImpl() implementations //===----------------------------------------------------------------------===// @@ -4310,3 +4323,7 @@ UnreachableInst *UnreachableInst::cloneImpl() const { LLVMContext &Context = getContext(); return new UnreachableInst(Context); } + +FreezeInst *FreezeInst::cloneImpl() const { + return new FreezeInst(getOperand(0)); +} diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 91026c3b1b2..e89d8b0a9b5 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3145,9 +3145,6 @@ void Verifier::visitUnaryOperator(UnaryOperator &U) { Assert(U.getType()->isFPOrFPVectorTy(), "FNeg operator only works with float types!", &U); break; - case Instruction::Freeze: - // Freeze can take all kinds of types. - break; default: llvm_unreachable("Unknown UnaryOperator opcode!"); } |

