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
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index 46bbdb8..2bd47b8 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -61,7 +61,7 @@
   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 @@
 };
 
 Ice::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) {
-  Ty.Dump(Stream);
+  Ty.dump(Stream);
   return Stream;
 }
 
@@ -137,7 +137,7 @@
   }
 };
 
-void ExtendedType::Dump(Ice::Ostream &Stream) const {
+void ExtendedType::dump(Ice::Ostream &Stream) const {
   Stream << Kind;
   switch (Kind) {
   case Simple: {
@@ -1316,6 +1316,57 @@
     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 @@
       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 @@
     // 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 @@
       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 @@
       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 @@
       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 @@
       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 @@
       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 @@
         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 @@
       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 @@
       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 @@
       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 @@
     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 @@
         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 @@
         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 @@
       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 @@
           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 @@
           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 @@
     }
     CurrentNode->appendInst(Switch);
     InstIsTerminating = true;
-    break;
+    return;
   }
   case naclbitc::FUNC_CODE_INST_UNREACHABLE: {
     // UNREACHABLE: []
@@ -1949,21 +2004,22 @@
     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 @@
         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 @@
       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 @@
       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 @@
           raw_string_ostream StrBuf(Buffer);
           StrBuf << "Invalid PNaCl intrinsic call to " << Name;
           Error(StrBuf.str());
+          appendErrorInstruction(ReturnType);
           return;
         }
       }
@@ -2101,6 +2151,20 @@
       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 @@
     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;
   }
 }
 
diff --git a/tests_lit/reader_tests/insertextract-err.ll b/tests_lit/reader_tests/insertextract-err.ll
new file mode 100644
index 0000000..5e183bf
--- /dev/null
+++ b/tests_lit/reader_tests/insertextract-err.ll
@@ -0,0 +1,148 @@
+; 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
+}
diff --git a/tests_lit/reader_tests/insertextract.ll b/tests_lit/reader_tests/insertextract.ll
index bc34011..7116109 100644
--- a/tests_lit/reader_tests/insertextract.ll
+++ b/tests_lit/reader_tests/insertextract.ll
@@ -1,184 +1,379 @@
 ; 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: }