diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 46 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/TargetLoweringBase.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 67 | ||||
| -rw-r--r-- | llvm/lib/IR/Core.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/IR/Instruction.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/IR/Instructions.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/IR/Verifier.cpp | 3 |
13 files changed, 93 insertions, 64 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 819f8a0712d..c6df821a22c 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -837,6 +837,7 @@ lltok::Kind LLLexer::LexIdentifier() { } while (false) INSTKEYWORD(fneg, FNeg); + INSTKEYWORD(freeze, Freeze); INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd); INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 042f324249f..c204a9448ce 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3414,7 +3414,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { } // Unary Operators. - case lltok::kw_fneg: { + case lltok::kw_fneg: + case lltok::kw_freeze: { unsigned Opc = Lex.getUIntVal(); Constant *Val; Lex.Lex(); @@ -3429,6 +3430,8 @@ 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; @@ -5722,6 +5725,7 @@ 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: @@ -6325,16 +6329,14 @@ bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { /// ParseUnaryOp /// ::= UnaryOp TypeAndValue ',' Value /// -/// If IsFP is false, then any integer operand is allowed, if it is true, any fp -/// operand is allowed. +/// If IsFP is true, then fp operand is only 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() - : LHS->getType()->isIntOrIntVectorTy(); + bool Valid = !IsFP || LHS->getType()->isFPOrFPVectorTy(); if (!Valid) return Error(Loc, "invalid operand type for instruction"); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 2ebfb9da257..e418f7cbfb4 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -279,6 +279,7 @@ enum Kind { // Instruction Opcodes (Opcode in UIntVal). kw_fneg, + kw_freeze, kw_add, kw_fadd, kw_sub, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index ed736298dfa..71166ba337e 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1055,16 +1055,13 @@ 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 IsFP ? Instruction::FNeg : -1; + return Ty->isFPOrFPVectorTy() ? Instruction::FNeg : -1; + case bitc::UNOP_FREEZE: + return Instruction::Freeze; } } @@ -3865,7 +3862,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) || + if (getValueTypePair(Record, OpNum, NextValueNo, LHS, &FullTy) || OpNum+1 > Record.size()) return error("Invalid record"); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index deb4019ea8b..86d20e920fe 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -521,6 +521,7 @@ 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; } } @@ -2433,6 +2434,17 @@ 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; @@ -2444,16 +2456,6 @@ 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); @@ -2611,6 +2613,17 @@ 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; @@ -2626,19 +2639,6 @@ 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; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 0e6e7027e0c..914edad0b8b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10592,3 +10592,8 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { lowerWorkItem(W, SI.getCondition(), SwitchMBB, DefaultMBB); } } + +void SelectionDAGBuilder::visitFreeze(const User &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 bfcf30b430b..c288a4f6908 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -668,6 +668,7 @@ 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); diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index cb95d47e598..c5b12902949 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1663,6 +1663,7 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const { case ExtractValue: return ISD::MERGE_VALUES; case InsertValue: return ISD::MERGE_VALUES; case LandingPad: return 0; + case Freeze: return 0; } llvm_unreachable("Unknown instruction type encountered!"); diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index a6cd8331008..218a25fdfff 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -941,43 +941,52 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, Constant *llvm::ConstantFoldUnaryInstruction(unsigned Opcode, Constant *C) { assert(Instruction::isUnaryOp(Opcode) && "Non-unary instruction detected"); - // Handle scalar UndefValue. Vectors are always evaluated per element. - bool HasScalarUndef = !C->getType()->isVectorTy() && isa<UndefValue>(C); + switch (static_cast<Instruction::UnaryOps>(Opcode)) { + default: + break; + case Instruction::FNeg: { + // Handle scalar UndefValue. Vectors are always evaluated per element. + bool HasScalarUndef = !C->getType()->isVectorTy() && isa<UndefValue>(C); - if (HasScalarUndef) { - switch (static_cast<Instruction::UnaryOps>(Opcode)) { - case Instruction::FNeg: + if (HasScalarUndef) { 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"); - // We only have FP UnaryOps right now. - assert(!isa<ConstantInt>(C) && "Unexpected Integer UnaryOp"); + // Constant should not be UndefValue, unless these are vector constants. + assert(!HasScalarUndef && "Unexpected UndefValue"); + assert(!isa<ConstantInt>(C) && "Unexpected Integer UnaryOp"); - if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { - const APFloat &CV = CFP->getValueAPF(); - switch (Opcode) { - default: - break; - case Instruction::FNeg: + if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { + const APFloat &CV = CFP->getValueAPF(); 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); + } 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)); + } - Result.push_back(ConstantExpr::get(Opcode, Elt)); + return ConstantVector::get(Result); } - - 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; + } + break; + } + case Instruction::UnaryOpsEnd: + llvm_unreachable("Invalid UnaryOp"); } // We don't know how to fold this. diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 03bff7e5fde..78ae36c9018 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -3410,6 +3410,11 @@ 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)); } diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index b157c7bb34b..2e9310c1173 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -307,6 +307,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { // Standard unary operators... case FNeg: return "fneg"; + case Freeze: return "freeze"; // Standard binary operators... case Add: return "add"; diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index f62ec8fbec1..95521ad9121 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -2232,6 +2232,9 @@ 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 diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index e89d8b0a9b5..91026c3b1b2 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3145,6 +3145,9 @@ 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!"); } |

