Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
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: 1 addition & 1 deletion llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -5145,7 +5145,7 @@ LLVM_C_ABI LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef,
LLVM_C_ABI LLVMValueRef LLVMBuildFreeze(LLVMBuilderRef, LLVMValueRef Val,
const char *Name);
LLVM_C_ABI LLVMValueRef LLVMBuildBitExtract(LLVMBuilderRef,
LLVMValueRef Type,
LLVMTypeRef Type,
LLVMValueRef Src,
LLVMValueRef Offset,
const char *Name);
Expand Down
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
2 changes: 2 additions & 0 deletions llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ enum ConstantsCodes {
// deactivation_symbol]
CST_CODE_BYTE = 35, // BYTE: [intval]
CST_CODE_WIDE_BYTE = 36, // WIDE_BYTE: [n x intval]
CST_CODE_CE_BITEXTRACT = 37, // BITEXTRACT: [opty, opval, opval]
CST_CODE_CE_BITINSERT = 38, // BITINSERT: [opval, opval, opval]
};

/// CastOpcodes - These are values used in the bitcode files to encode which
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/IR/Instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -5459,7 +5459,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitInsertInst, Value)
//===----------------------------------------------------------------------===//
class BitExtractInst: public Instruction {

constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};

LLVM_ABI BitExtractInst(Type* Ty, Value *Src, Value *Offset,
const Twine &NameStr = "",
Expand Down Expand Up @@ -5497,7 +5497,7 @@ class BitExtractInst: public Instruction {

template <>
struct OperandTraits<BitExtractInst> :
public FixedNumOperandTraits<BitExtractInst, 3> {};
public FixedNumOperandTraits<BitExtractInst, 2> {};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitExtractInst, Value)
} // end namespace llvm
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;
Type *Ty = nullptr;
Value *Op0, *Op1;
if (parseType(Ty, Loc) ||
parseToken(lltok::comma, "expected ',' after bitextract type") ||
parseTypeAndValue(Op0, Loc, 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;
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
57 changes: 57 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1835,6 +1835,14 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
I = new ShuffleVectorInst(Ops[0], Ops[1], Ops[2], "constexpr",
InsertBB);
break;
case Instruction::BitExtract:
I = BitExtractInst::Create(BC->getType(), Ops[0], Ops[1],
"constexpr", InsertBB);
break;
case Instruction::BitInsert:
I = BitInsertInst::Create(Ops[0], Ops[1], Ops[2], "constexpr",
InsertBB);
break;
default:
llvm_unreachable("Unhandled bitcode constant");
}
Expand Down Expand Up @@ -3651,6 +3659,24 @@ Error BitcodeReader::parseConstants() {
{(unsigned)Record[0], (unsigned)Record[1], IdxRecord});
break;
}
case bitc::CST_CODE_CE_BITEXTRACT: { // BITEXTRACT: [opty, opval, opval]
if (Record.size() < 3)
return error("Invalid bitextract constexpr record");
Type *SrcTy = getTypeByID(Record[0]);
if (!SrcTy)
return error("Invalid bitextract constexpr record");
V = BitcodeConstant::create(Alloc, CurTy, Instruction::BitExtract,
{(unsigned)Record[1], (unsigned)Record[2]});
break;
}
case bitc::CST_CODE_CE_BITINSERT: { // BITINSERT: [opval, opval, opval]
if (Record.size() < 3)
return error("Invalid bitinsert constexpr record");
V = BitcodeConstant::create(Alloc, CurTy, Instruction::BitInsert,
{(unsigned)Record[0], (unsigned)Record[1],
(unsigned)Record[2]});
break;
}
case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval]
VectorType *OpTy = dyn_cast<VectorType>(CurTy);
if (Record.size() < 3 || !OpTy)
Expand Down Expand Up @@ -5544,6 +5570,37 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
break;
}

case bitc::FUNC_CODE_INST_BITINSERT: { // BITINSERT: [ty, opval, opval, opval]
unsigned OpNum = 0;
Value *Base, *Val, *Offset;
unsigned BaseTypeID, ValTypeID, OffsetTypeID;
if (getValueTypePair(Record, OpNum, NextValueNo, Base, BaseTypeID, CurBB) ||
getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB) ||
getValueTypePair(Record, OpNum, NextValueNo, Offset, OffsetTypeID,
CurBB))
return error("Invalid bitinsert record");
I = BitInsertInst::Create(Base, Val, Offset);
ResTypeID = BaseTypeID;
InstructionList.push_back(I);
break;
}

case bitc::FUNC_CODE_INST_BITEXTRACT: { // BITEXTRACT: [ty, opval, opval]
unsigned OpNum = 0;
unsigned TypeID = Record[OpNum++];
Type *ResTy = getTypeByID(TypeID);
Value *Src, *Offset;
unsigned SrcTypeID, OffsetTypeID;
if (getValueTypePair(Record, OpNum, NextValueNo, Src, SrcTypeID, CurBB) ||
getValueTypePair(Record, OpNum, NextValueNo, Offset, OffsetTypeID,
CurBB))
return error("Invalid bitextract record");
I = BitExtractInst::Create(ResTy, Src, Offset);
ResTypeID = TypeID;
InstructionList.push_back(I);
break;
}

case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval]
unsigned OpNum = 0;
Value *Vec1, *Vec2, *Mask;
Expand Down
25 changes: 24 additions & 1 deletion llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3024,6 +3024,18 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
Record.push_back(VE.getTypeID(C->getOperand(2)->getType()));
Record.push_back(VE.getValueID(C->getOperand(2)));
break;
case Instruction::BitExtract:
Code = bitc::CST_CODE_CE_BITEXTRACT;
Record.push_back(VE.getTypeID(C->getType()));
Record.push_back(VE.getValueID(C->getOperand(0)));
Record.push_back(VE.getValueID(C->getOperand(1)));
break;
case Instruction::BitInsert:
Code = bitc::CST_CODE_CE_BITINSERT;
Record.push_back(VE.getValueID(C->getOperand(0)));
Record.push_back(VE.getValueID(C->getOperand(1)));
Record.push_back(VE.getValueID(C->getOperand(2)));
break;
case Instruction::ShuffleVector:
// If the return type and argument types are the same, this is a
// standard shufflevector instruction. If the types are different,
Expand Down Expand Up @@ -3246,6 +3258,18 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
pushValue(I.getOperand(1), InstID, Vals);
pushValueAndType(I.getOperand(2), InstID, Vals);
break;
case Instruction::BitExtract:
Code = bitc::FUNC_CODE_INST_BITEXTRACT;
Vals.push_back(VE.getTypeID(I.getType()));
pushValueAndType(I.getOperand(0), InstID, Vals);
pushValue(I.getOperand(1), InstID, Vals);
break;
case Instruction::BitInsert:
Code = bitc::FUNC_CODE_INST_BITINSERT;
pushValueAndType(I.getOperand(0), InstID, Vals);
pushValueAndType(I.getOperand(1), InstID, Vals);
pushValueAndType(I.getOperand(2), InstID, Vals);
Comment thread
guilhermeglopess marked this conversation as resolved.
Outdated
break;
case Instruction::ShuffleVector:
Code = bitc::FUNC_CODE_INST_SHUFFLEVEC;
pushValueAndType(I.getOperand(0), InstID, Vals);
Expand Down Expand Up @@ -3613,7 +3637,6 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
pushValueAndType(I.getOperand(0), InstID, Vals);
break;
}

Stream.EmitRecord(Code, Vals, AbbrevToUse);
Vals.clear();
}
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4802,6 +4802,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ' ';
TypePrinter.print(GEP->getSourceElementType(), Out);
Out << ',';
} else if (isa<BitExtractInst>(I)) {
Out << ' ';
TypePrinter.print(I.getType(), Out);
Out << ',';
} else if (const auto *LI = dyn_cast<LoadInst>(&I)) {
Out << ' ';
TypePrinter.print(LI->getType(), Out);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/ConstantsContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ struct ConstantExprKeyType {
case Instruction::BitInsert:
return new BitInsertInstConstantExpr(Ops[0], Ops[1], Ops[2]);
case Instruction::BitExtract:
return new BitExtractInstConstantExpr(Ty, Ops[1], Ops[2]);
return new BitExtractInstConstantExpr(Ty, Ops[0], Ops[1]);
}
}
};
Expand Down
8 changes: 4 additions & 4 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 Expand Up @@ -4553,7 +4553,7 @@ BitInsertInst *BitInsertInst::cloneImpl() const {
}

BitExtractInst *BitExtractInst::cloneImpl() const {
return BitExtractInst::Create(getType(), getOperand(1), getOperand(2));
return BitExtractInst::Create(getType(), getOperand(0), getOperand(1));
}

ShuffleVectorInst *ShuffleVectorInst::cloneImpl() const {
Expand Down
6 changes: 6 additions & 0 deletions llvm/test/Assembler/bitextract-invalid-1.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s
; CHECK: invalid bitextract operands
define i8 @invalid(i32 %src) {
%r = bitextract i8, i32 %src, i32 0
ret i8 %r
}
15 changes: 15 additions & 0 deletions llvm/test/Assembler/bitinsert-bitextract.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; RUN: llvm-as < %s | llvm-dis | FileCheck %s

; CHECK-LABEL: test_bitextract
; CHECK: bitextract i8, b32 %{{.*}}, i32 24
define i8 @test_bitextract(b32 %src) {
%result = bitextract i8, b32 %src, i32 24
ret i8 %result
}

; CHECK-LABEL: test_bitinsert
; CHECK: bitinsert b32 %{{.*}}, i8 %{{.*}}, i32 3
define b32 @test_bitinsert(b32 %base, i8 %val) {
%result = bitinsert b32 %base, i8 %val, i32 3
ret b32 %result
}
6 changes: 6 additions & 0 deletions llvm/test/Assembler/bitinsert-invalid-1.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s
; CHECK: invalid bitinsert operands
define i32 @invalid(i32 %base, i8 %val) {
%r = bitinsert i32 %base, i8 %val, i32 0
ret i32 %r
}
6 changes: 3 additions & 3 deletions llvm/tools/llvm-c-test/echo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,9 +1010,9 @@ struct FunCloner {
break;
}
case LLVMBitExtract: {
LLVMValueRef Type = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef SrcV = CloneValue(LLVMGetOperand(Src, 1));
LLVMValueRef Offset = CloneValue(LLVMGetOperand(Src, 2));
LLVMTypeRef Type = CloneType(LLVMTypeOf(Src));
LLVMValueRef SrcV = CloneValue(LLVMGetOperand(Src, 0));
LLVMValueRef Offset = CloneValue(LLVMGetOperand(Src, 1));
Dst = LLVMBuildBitExtract(Builder, Type, SrcV, Offset, Name);
break;
}
Expand Down