Commit aff9fa2c by Karl Schimpf

Fix insert/extract element vector operations to check that literal

indices are used. Also introduces a "error" instruction method for inserting an instruction placeholder when an instruction is erroneous, and the type of generated value is known. BUG= R=stichnot@chromium.org Review URL: https://codereview.chromium.org/686913003
parent b262c5e0
......@@ -61,7 +61,7 @@ public:
virtual ~ExtendedType() {}
ExtendedType::TypeKind getKind() const { return Kind; }
void Dump(Ice::Ostream &Stream) const;
void dump(Ice::Ostream &Stream) const;
/// Changes the extended type to a simple type with the given
/// value.
......@@ -87,7 +87,7 @@ private:
};
Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
Ty.Dump(Stream);
Ty.dump(Stream);
return Stream;
}
......@@ -137,7 +137,7 @@ public:
}
};
void ExtendedType::Dump(Ice::Ostream &Stream) const {
void ExtendedType::dump(Ice::Ostream &Stream) const {
Stream << Kind;
switch (Kind) {
case Simple: {
......@@ -1316,6 +1316,57 @@ private:
return false;
}
// Types of errors that can occur for insertelement and extractelement
// instructions.
enum VectorIndexCheckValue {
VectorIndexNotVector,
VectorIndexNotConstant,
VectorIndexNotInRange,
VectorIndexNotI32,
VectorIndexValid
};
void dumpVectorIndexCheckValue(raw_ostream &Stream,
VectorIndexCheckValue Value) const {
switch (Value) {
default:
report_fatal_error("Unknown VectorIndexCheckValue");
break;
case VectorIndexNotVector:
Stream << "Vector index on non vector";
break;
case VectorIndexNotConstant:
Stream << "Vector index not integer constant";
break;
case VectorIndexNotInRange:
Stream << "Vector index not in range of vector";
break;
case VectorIndexNotI32:
Stream << "Vector index not of type " << Ice::IceType_i32;
break;
case VectorIndexValid:
Stream << "Valid vector index";
break;
}
}
// Returns whether the given vector index (for insertelement and
// extractelement instructions) is valid.
VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec,
const Ice::Operand *Index) const {
Ice::Type VecType = Vec->getType();
if (!Ice::isVectorType(VecType))
return VectorIndexNotVector;
const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
if (C == nullptr)
return VectorIndexNotConstant;
if (C->getValue() >= typeNumElements(VecType))
return VectorIndexNotInRange;
if (Index->getType() != Ice::IceType_i32)
return VectorIndexNotI32;
return VectorIndexValid;
}
// Reports that the given binary Opcode, for the given type Ty,
// is not understood.
void ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty);
......@@ -1548,6 +1599,22 @@ private:
return false;
}
}
// Creates an error instruction, generating a value of type Ty, and
// adds a placeholder so that instruction indices line up.
// Some instructions, such as a call, will not generate a value
// if the return type is void. In such cases, a placeholder value
// for the badly formed instruction is not needed. Hence, if Ty is
// void, an error instruction is not appended.
// TODO(kschimpf) Remove error recovery once implementation complete.
void appendErrorInstruction(Ice::Type Ty) {
// Note: we don't worry about downstream translation errors because
// the function will not be translated if any errors occur.
if (Ty == Ice::IceType_void)
return;
Ice::Variable *Var = getNextInstVar(Ty);
CurrentNode->appendInst(Ice::InstAssign::create(Func, Var, Var));
}
};
void FunctionParser::ReportInvalidBinopOpcode(unsigned Opcode, Ice::Type Ty) {
......@@ -1622,7 +1689,7 @@ void FunctionParser::ProcessRecord() {
// constructor.
for (size_t i = 1; i < NumBbs; ++i)
InstallNextBasicBlock();
break;
return;
}
case naclbitc::FUNC_CODE_INST_BINOP: {
// BINOP: [opval, opval, opcode]
......@@ -1637,8 +1704,8 @@ void FunctionParser::ProcessRecord() {
raw_string_ostream StrBuf(Buffer);
StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2;
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Op2 = Op1;
appendErrorInstruction(Type1);
return;
}
Ice::InstArithmetic::OpKind Opcode;
......@@ -1646,7 +1713,7 @@ void FunctionParser::ProcessRecord() {
return;
CurrentNode->appendInst(Ice::InstArithmetic::create(
Func, Opcode, getNextInstVar(Type1), Op1, Op2));
break;
return;
}
case naclbitc::FUNC_CODE_INST_CAST: {
// CAST: [opval, destty, castopc]
......@@ -1662,6 +1729,7 @@ void FunctionParser::ProcessRecord() {
raw_string_ostream StrBuf(Buffer);
StrBuf << "Cast opcode not understood: " << Values[2];
Error(StrBuf.str());
appendErrorInstruction(CastType);
return;
}
Ice::Type SrcType = Src->getType();
......@@ -1672,11 +1740,12 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
<< " " << SrcType << " to " << CastType;
Error(StrBuf.str());
appendErrorInstruction(CastType);
return;
}
CurrentNode->appendInst(
Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src));
break;
return;
}
case naclbitc::FUNC_CODE_INST_VSELECT: {
// VSELECT: [opval, opval, pred]
......@@ -1690,6 +1759,7 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Select operands not same type. Found " << ThenType << " and "
<< ElseType;
Error(StrBuf.str());
appendErrorInstruction(ThenType);
return;
}
Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex);
......@@ -1703,6 +1773,7 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Select condition type " << CondType
<< " not allowed for values of type " << ThenType;
Error(StrBuf.str());
appendErrorInstruction(ThenType);
return;
}
} else if (CondVal->getType() != Ice::IceType_i1) {
......@@ -1711,11 +1782,12 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Select condition " << CondVal << " not type i1. Found: "
<< CondVal->getType();
Error(StrBuf.str());
appendErrorInstruction(ThenType);
return;
}
CurrentNode->appendInst(Ice::InstSelect::create(
Func, getNextInstVar(ThenType), CondVal, ThenVal, ElseVal));
break;
return;
}
case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
// EXTRACTELT: [opval, opval]
......@@ -1723,25 +1795,21 @@ void FunctionParser::ProcessRecord() {
return;
Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
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], BaseIndex);
if (Index->getType() != Ice::IceType_i32) {
VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
if (IndexCheckValue != VectorIndexValid) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Extractelement index " << *Index << " not i32. Found: "
<< Index->getType();
dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
StrBuf << ": extractelement " << VecType << " " << *Vec << ", "
<< Index->getType() << " " << *Index;
Error(StrBuf.str());
appendErrorInstruction(VecType);
return;
}
// TODO(kschimpf): Restrict index to a legal constant index (once
// constants can be defined).
CurrentNode->appendInst(Ice::InstExtractElement::create(
Func, getNextInstVar(typeElementType(VecType)), Vec, Index));
break;
return;
}
case naclbitc::FUNC_CODE_INST_INSERTELT: {
// INSERTELT: [opval, opval, opval]
......@@ -1749,35 +1817,23 @@ void FunctionParser::ProcessRecord() {
return;
Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex);
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], BaseIndex);
Ice::Type EltType = Elt->getType();
if (EltType != typeElementType(VecType)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Insertelement element " << *Elt << " not type "
<< typeElementType(VecType)
<< ". Found: " << EltType;
Error(StrBuf.str());
}
Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex);
if (Index->getType() != Ice::IceType_i32) {
VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index);
if (IndexCheckValue != VectorIndexValid) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Insertelement index " << *Index << " not i32. Found: "
<< Index->getType();
dumpVectorIndexCheckValue(StrBuf, IndexCheckValue);
StrBuf << ": insertelement " << VecType << " " << *Vec << ", "
<< Elt->getType() << " " << *Elt << ", " << Index->getType() << " "
<< *Index;
Error(StrBuf.str());
appendErrorInstruction(Elt->getType());
return;
}
// TODO(kschimpf): Restrict index to a legal constant index (once
// constants can be defined).
CurrentNode->appendInst(Ice::InstInsertElement::create(
Func, getNextInstVar(VecType), Vec, Elt, Index));
break;
return;
}
case naclbitc::FUNC_CODE_INST_CMP2: {
// CMP2: [opval, opval, pred]
......@@ -1787,16 +1843,16 @@ void FunctionParser::ProcessRecord() {
Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex);
Ice::Type Op1Type = Op1->getType();
Ice::Type Op2Type = Op2->getType();
Ice::Type DestType = getCompareResultType(Op1Type);
if (Op1Type != Op2Type) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Compare argument types differ: " << Op1Type
<< " and " << Op2Type;
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
appendErrorInstruction(DestType);
Op2 = Op1;
}
Ice::Type DestType = getCompareResultType(Op1Type);
if (DestType == Ice::IceType_void) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
......@@ -1813,8 +1869,7 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Compare record contains unknown integer predicate index: "
<< Values[2];
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Cond = Ice::InstIcmp::Eq;
appendErrorInstruction(DestType);
}
CurrentNode->appendInst(
Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2));
......@@ -1826,8 +1881,7 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Compare record contains unknown float predicate index: "
<< Values[2];
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Cond = Ice::InstFcmp::False;
appendErrorInstruction(DestType);
}
CurrentNode->appendInst(
Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2));
......@@ -1837,9 +1891,10 @@ void FunctionParser::ProcessRecord() {
raw_string_ostream StrBuf(Buffer);
StrBuf << "Compare on type not understood: " << Op1Type;
Error(StrBuf.str());
appendErrorInstruction(DestType);
return;
}
break;
return;
}
case naclbitc::FUNC_CODE_INST_RET: {
// RET: [opval?]
......@@ -1852,7 +1907,7 @@ void FunctionParser::ProcessRecord() {
Ice::InstRet::create(Func, getRelativeOperand(Values[0], BaseIndex)));
}
InstIsTerminating = true;
break;
return;
}
case naclbitc::FUNC_CODE_INST_BR: {
if (Values.size() == 1) {
......@@ -1882,7 +1937,7 @@ void FunctionParser::ProcessRecord() {
Ice::InstBr::create(Func, Cond, ThenBlock, ElseBlock));
}
InstIsTerminating = true;
break;
return;
}
case naclbitc::FUNC_CODE_INST_SWITCH: {
// SWITCH: [Condty, Cond, BbIndex, NumCases Case ...]
......@@ -1940,7 +1995,7 @@ void FunctionParser::ProcessRecord() {
}
CurrentNode->appendInst(Switch);
InstIsTerminating = true;
break;
return;
}
case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
// UNREACHABLE: []
......@@ -1949,21 +2004,22 @@ void FunctionParser::ProcessRecord() {
CurrentNode->appendInst(
Ice::InstUnreachable::create(Func));
InstIsTerminating = true;
break;
return;
}
case naclbitc::FUNC_CODE_INST_PHI: {
// PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2.
if (!isValidRecordSizeAtLeast(3, "function block phi"))
return;
Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
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());
appendErrorInstruction(Ty);
return;
}
Ice::Type Ty = Context->getSimpleTypeByID(Values[0]);
if (Ty == Ice::IceType_void) {
Error("Phi record using type void not allowed");
return;
......@@ -1979,47 +2035,53 @@ void FunctionParser::ProcessRecord() {
StrBuf << "Value " << *Op << " not type " << Ty
<< " in phi instruction. Found: " << Op->getType();
Error(StrBuf.str());
appendErrorInstruction(Ty);
return;
}
Phi->addArgument(Op, getBasicBlock(Values[i + 1]));
}
CurrentNode->appendInst(Phi);
break;
return;
}
case naclbitc::FUNC_CODE_INST_ALLOCA: {
// ALLOCA: [Size, align]
if (!isValidRecordSize(2, "function block alloca"))
return;
Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex);
Ice::Type PtrTy = Context->getIcePointerType();
if (ByteCount->getType() != Ice::IceType_i32) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount;
Error(StrBuf.str());
appendErrorInstruction(PtrTy);
return;
}
unsigned Alignment;
extractAlignment("Alloca", Values[1], Alignment);
CurrentNode->appendInst(
Ice::InstAlloca::create(Func, ByteCount, Alignment,
getNextInstVar(Context->getIcePointerType())));
break;
CurrentNode->appendInst(Ice::InstAlloca::create(Func, ByteCount, Alignment,
getNextInstVar(PtrTy)));
return;
}
case naclbitc::FUNC_CODE_INST_LOAD: {
// LOAD: [address, align, ty]
if (!isValidRecordSize(3, "function block load"))
return;
Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex);
if (!isValidPointerType(Address, "Load"))
Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
if (!isValidPointerType(Address, "Load")) {
appendErrorInstruction(Ty);
return;
}
unsigned Alignment;
extractAlignment("Load", Values[1], Alignment);
Ice::Type Ty = Context->getSimpleTypeByID(Values[2]);
if (!isValidLoadStoreAlignment(Alignment, Ty, "Load"))
if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) {
appendErrorInstruction(Ty);
return;
}
CurrentNode->appendInst(
Ice::InstLoad::create(Func, getNextInstVar(Ty), Address, Alignment));
break;
return;
}
case naclbitc::FUNC_CODE_INST_STORE: {
// STORE: [address, value, align]
......@@ -2035,7 +2097,7 @@ void FunctionParser::ProcessRecord() {
return;
CurrentNode->appendInst(
Ice::InstStore::create(Func, Value, Address, Alignment));
break;
return;
}
case naclbitc::FUNC_CODE_INST_CALL:
case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: {
......@@ -2059,19 +2121,6 @@ void FunctionParser::ProcessRecord() {
ParamsStartIndex = 3;
}
// Extract call information.
uint64_t CCInfo = Values[0];
CallingConv::ID CallingConv;
if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Function call calling convention value " << (CCInfo >> 1)
<< " not understood.";
Error(StrBuf.str());
return;
}
bool IsTailCall = static_cast<bool>(CCInfo & 1);
// Extract out the called function and its return type.
uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex);
Ice::Operand *Callee = getOperand(CalleeIndex);
......@@ -2094,6 +2143,7 @@ void FunctionParser::ProcessRecord() {
raw_string_ostream StrBuf(Buffer);
StrBuf << "Invalid PNaCl intrinsic call to " << Name;
Error(StrBuf.str());
appendErrorInstruction(ReturnType);
return;
}
}
......@@ -2101,6 +2151,20 @@ void FunctionParser::ProcessRecord() {
ReturnType = Context->getSimpleTypeByID(Values[2]);
}
// Extract call information.
uint64_t CCInfo = Values[0];
CallingConv::ID CallingConv;
if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Function call calling convention value " << (CCInfo >> 1)
<< " not understood.";
Error(StrBuf.str());
appendErrorInstruction(ReturnType);
return;
}
bool IsTailCall = static_cast<bool>(CCInfo & 1);
// Create the call instruction.
Ice::Variable *Dest = (ReturnType == Ice::IceType_void)
? nullptr
......@@ -2171,12 +2235,12 @@ void FunctionParser::ProcessRecord() {
if (!isValidRecordSize(2, "function block forward type ref"))
return;
setOperand(Values[0], createInstVar(Context->getSimpleTypeByID(Values[1])));
break;
return;
}
default:
// Generate error message!
BlockParserBaseClass::ProcessRecord();
break;
return;
}
}
......
; Tests insertelement and extractelement vector instructions report
; errors when malformed. Note: We can only test literal indexing since
; llvm-as will not allow other bad forms of these instructions.
; RUN: llvm-as < %s | pnacl-freeze \
; RUN: | not %llvm2ice -notranslate -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery | FileCheck %s
define void @ExtractV4xi1(<4 x i1> %v, i32 %i) {
%e0 = extractelement <4 x i1> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%e1 = extractelement <4 x i1> %v, i32 4
; CHECK: Error: {{.*}} not in range
%e2 = extractelement <4 x i1> %v, i32 9
; CHECK: Error: {{.*}} not in range
ret void
}
define void @ExtractV8xi1(<8 x i1> %v, i32 %i) {
%e0 = extractelement <8 x i1> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%e1 = extractelement <8 x i1> %v, i32 8;
; CHECK: Error: {{.*}} not in range
%e2 = extractelement <8 x i1> %v, i32 9;
; CHECK: Error: {{.*}} not in range
ret void
}
define void @ExtractV16xi1(<16 x i1> %v, i32 %i) {
%e0 = extractelement <16 x i1> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%e1 = extractelement <16 x i1> %v, i32 16
; CHECK: Error: {{.*}} not in range
%e2 = extractelement <16 x i1> %v, i32 24
; CHECK: Error: {{.*}} not in range
ret void
}
define void @ExtractV16xi8(<16 x i8> %v, i32 %i) {
%e0 = extractelement <16 x i8> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%e1 = extractelement <16 x i8> %v, i32 16
; CHECK: Error: {{.*}} not in range
%e2 = extractelement <16 x i8> %v, i32 71
; CHECK: Error: {{.*}} not in range
ret void
}
define void @ExtractV8xi16(<8 x i16> %v, i32 %i) {
%e0 = extractelement <8 x i16> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%e1 = extractelement <8 x i16> %v, i32 8
; CHECK: Error: {{.*}} not in range
%e2 = extractelement <8 x i16> %v, i32 15
; CHECK: Error: {{.*}} not in range
ret void
}
define i32 @ExtractV4xi32(<4 x i32> %v, i32 %i) {
%e0 = extractelement <4 x i32> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%e1 = extractelement <4 x i32> %v, i32 4
; CHECK: Error: {{.*}} not in range
%e2 = extractelement <4 x i32> %v, i32 17
; CHECK: Error: {{.*}} not in range
ret i32 %e0
}
define float @ExtractV4xfloat(<4 x float> %v, i32 %i) {
%e0 = extractelement <4 x float> %v, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%e1 = extractelement <4 x float> %v, i32 4
; CHECK: Error: {{.*}} not in range
%e2 = extractelement <4 x float> %v, i32 4
; CHECK: Error: {{.*}} not in range
ret float %e2
}
define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %i) {
%r0 = insertelement <4 x i1> %v, i1 1, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%r1 = insertelement <4 x i1> %v, i1 1, i32 4
; CHECK: Error: {{.*}} not in range
%r2 = insertelement <4 x i1> %v, i1 1, i32 7
; CHECK: Error: {{.*}} not in range
ret <4 x i1> %r2
}
define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %i) {
%r0 = insertelement <8 x i1> %v, i1 0, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%r1 = insertelement <8 x i1> %v, i1 0, i32 8
; CHECK: Error: {{.*}} not in range
%r2 = insertelement <8 x i1> %v, i1 0, i32 88
; CHECK: Error: {{.*}} not in range
ret <8 x i1> %r2
}
define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %i) {
%r = insertelement <16 x i1> %v, i1 1, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
ret <16 x i1> %r
%r1 = insertelement <16 x i1> %v, i1 1, i32 16
; CHECK: Error: {{.*}} not in range
%r2 = insertelement <16 x i1> %v, i1 1, i32 31
; CHECK: Error: {{.*}} not in range
ret <16 x i1> %r2
}
define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %i) {
%r0 = insertelement <16 x i8> %v, i8 34, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%r1 = insertelement <16 x i8> %v, i8 34, i32 16
; CHECK: Error: {{.*}} not in range
%r2 = insertelement <16 x i8> %v, i8 34, i32 19
; CHECK: Error: {{.*}} not in range
ret <16 x i8> %r0
}
define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %i) {
%r0 = insertelement <8 x i16> %v, i16 289, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%r1 = insertelement <8 x i16> %v, i16 289, i32 8
; CHECK: Error: {{.*}} not in range
%r2 = insertelement <8 x i16> %v, i16 289, i32 19
; CHECK: Error: {{.*}} not in range
ret <8 x i16> %r1
}
define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %i) {
%r0 = insertelement <4 x i32> %v, i32 54545454, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%r1 = insertelement <4 x i32> %v, i32 54545454, i32 4
; CHECK: Error: {{.*}} not in range
%r2 = insertelement <4 x i32> %v, i32 54545454, i32 9
; CHECK: Error: {{.*}} not in range
ret <4 x i32> %r2
}
define <4 x float> @InsertV4xfloat(<4 x float> %v, i32 %i) {
%r0 = insertelement <4 x float> %v, float 3.0, i32 %i
; CHECK: Error: {{.*}} not {{.*}} constant
%r1 = insertelement <4 x float> %v, float 3.0, i32 4
; CHECK: Error: {{.*}} not in range
%r2 = insertelement <4 x float> %v, float 3.0, i32 44
; CHECK: Error: {{.*}} not in range
ret <4 x float> %r2
}
; Tests insertelement and extractelement vector instructions.
; RUN: %p2i -i %s --insts | FileCheck %s
; RUN: %l2i -i %s --insts | %ifl FileCheck %s
; RUN: %lc2i -i %s --insts | %iflc 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) {
define void @ExtractV4xi1(<4 x i1> %v) {
entry:
%e = extractelement <4 x i1> %v, i32 %i
%e0 = extractelement <4 x i1> %v, i32 0
%e1 = extractelement <4 x i1> %v, i32 1
%e2 = extractelement <4 x i1> %v, i32 2
%e3 = extractelement <4 x i1> %v, i32 3
ret void
}
; CHECK: define void @ExtractV4xi1(<4 x i1> %v, i32 %i) {
; CHECK: define void @ExtractV4xi1(<4 x i1> %v) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = extractelement <4 x i1> %v, i32 %i
; CHECK-NEXT: %e0 = extractelement <4 x i1> %v, i32 0
; CHECK-NEXT: %e1 = extractelement <4 x i1> %v, i32 1
; CHECK-NEXT: %e2 = extractelement <4 x i1> %v, i32 2
; CHECK-NEXT: %e3 = extractelement <4 x i1> %v, i32 3
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV8xi1(<8 x i1> %v, i32 %i) {
define void @ExtractV8xi1(<8 x i1> %v) {
entry:
%e = extractelement <8 x i1> %v, i32 %i
%e0 = extractelement <8 x i1> %v, i32 0
%e1 = extractelement <8 x i1> %v, i32 1
%e2 = extractelement <8 x i1> %v, i32 2
%e3 = extractelement <8 x i1> %v, i32 3
%e4 = extractelement <8 x i1> %v, i32 4
%e5 = extractelement <8 x i1> %v, i32 5
%e6 = extractelement <8 x i1> %v, i32 6
%e7 = extractelement <8 x i1> %v, i32 7
ret void
}
; CHECK-NEXT: define void @ExtractV8xi1(<8 x i1> %v, i32 %i) {
; CHECK-NEXT: define void @ExtractV8xi1(<8 x i1> %v) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = extractelement <8 x i1> %v, i32 %i
; CHECK-NEXT: %e0 = extractelement <8 x i1> %v, i32 0
; CHECK-NEXT: %e1 = extractelement <8 x i1> %v, i32 1
; CHECK-NEXT: %e2 = extractelement <8 x i1> %v, i32 2
; CHECK-NEXT: %e3 = extractelement <8 x i1> %v, i32 3
; CHECK-NEXT: %e4 = extractelement <8 x i1> %v, i32 4
; CHECK-NEXT: %e5 = extractelement <8 x i1> %v, i32 5
; CHECK-NEXT: %e6 = extractelement <8 x i1> %v, i32 6
; CHECK-NEXT: %e7 = extractelement <8 x i1> %v, i32 7
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV16xi1(<16 x i1> %v, i32 %i) {
define void @ExtractV16xi1(<16 x i1> %v) {
entry:
%e = extractelement <16 x i1> %v, i32 %i
%e0 = extractelement <16 x i1> %v, i32 0
%e1 = extractelement <16 x i1> %v, i32 1
%e2 = extractelement <16 x i1> %v, i32 2
%e3 = extractelement <16 x i1> %v, i32 3
%e4 = extractelement <16 x i1> %v, i32 4
%e5 = extractelement <16 x i1> %v, i32 5
%e6 = extractelement <16 x i1> %v, i32 6
%e7 = extractelement <16 x i1> %v, i32 7
%e8 = extractelement <16 x i1> %v, i32 8
%e9 = extractelement <16 x i1> %v, i32 9
%e10 = extractelement <16 x i1> %v, i32 10
%e11 = extractelement <16 x i1> %v, i32 11
%e12 = extractelement <16 x i1> %v, i32 12
%e13 = extractelement <16 x i1> %v, i32 13
%e14 = extractelement <16 x i1> %v, i32 14
%e15 = extractelement <16 x i1> %v, i32 15
ret void
}
; CHECK-NEXT: define void @ExtractV16xi1(<16 x i1> %v, i32 %i) {
; CHECK-NEXT: define void @ExtractV16xi1(<16 x i1> %v) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = extractelement <16 x i1> %v, i32 %i
; CHECK-NEXT: %e0 = extractelement <16 x i1> %v, i32 0
; CHECK-NEXT: %e1 = extractelement <16 x i1> %v, i32 1
; CHECK-NEXT: %e2 = extractelement <16 x i1> %v, i32 2
; CHECK-NEXT: %e3 = extractelement <16 x i1> %v, i32 3
; CHECK-NEXT: %e4 = extractelement <16 x i1> %v, i32 4
; CHECK-NEXT: %e5 = extractelement <16 x i1> %v, i32 5
; CHECK-NEXT: %e6 = extractelement <16 x i1> %v, i32 6
; CHECK-NEXT: %e7 = extractelement <16 x i1> %v, i32 7
; CHECK-NEXT: %e8 = extractelement <16 x i1> %v, i32 8
; CHECK-NEXT: %e9 = extractelement <16 x i1> %v, i32 9
; CHECK-NEXT: %e10 = extractelement <16 x i1> %v, i32 10
; CHECK-NEXT: %e11 = extractelement <16 x i1> %v, i32 11
; CHECK-NEXT: %e12 = extractelement <16 x i1> %v, i32 12
; CHECK-NEXT: %e13 = extractelement <16 x i1> %v, i32 13
; CHECK-NEXT: %e14 = extractelement <16 x i1> %v, i32 14
; CHECK-NEXT: %e15 = extractelement <16 x i1> %v, i32 15
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV16xi8(<16 x i8> %v, i32 %i) {
entry:
%e = extractelement <16 x i8> %v, i32 %i
%e0 = extractelement <16 x i8> %v, i32 0
%e1 = extractelement <16 x i8> %v, i32 1
%e2 = extractelement <16 x i8> %v, i32 2
%e3 = extractelement <16 x i8> %v, i32 3
%e4 = extractelement <16 x i8> %v, i32 4
%e5 = extractelement <16 x i8> %v, i32 5
%e6 = extractelement <16 x i8> %v, i32 6
%e7 = extractelement <16 x i8> %v, i32 7
%e8 = extractelement <16 x i8> %v, i32 8
%e9 = extractelement <16 x i8> %v, i32 9
%e10 = extractelement <16 x i8> %v, i32 10
%e11 = extractelement <16 x i8> %v, i32 11
%e12 = extractelement <16 x i8> %v, i32 12
%e13 = extractelement <16 x i8> %v, i32 13
%e14 = extractelement <16 x i8> %v, i32 14
%e15 = extractelement <16 x i8> %v, i32 15
ret void
}
; CHECK-NEXT: define void @ExtractV16xi8(<16 x i8> %v, i32 %i) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = extractelement <16 x i8> %v, i32 %i
; CHECK-NEXT: %e0 = extractelement <16 x i8> %v, i32 0
; CHECK-NEXT: %e1 = extractelement <16 x i8> %v, i32 1
; CHECK-NEXT: %e2 = extractelement <16 x i8> %v, i32 2
; CHECK-NEXT: %e3 = extractelement <16 x i8> %v, i32 3
; CHECK-NEXT: %e4 = extractelement <16 x i8> %v, i32 4
; CHECK-NEXT: %e5 = extractelement <16 x i8> %v, i32 5
; CHECK-NEXT: %e6 = extractelement <16 x i8> %v, i32 6
; CHECK-NEXT: %e7 = extractelement <16 x i8> %v, i32 7
; CHECK-NEXT: %e8 = extractelement <16 x i8> %v, i32 8
; CHECK-NEXT: %e9 = extractelement <16 x i8> %v, i32 9
; CHECK-NEXT: %e10 = extractelement <16 x i8> %v, i32 10
; CHECK-NEXT: %e11 = extractelement <16 x i8> %v, i32 11
; CHECK-NEXT: %e12 = extractelement <16 x i8> %v, i32 12
; CHECK-NEXT: %e13 = extractelement <16 x i8> %v, i32 13
; CHECK-NEXT: %e14 = extractelement <16 x i8> %v, i32 14
; CHECK-NEXT: %e15 = extractelement <16 x i8> %v, i32 15
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define void @ExtractV8xi16(<8 x i16> %v, i32 %i) {
define void @ExtractV8xi16(<8 x i16> %v) {
entry:
%e = extractelement <8 x i16> %v, i32 %i
%e0 = extractelement <8 x i16> %v, i32 0
%e1 = extractelement <8 x i16> %v, i32 1
%e2 = extractelement <8 x i16> %v, i32 2
%e3 = extractelement <8 x i16> %v, i32 3
%e4 = extractelement <8 x i16> %v, i32 4
%e5 = extractelement <8 x i16> %v, i32 5
%e6 = extractelement <8 x i16> %v, i32 6
%e7 = extractelement <8 x i16> %v, i32 7
ret void
}
; CHECK-NEXT: define void @ExtractV8xi16(<8 x i16> %v, i32 %i) {
; CHECK-NEXT: define void @ExtractV8xi16(<8 x i16> %v) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = extractelement <8 x i16> %v, i32 %i
; CHECK-NEXT: %e0 = extractelement <8 x i16> %v, i32 0
; CHECK-NEXT: %e1 = extractelement <8 x i16> %v, i32 1
; CHECK-NEXT: %e2 = extractelement <8 x i16> %v, i32 2
; CHECK-NEXT: %e3 = extractelement <8 x i16> %v, i32 3
; CHECK-NEXT: %e4 = extractelement <8 x i16> %v, i32 4
; CHECK-NEXT: %e5 = extractelement <8 x i16> %v, i32 5
; CHECK-NEXT: %e6 = extractelement <8 x i16> %v, i32 6
; CHECK-NEXT: %e7 = extractelement <8 x i16> %v, i32 7
; CHECK-NEXT: ret void
; CHECK-NEXT: }
define i32 @ExtractV4xi32(<4 x i32> %v, i32 %i) {
define i32 @ExtractV4xi32(<4 x i32> %v) {
entry:
%e = extractelement <4 x i32> %v, i32 %i
ret i32 %e
%e0 = extractelement <4 x i32> %v, i32 0
%e1 = extractelement <4 x i32> %v, i32 1
%e2 = extractelement <4 x i32> %v, i32 2
%e3 = extractelement <4 x i32> %v, i32 3
ret i32 %e0
}
; CHECK-NEXT: define i32 @ExtractV4xi32(<4 x i32> %v, i32 %i) {
; CHECK-NEXT: define i32 @ExtractV4xi32(<4 x i32> %v) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = extractelement <4 x i32> %v, i32 %i
; CHECK-NEXT: ret i32 %e
; CHECK-NEXT: %e0 = extractelement <4 x i32> %v, i32 0
; CHECK-NEXT: %e1 = extractelement <4 x i32> %v, i32 1
; CHECK-NEXT: %e2 = extractelement <4 x i32> %v, i32 2
; CHECK-NEXT: %e3 = extractelement <4 x i32> %v, i32 3
; CHECK-NEXT: ret i32 %e0
; CHECK-NEXT: }
define float @ExtractV4xfloat(<4 x float> %v, i32 %i) {
define float @ExtractV4xfloat(<4 x float> %v) {
entry:
%e = extractelement <4 x float> %v, i32 %i
ret float %e
%e0 = extractelement <4 x float> %v, i32 0
%e1 = extractelement <4 x float> %v, i32 1
%e2 = extractelement <4 x float> %v, i32 2
%e3 = extractelement <4 x float> %v, i32 3
ret float %e0
}
; CHECK-NEXT: define float @ExtractV4xfloat(<4 x float> %v, i32 %i) {
; CHECK-NEXT: define float @ExtractV4xfloat(<4 x float> %v) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = extractelement <4 x float> %v, i32 %i
; CHECK-NEXT: ret float %e
; CHECK-NEXT: %e0 = extractelement <4 x float> %v, i32 0
; CHECK-NEXT: %e1 = extractelement <4 x float> %v, i32 1
; CHECK-NEXT: %e2 = extractelement <4 x float> %v, i32 2
; CHECK-NEXT: %e3 = extractelement <4 x float> %v, i32 3
; CHECK-NEXT: ret float %e0
; CHECK-NEXT: }
define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %pe, i32 %i) {
define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %pe) {
entry:
%e = trunc i32 %pe to i1
%r = insertelement <4 x i1> %v, i1 %e, i32 %i
ret <4 x i1> %r
%r0 = insertelement <4 x i1> %v, i1 %e, i32 0
%r1 = insertelement <4 x i1> %v, i1 %e, i32 1
%r2 = insertelement <4 x i1> %v, i1 %e, i32 2
%r3 = insertelement <4 x i1> %v, i1 %e, i32 3
ret <4 x i1> %r3
}
; CHECK-NEXT: define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %pe, i32 %i) {
; CHECK-NEXT: define <4 x i1> @InsertV4xi1(<4 x i1> %v, i32 %pe) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = trunc i32 %pe to i1
; CHECK-NEXT: %r = insertelement <4 x i1> %v, i1 %e, i32 %i
; CHECK-NEXT: ret <4 x i1> %r
; CHECK-NEXT: %r0 = insertelement <4 x i1> %v, i1 %e, i32 0
; CHECK-NEXT: %r1 = insertelement <4 x i1> %v, i1 %e, i32 1
; CHECK-NEXT: %r2 = insertelement <4 x i1> %v, i1 %e, i32 2
; CHECK-NEXT: %r3 = insertelement <4 x i1> %v, i1 %e, i32 3
; CHECK-NEXT: ret <4 x i1> %r3
; CHECK-NEXT: }
define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %pe, i32 %i) {
define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %pe) {
entry:
%e = trunc i32 %pe to i1
%r = insertelement <8 x i1> %v, i1 %e, i32 %i
ret <8 x i1> %r
%r0 = insertelement <8 x i1> %v, i1 %e, i32 0
%r1 = insertelement <8 x i1> %v, i1 %e, i32 1
%r2 = insertelement <8 x i1> %v, i1 %e, i32 2
%r3 = insertelement <8 x i1> %v, i1 %e, i32 3
%r4 = insertelement <8 x i1> %v, i1 %e, i32 4
%r5 = insertelement <8 x i1> %v, i1 %e, i32 5
%r6 = insertelement <8 x i1> %v, i1 %e, i32 6
%r7 = insertelement <8 x i1> %v, i1 %e, i32 7
ret <8 x i1> %r7
}
; CHECK-NEXT: define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %pe, i32 %i) {
; CHECK-NEXT: define <8 x i1> @InsertV8xi1(<8 x i1> %v, i32 %pe) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = trunc i32 %pe to i1
; CHECK-NEXT: %r = insertelement <8 x i1> %v, i1 %e, i32 %i
; CHECK-NEXT: ret <8 x i1> %r
; CHECK-NEXT: %r0 = insertelement <8 x i1> %v, i1 %e, i32 0
; CHECK-NEXT: %r1 = insertelement <8 x i1> %v, i1 %e, i32 1
; CHECK-NEXT: %r2 = insertelement <8 x i1> %v, i1 %e, i32 2
; CHECK-NEXT: %r3 = insertelement <8 x i1> %v, i1 %e, i32 3
; CHECK-NEXT: %r4 = insertelement <8 x i1> %v, i1 %e, i32 4
; CHECK-NEXT: %r5 = insertelement <8 x i1> %v, i1 %e, i32 5
; CHECK-NEXT: %r6 = insertelement <8 x i1> %v, i1 %e, i32 6
; CHECK-NEXT: %r7 = insertelement <8 x i1> %v, i1 %e, i32 7
; CHECK-NEXT: ret <8 x i1> %r7
; CHECK-NEXT: }
define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %pe, i32 %i) {
define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %pe) {
entry:
%e = trunc i32 %pe to i1
%r = insertelement <16 x i1> %v, i1 %e, i32 %i
ret <16 x i1> %r
%r0 = insertelement <16 x i1> %v, i1 %e, i32 0
%r1 = insertelement <16 x i1> %v, i1 %e, i32 1
%r2 = insertelement <16 x i1> %v, i1 %e, i32 2
%r3 = insertelement <16 x i1> %v, i1 %e, i32 3
%r4 = insertelement <16 x i1> %v, i1 %e, i32 4
%r5 = insertelement <16 x i1> %v, i1 %e, i32 5
%r6 = insertelement <16 x i1> %v, i1 %e, i32 6
%r7 = insertelement <16 x i1> %v, i1 %e, i32 7
%r8 = insertelement <16 x i1> %v, i1 %e, i32 8
%r9 = insertelement <16 x i1> %v, i1 %e, i32 9
%r10 = insertelement <16 x i1> %v, i1 %e, i32 10
%r11 = insertelement <16 x i1> %v, i1 %e, i32 11
%r12 = insertelement <16 x i1> %v, i1 %e, i32 12
%r13 = insertelement <16 x i1> %v, i1 %e, i32 13
%r14 = insertelement <16 x i1> %v, i1 %e, i32 14
%r15 = insertelement <16 x i1> %v, i1 %e, i32 15
ret <16 x i1> %r15
}
; CHECK-NEXT: define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %pe, i32 %i) {
; CHECK-NEXT: define <16 x i1> @InsertV16xi1(<16 x i1> %v, i32 %pe) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = trunc i32 %pe to i1
; CHECK-NEXT: %r = insertelement <16 x i1> %v, i1 %e, i32 %i
; CHECK-NEXT: ret <16 x i1> %r
; CHECK-NEXT: %r0 = insertelement <16 x i1> %v, i1 %e, i32 0
; CHECK-NEXT: %r1 = insertelement <16 x i1> %v, i1 %e, i32 1
; CHECK-NEXT: %r2 = insertelement <16 x i1> %v, i1 %e, i32 2
; CHECK-NEXT: %r3 = insertelement <16 x i1> %v, i1 %e, i32 3
; CHECK-NEXT: %r4 = insertelement <16 x i1> %v, i1 %e, i32 4
; CHECK-NEXT: %r5 = insertelement <16 x i1> %v, i1 %e, i32 5
; CHECK-NEXT: %r6 = insertelement <16 x i1> %v, i1 %e, i32 6
; CHECK-NEXT: %r7 = insertelement <16 x i1> %v, i1 %e, i32 7
; CHECK-NEXT: %r8 = insertelement <16 x i1> %v, i1 %e, i32 8
; CHECK-NEXT: %r9 = insertelement <16 x i1> %v, i1 %e, i32 9
; CHECK-NEXT: %r10 = insertelement <16 x i1> %v, i1 %e, i32 10
; CHECK-NEXT: %r11 = insertelement <16 x i1> %v, i1 %e, i32 11
; CHECK-NEXT: %r12 = insertelement <16 x i1> %v, i1 %e, i32 12
; CHECK-NEXT: %r13 = insertelement <16 x i1> %v, i1 %e, i32 13
; CHECK-NEXT: %r14 = insertelement <16 x i1> %v, i1 %e, i32 14
; CHECK-NEXT: %r15 = insertelement <16 x i1> %v, i1 %e, i32 15
; CHECK-NEXT: ret <16 x i1> %r15
; CHECK-NEXT: }
define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %pe, i32 %i) {
define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %pe) {
entry:
%e = trunc i32 %pe to i8
%r = insertelement <16 x i8> %v, i8 %e, i32 %i
ret <16 x i8> %r
%r0 = insertelement <16 x i8> %v, i8 %e, i32 0
%r1 = insertelement <16 x i8> %v, i8 %e, i32 1
%r2 = insertelement <16 x i8> %v, i8 %e, i32 2
%r3 = insertelement <16 x i8> %v, i8 %e, i32 3
%r4 = insertelement <16 x i8> %v, i8 %e, i32 4
%r5 = insertelement <16 x i8> %v, i8 %e, i32 5
%r6 = insertelement <16 x i8> %v, i8 %e, i32 6
%r7 = insertelement <16 x i8> %v, i8 %e, i32 7
ret <16 x i8> %r7
}
; CHECK-NEXT: define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %pe, i32 %i) {
; CHECK-NEXT: define <16 x i8> @InsertV16xi8(<16 x i8> %v, i32 %pe) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = trunc i32 %pe to i8
; CHECK-NEXT: %r = insertelement <16 x i8> %v, i8 %e, i32 %i
; CHECK-NEXT: ret <16 x i8> %r
; CHECK-NEXT: %r0 = insertelement <16 x i8> %v, i8 %e, i32 0
; CHECK-NEXT: %r1 = insertelement <16 x i8> %v, i8 %e, i32 1
; CHECK-NEXT: %r2 = insertelement <16 x i8> %v, i8 %e, i32 2
; CHECK-NEXT: %r3 = insertelement <16 x i8> %v, i8 %e, i32 3
; CHECK-NEXT: %r4 = insertelement <16 x i8> %v, i8 %e, i32 4
; CHECK-NEXT: %r5 = insertelement <16 x i8> %v, i8 %e, i32 5
; CHECK-NEXT: %r6 = insertelement <16 x i8> %v, i8 %e, i32 6
; CHECK-NEXT: %r7 = insertelement <16 x i8> %v, i8 %e, i32 7
; CHECK-NEXT: ret <16 x i8> %r7
; CHECK-NEXT: }
define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %pe, i32 %i) {
define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %pe) {
entry:
%e = trunc i32 %pe to i16
%r = insertelement <8 x i16> %v, i16 %e, i32 %i
ret <8 x i16> %r
%r0 = insertelement <8 x i16> %v, i16 %e, i32 0
%r1 = insertelement <8 x i16> %v, i16 %e, i32 1
%r2 = insertelement <8 x i16> %v, i16 %e, i32 2
%r3 = insertelement <8 x i16> %v, i16 %e, i32 3
%r4 = insertelement <8 x i16> %v, i16 %e, i32 4
%r5 = insertelement <8 x i16> %v, i16 %e, i32 5
%r6 = insertelement <8 x i16> %v, i16 %e, i32 6
%r7 = insertelement <8 x i16> %v, i16 %e, i32 7
ret <8 x i16> %r7
}
; CHECK-NEXT: define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %pe, i32 %i) {
; CHECK-NEXT: define <8 x i16> @InsertV8xi16(<8 x i16> %v, i32 %pe) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %e = trunc i32 %pe to i16
; CHECK-NEXT: %r = insertelement <8 x i16> %v, i16 %e, i32 %i
; CHECK-NEXT: ret <8 x i16> %r
; CHECK-NEXT: %r0 = insertelement <8 x i16> %v, i16 %e, i32 0
; CHECK-NEXT: %r1 = insertelement <8 x i16> %v, i16 %e, i32 1
; CHECK-NEXT: %r2 = insertelement <8 x i16> %v, i16 %e, i32 2
; CHECK-NEXT: %r3 = insertelement <8 x i16> %v, i16 %e, i32 3
; CHECK-NEXT: %r4 = insertelement <8 x i16> %v, i16 %e, i32 4
; CHECK-NEXT: %r5 = insertelement <8 x i16> %v, i16 %e, i32 5
; CHECK-NEXT: %r6 = insertelement <8 x i16> %v, i16 %e, i32 6
; CHECK-NEXT: %r7 = insertelement <8 x i16> %v, i16 %e, i32 7
; CHECK-NEXT: ret <8 x i16> %r7
; CHECK-NEXT: }
define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %e, i32 %i) {
define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %e) {
entry:
%r = insertelement <4 x i32> %v, i32 %e, i32 %i
ret <4 x i32> %r
%r0 = insertelement <4 x i32> %v, i32 %e, i32 0
%r1 = insertelement <4 x i32> %v, i32 %e, i32 1
%r2 = insertelement <4 x i32> %v, i32 %e, i32 2
%r3 = insertelement <4 x i32> %v, i32 %e, i32 3
ret <4 x i32> %r3
}
; CHECK-NEXT: define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %e, i32 %i) {
; CHECK-NEXT: define <4 x i32> @InsertV4xi32(<4 x i32> %v, i32 %e) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %r = insertelement <4 x i32> %v, i32 %e, i32 %i
; CHECK-NEXT: ret <4 x i32> %r
; CHECK-NEXT: %r0 = insertelement <4 x i32> %v, i32 %e, i32 0
; CHECK-NEXT: %r1 = insertelement <4 x i32> %v, i32 %e, i32 1
; CHECK-NEXT: %r2 = insertelement <4 x i32> %v, i32 %e, i32 2
; CHECK-NEXT: %r3 = insertelement <4 x i32> %v, i32 %e, i32 3
; CHECK-NEXT: ret <4 x i32> %r3
; CHECK-NEXT: }
define <4 x float> @InsertV4xfloat(<4 x float> %v, float %e, i32 %i) {
define <4 x float> @InsertV4xfloat(<4 x float> %v, float %e) {
entry:
%r = insertelement <4 x float> %v, float %e, i32 %i
ret <4 x float> %r
%r0 = insertelement <4 x float> %v, float %e, i32 0
%r1 = insertelement <4 x float> %v, float %e, i32 1
%r2 = insertelement <4 x float> %v, float %e, i32 2
%r3 = insertelement <4 x float> %v, float %e, i32 3
ret <4 x float> %r3
}
; CHECK-NEXT: define <4 x float> @InsertV4xfloat(<4 x float> %v, float %e, i32 %i) {
; CHECK-NEXT: define <4 x float> @InsertV4xfloat(<4 x float> %v, float %e) {
; CHECK-NEXT: entry:
; CHECK-NEXT: %r = insertelement <4 x float> %v, float %e, i32 %i
; CHECK-NEXT: ret <4 x float> %r
; CHECK-NEXT: %r0 = insertelement <4 x float> %v, float %e, i32 0
; CHECK-NEXT: %r1 = insertelement <4 x float> %v, float %e, i32 1
; CHECK-NEXT: %r2 = insertelement <4 x float> %v, float %e, i32 2
; CHECK-NEXT: %r3 = insertelement <4 x float> %v, float %e, i32 3
; CHECK-NEXT: ret <4 x float> %r3
; 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