Commit 47661568 by Karl Schimpf

Add phi instruction to Subzero bitcode reader.

parent 65d8d532
...@@ -823,7 +823,7 @@ public: ...@@ -823,7 +823,7 @@ public:
for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(), for (Function::const_arg_iterator ArgI = LLVMFunc->arg_begin(),
ArgE = LLVMFunc->arg_end(); ArgE = LLVMFunc->arg_end();
ArgI != ArgE; ++ArgI) { ArgI != ArgE; ++ArgI) {
Func->addArg(NextInstVar(Context->convertToIceType(ArgI->getType()))); Func->addArg(getNextInstVar(Context->convertToIceType(ArgI->getType())));
} }
} }
...@@ -884,7 +884,7 @@ private: ...@@ -884,7 +884,7 @@ private:
Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); } Ice::CfgNode *InstallNextBasicBlock() { return Func->makeNode(); }
// Returns the Index-th basic block in the list of basic blocks. // Returns the Index-th basic block in the list of basic blocks.
Ice::CfgNode *GetBasicBlock(uint32_t Index) { Ice::CfgNode *getBasicBlock(uint32_t Index) {
const Ice::NodeList &Nodes = Func->getNodes(); const Ice::NodeList &Nodes = Func->getNodes();
if (Index >= Nodes.size()) { if (Index >= Nodes.size()) {
std::string Buffer; std::string Buffer;
...@@ -907,33 +907,34 @@ private: ...@@ -907,33 +907,34 @@ private:
Error("Branch to entry block not allowed"); Error("Branch to entry block not allowed");
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
} }
return GetBasicBlock(Index); return getBasicBlock(Index);
} }
// Generates the next available local variable using the given // Generates the next available local variable using the given type.
// type. Note: if Ty is void, this function returns NULL. Ice::Variable *getNextInstVar(Ice::Type Ty) {
Ice::Variable *NextInstVar(Ice::Type Ty) { if (Ty == Ice::IceType_void) {
if (Ty == Ice::IceType_void) Error("Can't define instruction value using type void");
return NULL; // Recover since we can't throw an exception.
Ty = Ice::IceType_i32;
}
Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode); Ice::Variable *Var = Func->makeVariable(Ty, CurrentNode);
LocalOperands.push_back(Var); LocalOperands.push_back(Var);
return Var; return Var;
} }
// Converts a relative index (to the next instruction to be read) to // Converts a relative index (wrt to BaseIndex) to an absolute value
// an absolute value index. // index.
uint32_t convertRelativeToAbsIndex(int32_t Id) { uint32_t convertRelativeToAbsIndex(int32_t Id, int32_t BaseIndex) {
int32_t AbsNextId = CachedNumGlobalValueIDs + LocalOperands.size(); if (BaseIndex < Id) {
if (Id > 0 && AbsNextId < Id) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Invalid relative value id: " << Id StrBuf << "Invalid relative value id: " << Id
<< " (must be <= " << AbsNextId << ")"; << " (must be <= " << BaseIndex << ")";
Error(StrBuf.str()); Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
return 0; return 0;
} }
return AbsNextId - Id; return BaseIndex - Id;
} }
// Returns the value referenced by the given value Index. // Returns the value referenced by the given value Index.
...@@ -954,10 +955,15 @@ private: ...@@ -954,10 +955,15 @@ private:
return LocalOperands[LocalIndex]; return LocalOperands[LocalIndex];
} }
// Returns the relative operand (wrt to next instruction) referenced by // Returns the relative operand (wrt to BaseIndex) referenced by
// the given value index. // the given value Index.
Ice::Operand *getRelativeOperand(uint32_t Index) { Ice::Operand *getRelativeOperand(int32_t Index, int32_t BaseIndex) {
return getOperand(convertRelativeToAbsIndex(Index)); return getOperand(convertRelativeToAbsIndex(Index, BaseIndex));
}
// Returns the absolute index of the next value generating instruction.
uint32_t getNextInstIndex() const {
return CachedNumGlobalValueIDs + LocalOperands.size();
} }
// Generates type error message for binary operator Op // Generates type error message for binary operator Op
...@@ -1316,9 +1322,10 @@ void FunctionParser::ProcessRecord() { ...@@ -1316,9 +1322,10 @@ void FunctionParser::ProcessRecord() {
const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); const NaClBitcodeRecord::RecordVector &Values = Record.GetValues();
if (InstIsTerminating) { if (InstIsTerminating) {
InstIsTerminating = false; InstIsTerminating = false;
CurrentNode = GetBasicBlock(++CurrentBbIndex); CurrentNode = getBasicBlock(++CurrentBbIndex);
} }
Ice::Inst *Inst = NULL; // The base index for relative indexing.
int32_t BaseIndex = getNextInstIndex();
switch (Record.GetCode()) { switch (Record.GetCode()) {
case naclbitc::FUNC_CODE_DECLAREBLOCKS: { case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
// DECLAREBLOCKS: [n] // DECLAREBLOCKS: [n]
...@@ -1344,8 +1351,8 @@ void FunctionParser::ProcessRecord() { ...@@ -1344,8 +1351,8 @@ void FunctionParser::ProcessRecord() {
// BINOP: [opval, opval, opcode] // BINOP: [opval, opval, opcode]
if (!isValidRecordSize(3, "function block binop")) if (!isValidRecordSize(3, "function block binop"))
return; return;
Ice::Operand *Op1 = getRelativeOperand(Values[0]); Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *Op2 = getRelativeOperand(Values[1]); Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Ice::Type Type1 = Op1->getType(); Ice::Type Type1 = Op1->getType();
Ice::Type Type2 = Op2->getType(); Ice::Type Type2 = Op2->getType();
if (Type1 != Type2) { if (Type1 != Type2) {
...@@ -1360,15 +1367,15 @@ void FunctionParser::ProcessRecord() { ...@@ -1360,15 +1367,15 @@ void FunctionParser::ProcessRecord() {
Ice::InstArithmetic::OpKind Opcode; Ice::InstArithmetic::OpKind Opcode;
if (!convertBinopOpcode(Values[2], Type1, Opcode)) if (!convertBinopOpcode(Values[2], Type1, Opcode))
return; return;
Ice::Variable *Dest = NextInstVar(Type1); CurrentNode->appendInst(Ice::InstArithmetic::create(
Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2); Func, Opcode, getNextInstVar(Type1), Op1, Op2));
break; break;
} }
case naclbitc::FUNC_CODE_INST_CAST: { case naclbitc::FUNC_CODE_INST_CAST: {
// CAST: [opval, destty, castopc] // CAST: [opval, destty, castopc]
if (!isValidRecordSize(3, "function block cast")) if (!isValidRecordSize(3, "function block cast"))
return; return;
Ice::Operand *Src = getRelativeOperand(Values[0]); Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Type *CastType = Context->getTypeByID(Values[1]); Type *CastType = Context->getTypeByID(Values[1]);
Instruction::CastOps LLVMCastOp; Instruction::CastOps LLVMCastOp;
Ice::InstCast::OpKind CastKind; Ice::InstCast::OpKind CastKind;
...@@ -1389,15 +1396,16 @@ void FunctionParser::ProcessRecord() { ...@@ -1389,15 +1396,16 @@ void FunctionParser::ProcessRecord() {
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType)); CurrentNode->appendInst(Ice::InstCast::create(
Inst = Ice::InstCast::create(Func, CastKind, Dest, Src); Func, CastKind, getNextInstVar(Context->convertToIceType(CastType)),
Src));
break; break;
} }
case naclbitc::FUNC_CODE_INST_VSELECT: { case naclbitc::FUNC_CODE_INST_VSELECT: {
// VSELECT: [opval, opval, pred] // VSELECT: [opval, opval, pred]
Ice::Operand *ThenVal = getOperand(convertRelativeToAbsIndex(Values[0])); Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex);
Ice::Type ThenType = ThenVal->getType(); Ice::Type ThenType = ThenVal->getType();
Ice::Operand *ElseVal = getOperand(convertRelativeToAbsIndex(Values[1])); Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex);
Ice::Type ElseType = ElseVal->getType(); Ice::Type ElseType = ElseVal->getType();
if (ThenType != ElseType) { if (ThenType != ElseType) {
std::string Buffer; std::string Buffer;
...@@ -1407,7 +1415,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1407,7 +1415,7 @@ void FunctionParser::ProcessRecord() {
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
Ice::Operand *CondVal = getOperand(convertRelativeToAbsIndex(Values[2])); Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
Ice::Type CondType = CondVal->getType(); Ice::Type CondType = CondVal->getType();
if (isVectorType(CondType)) { if (isVectorType(CondType)) {
if (!isVectorType(ThenType) || if (!isVectorType(ThenType) ||
...@@ -1427,15 +1435,15 @@ void FunctionParser::ProcessRecord() { ...@@ -1427,15 +1435,15 @@ void FunctionParser::ProcessRecord() {
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
Ice::Variable *DestVal = NextInstVar(ThenType); CurrentNode->appendInst(Ice::InstSelect::create(
Inst = Ice::InstSelect::create(Func, DestVal, CondVal, ThenVal, ElseVal); Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
break; break;
} }
case naclbitc::FUNC_CODE_INST_EXTRACTELT: { case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
// EXTRACTELT: [opval, opval] // EXTRACTELT: [opval, opval]
if (!isValidRecordSize(2, "function block extract element")) if (!isValidRecordSize(2, "function block extract element"))
return; return;
Ice::Operand *Vec = getRelativeOperand(Values[0]); Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Ice::Type VecType = Vec->getType(); Ice::Type VecType = Vec->getType();
if (!Ice::isVectorType(VecType)) { if (!Ice::isVectorType(VecType)) {
std::string Buffer; std::string Buffer;
...@@ -1443,7 +1451,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1443,7 +1451,7 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Extractelement not on vector. Found: " << Vec; StrBuf << "Extractelement not on vector. Found: " << Vec;
Error(StrBuf.str()); Error(StrBuf.str());
} }
Ice::Operand *Index = getRelativeOperand(Values[1]); Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex);
if (Index->getType() != Ice::IceType_i32) { if (Index->getType() != Ice::IceType_i32) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
...@@ -1452,15 +1460,15 @@ void FunctionParser::ProcessRecord() { ...@@ -1452,15 +1460,15 @@ void FunctionParser::ProcessRecord() {
} }
// TODO(kschimpf): Restrict index to a legal constant index (once // TODO(kschimpf): Restrict index to a legal constant index (once
// constants can be defined). // constants can be defined).
Ice::Variable *Dest = NextInstVar(typeElementType(VecType)); CurrentNode->appendInst(Ice::InstExtractElement::create(
Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index); Func, getNextInstVar(typeElementType(VecType)), Vec, Index));
break; break;
} }
case naclbitc::FUNC_CODE_INST_INSERTELT: { case naclbitc::FUNC_CODE_INST_INSERTELT: {
// INSERTELT: [opval, opval, opval] // INSERTELT: [opval, opval, opval]
if (!isValidRecordSize(3, "function block insert element")) if (!isValidRecordSize(3, "function block insert element"))
return; return;
Ice::Operand *Vec = getRelativeOperand(Values[0]); Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
Ice::Type VecType = Vec->getType(); Ice::Type VecType = Vec->getType();
if (!Ice::isVectorType(VecType)) { if (!Ice::isVectorType(VecType)) {
std::string Buffer; std::string Buffer;
...@@ -1468,7 +1476,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1468,7 +1476,7 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Insertelement not on vector. Found: " << Vec; StrBuf << "Insertelement not on vector. Found: " << Vec;
Error(StrBuf.str()); Error(StrBuf.str());
} }
Ice::Operand *Elt = getRelativeOperand(Values[1]); Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex);
Ice::Type EltType = Elt->getType(); Ice::Type EltType = Elt->getType();
if (EltType != typeElementType(VecType)) { if (EltType != typeElementType(VecType)) {
std::string Buffer; std::string Buffer;
...@@ -1477,7 +1485,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1477,7 +1485,7 @@ void FunctionParser::ProcessRecord() {
<< ". Found: " << Elt; << ". Found: " << Elt;
Error(StrBuf.str()); Error(StrBuf.str());
} }
Ice::Operand *Index = getRelativeOperand(Values[2]); Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
if (Index->getType() != Ice::IceType_i32) { if (Index->getType() != Ice::IceType_i32) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
...@@ -1486,16 +1494,16 @@ void FunctionParser::ProcessRecord() { ...@@ -1486,16 +1494,16 @@ void FunctionParser::ProcessRecord() {
} }
// TODO(kschimpf): Restrict index to a legal constant index (once // TODO(kschimpf): Restrict index to a legal constant index (once
// constants can be defined). // constants can be defined).
Ice::Variable *Dest = NextInstVar(EltType); CurrentNode->appendInst(Ice::InstInsertElement::create(
Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index); Func, getNextInstVar(EltType), Vec, Elt, Index));
break; break;
} }
case naclbitc::FUNC_CODE_INST_CMP2: { case naclbitc::FUNC_CODE_INST_CMP2: {
// CMP2: [opval, opval, pred] // CMP2: [opval, opval, pred]
if (!isValidRecordSize(3, "function block compare")) if (!isValidRecordSize(3, "function block compare"))
return; return;
Ice::Operand *Op1 = getRelativeOperand(Values[0]); Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex);
Ice::Operand *Op2 = getRelativeOperand(Values[1]); Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Ice::Type Op1Type = Op1->getType(); Ice::Type Op1Type = Op1->getType();
Ice::Type Op2Type = Op2->getType(); Ice::Type Op2Type = Op2->getType();
if (Op1Type != Op2Type) { if (Op1Type != Op2Type) {
...@@ -1515,7 +1523,7 @@ void FunctionParser::ProcessRecord() { ...@@ -1515,7 +1523,7 @@ void FunctionParser::ProcessRecord() {
Error(StrBuf.str()); Error(StrBuf.str());
return; return;
} }
Ice::Variable *Dest = NextInstVar(DestType); Ice::Variable *Dest = getNextInstVar(DestType);
if (isIntegerType(Op1Type)) { if (isIntegerType(Op1Type)) {
Ice::InstIcmp::ICond Cond; Ice::InstIcmp::ICond Cond;
if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) { if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
...@@ -1527,7 +1535,8 @@ void FunctionParser::ProcessRecord() { ...@@ -1527,7 +1535,8 @@ void FunctionParser::ProcessRecord() {
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
Cond = Ice::InstIcmp::Eq; Cond = Ice::InstIcmp::Eq;
} }
Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2); CurrentNode->appendInst(
Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2));
} else if (isFloatingType(Op1Type)){ } else if (isFloatingType(Op1Type)){
Ice::InstFcmp::FCond Cond; Ice::InstFcmp::FCond Cond;
if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
...@@ -1539,7 +1548,8 @@ void FunctionParser::ProcessRecord() { ...@@ -1539,7 +1548,8 @@ void FunctionParser::ProcessRecord() {
// TODO(kschimpf) Remove error recovery once implementation complete. // TODO(kschimpf) Remove error recovery once implementation complete.
Cond = Ice::InstFcmp::False; Cond = Ice::InstFcmp::False;
} }
Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2); CurrentNode->appendInst(
Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2));
} else { } else {
// Not sure this can happen, but be safe. // Not sure this can happen, but be safe.
std::string Buffer; std::string Buffer;
...@@ -1555,9 +1565,10 @@ void FunctionParser::ProcessRecord() { ...@@ -1555,9 +1565,10 @@ void FunctionParser::ProcessRecord() {
if (!isValidRecordSizeInRange(0, 1, "function block ret")) if (!isValidRecordSizeInRange(0, 1, "function block ret"))
return; return;
if (Values.size() == 0) { if (Values.size() == 0) {
Inst = Ice::InstRet::create(Func); CurrentNode->appendInst(Ice::InstRet::create(Func));
} else { } else {
Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0])); CurrentNode->appendInst(
Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex)));
} }
InstIsTerminating = true; InstIsTerminating = true;
break; break;
...@@ -1568,12 +1579,12 @@ void FunctionParser::ProcessRecord() { ...@@ -1568,12 +1579,12 @@ void FunctionParser::ProcessRecord() {
Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); Ice::CfgNode *Block = getBranchBasicBlock(Values[0]);
if (Block == NULL) if (Block == NULL)
return; return;
Inst = Ice::InstBr::create(Func, Block); CurrentNode->appendInst(Ice::InstBr::create(Func, Block));
} else { } else {
// BR: [bb#, bb#, opval] // BR: [bb#, bb#, opval]
if (!isValidRecordSize(3, "function block branch")) if (!isValidRecordSize(3, "function block branch"))
return; return;
Ice::Operand *Cond = getRelativeOperand(Values[2]); Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex);
if (Cond->getType() != Ice::IceType_i1) { if (Cond->getType() != Ice::IceType_i1) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
...@@ -1585,16 +1596,51 @@ void FunctionParser::ProcessRecord() { ...@@ -1585,16 +1596,51 @@ void FunctionParser::ProcessRecord() {
Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]);
if (ThenBlock == NULL || ElseBlock == NULL) if (ThenBlock == NULL || ElseBlock == NULL)
return; return;
Inst = Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock); CurrentNode->appendInst(
Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock));
} }
InstIsTerminating = true; InstIsTerminating = true;
break; break;
} }
case naclbitc::FUNC_CODE_INST_PHI: {
// PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
if (!isValidRecordSizeAtLeast(3, "function block phi"))
return;
if ((Values.size() & 0x1) == 0) {
// Not an odd number of values.
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "function block phi record size not valid: " << Values.size();
Error(StrBuf.str());
return;
}
Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[0]));
if (Ty == Ice::IceType_void) {
Error("Phi record using type void not allowed");
return;
}
Ice::Variable *Dest = getNextInstVar(Ty);
Ice::InstPhi *Phi = Ice::InstPhi::create(Func, Values.size() >> 1, Dest);
for (unsigned i = 1; i < Values.size(); i += 2) {
Ice::Operand *Op =
getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex);
if (Op->getType() != Ty) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Phi instruction expects type " << Ty << " but found: " << Op;
Error(StrBuf.str());
return;
}
Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
}
CurrentNode->appendInst(Phi);
break;
}
case naclbitc::FUNC_CODE_INST_ALLOCA: { case naclbitc::FUNC_CODE_INST_ALLOCA: {
// ALLOCA: [Size, align] // ALLOCA: [Size, align]
if (!isValidRecordSize(2, "function block alloca")) if (!isValidRecordSize(2, "function block alloca"))
return; return;
Ice::Operand *ByteCount = getRelativeOperand(Values[0]); Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
if (ByteCount->getType() != Ice::IceType_i32) { if (ByteCount->getType() != Ice::IceType_i32) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
...@@ -1604,15 +1650,16 @@ void FunctionParser::ProcessRecord() { ...@@ -1604,15 +1650,16 @@ void FunctionParser::ProcessRecord() {
} }
unsigned Alignment; unsigned Alignment;
extractAlignment("Alloca", Values[1], Alignment); extractAlignment("Alloca", Values[1], Alignment);
Ice::Variable *Dest = NextInstVar(Context->getIcePointerType()); CurrentNode->appendInst(
Inst = Ice::InstAlloca::create(Func, ByteCount, Alignment, Dest); Ice::InstAlloca::create(Func, ByteCount, Alignment,
getNextInstVar(Context->getIcePointerType())));
break; break;
} }
case naclbitc::FUNC_CODE_INST_LOAD: { case naclbitc::FUNC_CODE_INST_LOAD: {
// LOAD: [address, align, ty] // LOAD: [address, align, ty]
if (!isValidRecordSize(3, "function block load")) if (!isValidRecordSize(3, "function block load"))
return; return;
Ice::Operand *Address = getRelativeOperand(Values[0]); Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
if (!isValidPointerType(Address, "Load")) if (!isValidPointerType(Address, "Load"))
return; return;
unsigned Alignment; unsigned Alignment;
...@@ -1620,23 +1667,24 @@ void FunctionParser::ProcessRecord() { ...@@ -1620,23 +1667,24 @@ void FunctionParser::ProcessRecord() {
Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2])); Ice::Type Ty = Context->convertToIceType(Context->getTypeByID(Values[2]));
if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
return; return;
Ice::Variable *Dest = NextInstVar(Ty); CurrentNode->appendInst(
Inst = Ice::InstLoad::create(Func, Dest, Address, Alignment); Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment));
break; break;
} }
case naclbitc::FUNC_CODE_INST_STORE: { case naclbitc::FUNC_CODE_INST_STORE: {
// STORE: [address, value, align] // STORE: [address, value, align]
if (!isValidRecordSize(3, "function block store")) if (!isValidRecordSize(3, "function block store"))
return; return;
Ice::Operand *Address = getRelativeOperand(Values[0]); Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
if (!isValidPointerType(Address, "Store")) if (!isValidPointerType(Address, "Store"))
return; return;
Ice::Operand *Value = getRelativeOperand(Values[1]); Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex);
unsigned Alignment; unsigned Alignment;
extractAlignment("Store", Values[2], Alignment); extractAlignment("Store", Values[2], Alignment);
if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store"))
return; return;
Inst = Ice::InstStore::create(Func, Value, Address, Alignment); CurrentNode->appendInst(
Ice::InstStore::create(Func, Value, Address, Alignment));
break; break;
} }
default: default:
...@@ -1644,8 +1692,6 @@ void FunctionParser::ProcessRecord() { ...@@ -1644,8 +1692,6 @@ void FunctionParser::ProcessRecord() {
BlockParserBaseClass::ProcessRecord(); BlockParserBaseClass::ProcessRecord();
break; break;
} }
if (Inst)
CurrentNode->appendInst(Inst);
} }
/// Parses constants within a function block. /// Parses constants within a function block.
......
; Test reading phi instructions.
; RUN: llvm-as < %s | pnacl-freeze -allow-local-symbol-tables \
; RUN: | %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: -allow-local-symbol-tables \
; RUN: | FileCheck %s
; TODO(kschimpf) Add forward reference examples.
define internal i32 @testPhi1(i32 %arg) {
entry:
%cmp1 = icmp sgt i32 %arg, 0
br i1 %cmp1, label %next, label %target
next:
br label %target
target:
%merge = phi i1 [ %cmp1, %entry ], [ false, %next ]
%result = zext i1 %merge to i32
ret i32 %result
}
; CHECK: define internal i32 @testPhi1(i32 %arg) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %cmp1 = icmp sgt i32 %arg, 0
; CHECK-NEXT: br i1 %cmp1, label %next, label %target
; CHECK-NEXT: next:
; CHECK-NEXT: br label %target
; CHECK-NEXT: target:
; CHECK-NEXT: %merge = phi i1 [ %cmp1, %entry ], [ false, %next ]
; CHECK-NEXT: %result = zext i1 %merge to i32
; CHECK-NEXT: ret i32 %result
; CHECK-NEXT: }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment