Commit 71ba8222 by Karl Schimpf

Add vector insert/extract instructions to Subzero bitcode reader.

BUG= //code.google.com/p/nativeclient/issues/detail?id=3894 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/529113002
parent 94539ce0
......@@ -909,6 +909,12 @@ private:
return LocalOperands[LocalIndex];
}
// Returns the relative operand (wrt to next instruction) referenced by
// the given value index.
Ice::Operand *getRelativeOperand(uint32_t Index) {
return getOperand(convertRelativeToAbsIndex(Index));
}
// Generates type error message for binary operator Op
// operating on Type OpTy.
void ReportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy);
......@@ -1143,8 +1149,8 @@ void FunctionParser::ProcessRecord() {
// BINOP: [opval, opval, opcode]
if (!isValidRecordSize(3, "function block binop"))
return;
Ice::Operand *Op1 = getOperand(convertRelativeToAbsIndex(Values[0]));
Ice::Operand *Op2 = getOperand(convertRelativeToAbsIndex(Values[1]));
Ice::Operand *Op1 = getRelativeOperand(Values[0]);
Ice::Operand *Op2 = getRelativeOperand(Values[1]);
Ice::Type Type1 = Op1->getType();
Ice::Type Type2 = Op2->getType();
if (Type1 != Type2) {
......@@ -1167,7 +1173,7 @@ void FunctionParser::ProcessRecord() {
// CAST: [opval, destty, castopc]
if (!isValidRecordSize(3, "function block cast"))
return;
Ice::Operand *Src = getOperand(convertRelativeToAbsIndex(Values[0]));
Ice::Operand *Src = getRelativeOperand(Values[0]);
Type *CastType = Context->getTypeByID(Values[1]);
Instruction::CastOps LLVMCastOp;
Ice::InstCast::OpKind CastKind;
......@@ -1192,6 +1198,61 @@ void FunctionParser::ProcessRecord() {
Inst = Ice::InstCast::create(Func, CastKind, Dest, Src);
break;
}
case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
// EXTRACTELT: [opval, opval]
Ice::Operand *Vec = getRelativeOperand(Values[0]);
Ice::Type VecType = Vec->getType();
if (!Ice::isVectorType(VecType)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Extractelement not on vector. Found: " << Vec;
Error(StrBuf.str());
}
Ice::Operand *Index = getRelativeOperand(Values[1]);
if (Index->getType() != Ice::IceType_i32) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Extractelement index not i32. Found: " << Index;
Error(StrBuf.str());
}
// TODO(kschimpf): Restrict index to a legal constant index (once
// constants can be defined).
Ice::Variable *Dest = NextInstVar(typeElementType(VecType));
Inst = Ice::InstExtractElement::create(Func, Dest, Vec, Index);
break;
}
case naclbitc::FUNC_CODE_INST_INSERTELT: {
// INSERTELT: [opval, opval, opval]
Ice::Operand *Vec = getRelativeOperand(Values[0]);
Ice::Type VecType = Vec->getType();
if (!Ice::isVectorType(VecType)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Insertelement not on vector. Found: " << Vec;
Error(StrBuf.str());
}
Ice::Operand *Elt = getRelativeOperand(Values[1]);
Ice::Type EltType = Elt->getType();
if (EltType != typeElementType(VecType)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Insertelement element not " << typeElementType(VecType)
<< ". Found: " << Elt;
Error(StrBuf.str());
}
Ice::Operand *Index = getRelativeOperand(Values[2]);
if (Index->getType() != Ice::IceType_i32) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Insertelement index not i32. Found: " << Index;
Error(StrBuf.str());
}
// TODO(kschimpf): Restrict index to a legal constant index (once
// constants can be defined).
Ice::Variable *Dest = NextInstVar(EltType);
Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index);
break;
}
case naclbitc::FUNC_CODE_INST_RET: {
// RET: [opval?]
InstIsTerminating = true;
......@@ -1200,8 +1261,7 @@ void FunctionParser::ProcessRecord() {
if (Values.size() == 0) {
Inst = Ice::InstRet::create(Func);
} else {
Inst = Ice::InstRet::create(
Func, getOperand(convertRelativeToAbsIndex(Values[0])));
Inst = Ice::InstRet::create(Func, getRelativeOperand(Values[0]));
}
break;
}
......
; Tests insertelement and extractelement vector instructions.
; RUN: llvm-as < %s | pnacl-freeze \
; RUN: | %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: | FileCheck %s
; TODO(kschimpf): Change index arguments to valid constant indices once
; we can handle constants.
define void @ExtractV4xi1(<4 x i1> %v, i32 %i) {
%e = extractelement <4 x i1> %v, i32 %i
ret void
}
; CHECK: define void @ExtractV4xi1(<4 x i1> %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = extractelement <4 x i1> %__0, i32 %__1
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV8xi1(<8 x i1> %v, i32 %i) {
%e = extractelement <8 x i1> %v, i32 %i
ret void
}
; CHECK-NEXT: define void @ExtractV8xi1(<8 x i1> %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = extractelement <8 x i1> %__0, i32 %__1
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV16xi1(<16 x i1> %v, i32 %i) {
%e = extractelement <16 x i1> %v, i32 %i
ret void
}
; CHECK-NEXT: define void @ExtractV16xi1(<16 x i1> %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = extractelement <16 x i1> %__0, i32 %__1
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV16xi8(<16 x i8> %v, i32 %i) {
%e = extractelement <16 x i8> %v, i32 %i
ret void
}
; CHECK-NEXT: define void @ExtractV16xi8(<16 x i8> %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = extractelement <16 x i8> %__0, i32 %__1
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV8xi16(<8 x i16> %v, i32 %i) {
%e = extractelement <8 x i16> %v, i32 %i
ret void
}
; CHECK-NEXT: define void @ExtractV8xi16(<8 x i16> %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = extractelement <8 x i16> %__0, i32 %__1
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define i32 @ExtractV4xi32(<4 x i32> %v, i32 %i) {
%e = extractelement <4 x i32> %v, i32 %i
ret i32 %e
}
; CHECK-NEXT: define i32 @ExtractV4xi32(<4 x i32> %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = extractelement <4 x i32> %__0, i32 %__1
; CHECK-NEXT: ret i32 %__2
; CHECK-NEXT: }
define float @ExtractV4xfloat(<4 x float> %v, i32 %i) {
%e = extractelement <4 x float> %v, i32 %i
ret float %e
}
; CHECK-NEXT: define float @ExtractV4xfloat(<4 x float> %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = extractelement <4 x float> %__0, i32 %__1
; CHECK-NEXT: ret float %__2
; CHECK-NEXT: }
define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %pe, i32 %i) {
%e = trunc i32 %pe to i1
%r = insertelement <4 x i1> %v, i1 %e, i32 %i
ret <4 x i1> %r
}
; CHECK-NEXT: define <4 x i1> @InsertV4xi1(<4 x i1> %__0, i32 %__1, i32 %__2) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__3 = trunc i32 %__1 to i1
; CHECK-NEXT: %__4 = insertelement <4 x i1> %__0, i1 %__3, i32 %__2
; CHECK-NEXT: ret i1 %__4
; CHECK-NEXT: }
define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %pe, i32 %i) {
%e = trunc i32 %pe to i1
%r = insertelement <8 x i1> %v, i1 %e, i32 %i
ret <8 x i1> %r
}
; CHECK-NEXT: define <8 x i1> @InsertV8xi1(<8 x i1> %__0, i32 %__1, i32 %__2) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__3 = trunc i32 %__1 to i1
; CHECK-NEXT: %__4 = insertelement <8 x i1> %__0, i1 %__3, i32 %__2
; CHECK-NEXT: ret i1 %__4
; CHECK-NEXT: }
define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %pe, i32 %i) {
%e = trunc i32 %pe to i1
%r = insertelement <16 x i1> %v, i1 %e, i32 %i
ret <16 x i1> %r
}
; CHECK-NEXT: define <16 x i1> @InsertV16xi1(<16 x i1> %__0, i32 %__1, i32 %__2) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__3 = trunc i32 %__1 to i1
; CHECK-NEXT: %__4 = insertelement <16 x i1> %__0, i1 %__3, i32 %__2
; CHECK-NEXT: ret i1 %__4
; CHECK-NEXT: }
define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %pe, i32 %i) {
%e = trunc i32 %pe to i8
%r = insertelement <16 x i8> %v, i8 %e, i32 %i
ret <16 x i8> %r
}
; CHECK-NEXT: define <16 x i8> @InsertV16xi8(<16 x i8> %__0, i32 %__1, i32 %__2) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__3 = trunc i32 %__1 to i8
; CHECK-NEXT: %__4 = insertelement <16 x i8> %__0, i8 %__3, i32 %__2
; CHECK-NEXT: ret i8 %__4
; CHECK-NEXT: }
define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %pe, i32 %i) {
%e = trunc i32 %pe to i16
%r = insertelement <8 x i16> %v, i16 %e, i32 %i
ret <8 x i16> %r
}
; CHECK-NEXT: define <8 x i16> @InsertV8xi16(<8 x i16> %__0, i32 %__1, i32 %__2) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__3 = trunc i32 %__1 to i16
; CHECK-NEXT: %__4 = insertelement <8 x i16> %__0, i16 %__3, i32 %__2
; CHECK-NEXT: ret i16 %__4
; CHECK-NEXT: }
define <4 x i32> @InsertV16xi32(<4 x i32> %v, i32 %e, i32 %i) {
%r = insertelement <4 x i32> %v, i32 %e, i32 %i
ret <4 x i32> %r
}
; CHECK-NEXT: define <4 x i32> @InsertV16xi32(<4 x i32> %__0, i32 %__1, i32 %__2) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__3 = insertelement <4 x i32> %__0, i32 %__1, i32 %__2
; CHECK-NEXT: ret i32 %__3
; CHECK-NEXT: }
define <4 x float> @InsertV16xfloat(<4 x float> %v, float %e, i32 %i) {
%r = insertelement <4 x float> %v, float %e, i32 %i
ret <4 x float> %r
}
; CHECK-NEXT: define <4 x float> @InsertV16xfloat(<4 x float> %__0, float %__1, i32 %__2) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__3 = insertelement <4 x float> %__0, float %__1, i32 %__2
; CHECK-NEXT: ret float %__3
; 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