Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/AsmParser/LLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,8 @@ namespace llvm {
bool parseExtractElement(Instruction *&Inst, PerFunctionState &PFS);
bool parseInsertElement(Instruction *&Inst, PerFunctionState &PFS);
bool parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS);
bool parseBitExtract(Instruction *&Inst, PerFunctionState &PFS);
bool parseBitInsert(Instruction *&Inst, PerFunctionState &PFS);
int parsePHI(Instruction *&Inst, PerFunctionState &PFS);
bool parseLandingPad(Instruction *&Inst, PerFunctionState &PFS);
bool parseCall(Instruction *&Inst, PerFunctionState &PFS,
Expand Down
65 changes: 63 additions & 2 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4736,6 +4736,12 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
return true;
}

if(Opc == Instruction::BitExtract) {
if (parseType(Ty) ||
parseToken(lltok::comma, "expected comma after bitextract's type"))
return true;
}

if (parseGlobalValueVector(Elts) ||
parseToken(lltok::rparen, "expected ')' in constantexpr"))
return true;
Expand Down Expand Up @@ -4805,14 +4811,26 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
if (!ExtractElementInst::isValidOperands(Elts[0], Elts[1]))
return error(ID.Loc, "invalid extractelement operands");
ID.ConstantVal = ConstantExpr::getExtractElement(Elts[0], Elts[1]);
} else {
assert(Opc == Instruction::InsertElement && "Unknown opcode");
} else if (Opc == Instruction::InsertElement) {
if (Elts.size() != 3)
return error(ID.Loc, "expected three operands to insertelement");
if (!InsertElementInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
return error(ID.Loc, "invalid insertelement operands");
ID.ConstantVal =
ConstantExpr::getInsertElement(Elts[0], Elts[1],Elts[2]);
} else if (Opc == Instruction::BitInsert) {
if (Elts.size() != 3)
return error(ID.Loc, "expected three operands to bitinsert");
if (!BitInsertInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
return error(ID.Loc, "invalid bitinsert operands");
ID.ConstantVal = ConstantExpr::getBitInsert(Elts[0], Elts[1], Elts[2]);
} else {
assert(Opc == Instruction::BitExtract && "Unknown opcode");
if (Elts.size() != 2)
return error(ID.Loc, "expected two operands to bitextract");
if (!BitExtractInst::isValidOperands(Ty, Elts[0], Elts[1]))
return error(ID.Loc, "invalid bitextract operands");
ID.ConstantVal = ConstantExpr::getBitExtract(Ty, Elts[0], Elts[1]);
}

ID.Kind = ValID::t_Constant;
Expand Down Expand Up @@ -7721,6 +7739,10 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
return parseLandingPad(Inst, PFS);
case lltok::kw_freeze:
return parseFreeze(Inst, PFS);
case lltok::kw_bitinsert:
return parseBitInsert(Inst, PFS);
case lltok::kw_bitextract:
return parseBitExtract(Inst, PFS);
// Call.
case lltok::kw_call:
return parseCall(Inst, PFS, CallInst::TCK_None);
Expand Down Expand Up @@ -8538,6 +8560,45 @@ bool LLParser::parseInsertElement(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}

// parseBitExtract
// ::= 'bitextract' Type ',' TypeAndValue ',' TypeAndValue
bool LLParser::parseBitExtract(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc = Lex.getLoc();
Type *Ty = nullptr;
Value *Op0, *Op1;
if (parseType(Ty) ||
parseToken(lltok::comma, "expected ',' after bitextract type") ||
parseTypeAndValue(Op0, PFS) ||
parseToken(lltok::comma, "expected ',' after bitextract source value") ||
parseTypeAndValue(Op1, PFS))
return true;

if (!BitExtractInst::isValidOperands(Ty, Op0, Op1))
return error(Loc, "invalid bitextract operands");

Inst = BitExtractInst::Create(Ty, Op0, Op1);
return false;
}

// parseBitInsert
// ::= 'bitinsert' TypeAndValue ',' TypeAndValue ',' TypeAndValue
bool LLParser::parseBitInsert(Instruction *&Inst, PerFunctionState &PFS) {
LocTy Loc = Lex.getLoc();
Value *Op0, *Op1, *Op2;
if (parseTypeAndValue(Op0, Loc, PFS) ||
parseToken(lltok::comma, "expected ',' after bitinsert source value") ||
parseTypeAndValue(Op1, PFS) ||
parseToken(lltok::comma, "expected ',' after bitinsert insert value") ||
parseTypeAndValue(Op2, PFS))
return true;

if (!BitInsertInst::isValidOperands(Op0, Op1, Op2))
return error(Loc, "invalid bitinsert operands");

Inst = BitInsertInst::Create(Op0, Op1, Op2);
return false;
}

/// parseShuffleVector
/// ::= 'shufflevector' TypeAndValue ',' TypeAndValue ',' TypeAndValue
bool LLParser::parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) {
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/IR/Instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2621,7 +2621,7 @@ bool BitInsertInst::isValidOperands(const Value *Base, const Value *Val,
if (!Val->getType()->isFirstClassType())
return false;// Second operand of bitinsert must be a first-class type.

if (!Offset->getType()->isIntegerTy())
if (!Offset->getType()->isIntegerTy(32))
return false; // Third operand of bitinsert must be i32.
return true;
}
Expand All @@ -2635,7 +2635,7 @@ BitExtractInst::BitExtractInst(Type *Ty, Value *Src, Value *Offset,
InsertPosition InsertBef)
: Instruction(Ty, BitExtract, AllocMarker, InsertBef) {
assert(isValidOperands(Ty, Src, Offset) &&
"Invalid bitinsert instruction operands!");
"Invalid bitextract instruction operands!");
Op<0>() = Src;
Op<1>() = Offset;
setName(Name);
Expand All @@ -2649,7 +2649,7 @@ bool BitExtractInst::isValidOperands(const Type *Ty, const Value *Src,
if (!Src->getType()->isByteTy())
return false;// Second operand of bitextract must be a byte type.

if (!Offset->getType()->isIntegerTy())
if (!Offset->getType()->isIntegerTy(32))
return false; // Third operand of bitextract must be i32.
return true;
}
Expand Down