summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/IR/DerivedTypes.h20
-rw-r--r--include/llvm/IR/Intrinsics.h6
-rw-r--r--include/llvm/IR/Intrinsics.td4
-rw-r--r--lib/IR/Function.cpp12
-rw-r--r--lib/IR/Verifier.cpp6
-rw-r--r--utils/TableGen/IntrinsicEmitter.cpp5
6 files changed, 48 insertions, 5 deletions
diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h
index 758ef71a1f..71d9973bcb 100644
--- a/include/llvm/IR/DerivedTypes.h
+++ b/include/llvm/IR/DerivedTypes.h
@@ -400,6 +400,26 @@ public:
return VectorType::get(EltTy, VTy->getNumElements());
}
+ /// VectorType::getHalfElementsVectorType - This static method returns
+ /// a VectorType with half as many elements as the input type and the
+ /// same element type.
+ ///
+ static VectorType *getHalfElementsVectorType(VectorType *VTy) {
+ unsigned NumElts = VTy->getNumElements();
+ assert ((NumElts & 1) == 0 &&
+ "Cannot halve vector with odd number of elements.");
+ return VectorType::get(VTy->getElementType(), NumElts/2);
+ }
+
+ /// VectorType::getDoubleElementsVectorType - This static method returns
+ /// a VectorType with twice as many elements as the input type and the
+ /// same element type.
+ ///
+ static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
+ unsigned NumElts = VTy->getNumElements();
+ return VectorType::get(VTy->getElementType(), NumElts*2);
+ }
+
/// isValidElementType - Return true if the specified type is valid as a
/// element type.
static bool isValidElementType(Type *ElemTy);
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index b3e58b7cc4..839bbbd8b4 100644
--- a/include/llvm/IR/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -79,7 +79,7 @@ namespace Intrinsic {
enum IITDescriptorKind {
Void, VarArg, MMX, Metadata, Half, Float, Double,
Integer, Vector, Pointer, Struct,
- Argument, ExtendArgument, TruncArgument,
+ Argument, ExtendArgument, TruncArgument, HalfVecArgument
} Kind;
union {
@@ -99,12 +99,12 @@ namespace Intrinsic {
};
unsigned getArgumentNumber() const {
assert(Kind == Argument || Kind == ExtendArgument ||
- Kind == TruncArgument);
+ Kind == TruncArgument || Kind == HalfVecArgument);
return Argument_Info >> 2;
}
ArgKind getArgumentKind() const {
assert(Kind == Argument || Kind == ExtendArgument ||
- Kind == TruncArgument);
+ Kind == TruncArgument || Kind == HalfVecArgument);
return (ArgKind)(Argument_Info&3);
}
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index 91bf99eab2..3e6c08dd23 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -113,6 +113,10 @@ class LLVMMatchType<int num>
class LLVMExtendedType<int num> : LLVMMatchType<num>;
class LLVMTruncatedType<int num> : LLVMMatchType<num>;
+// Match the type of another intrinsic parameter that is expected to be a
+// vector type, but change the element count to be half as many
+class LLVMHalfElementsVectorType<int num> : LLVMMatchType<num>;
+
def llvm_void_ty : LLVMType<isVoid>;
def llvm_anyint_ty : LLVMType<iAny>;
def llvm_anyfloat_ty : LLVMType<fAny>;
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index f690ee0776..c2ea0e1e4d 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -470,7 +470,8 @@ enum IIT_Info {
IIT_TRUNC_ARG = 24,
IIT_ANYPTR = 25,
IIT_V1 = 26,
- IIT_VARARG = 27
+ IIT_VARARG = 27,
+ IIT_HALF_VEC_ARG = 28
};
@@ -568,6 +569,12 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
ArgInfo));
return;
}
+ case IIT_HALF_VEC_ARG: {
+ unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::HalfVecArgument,
+ ArgInfo));
+ return;
+ }
case IIT_EMPTYSTRUCT:
OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
return;
@@ -672,6 +679,9 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
assert(ITy->getBitWidth() % 2 == 0);
return IntegerType::get(Context, ITy->getBitWidth() / 2);
}
+ case IITDescriptor::HalfVecArgument:
+ return VectorType::getHalfElementsVectorType(cast<VectorType>(
+ Tys[D.getArgumentNumber()]));
}
llvm_unreachable("unhandled");
}
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index aa84f230d0..089ad1ca5f 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -2206,6 +2206,12 @@ bool Verifier::VerifyIntrinsicType(Type *Ty,
return Ty != NewTy;
}
+ case IITDescriptor::HalfVecArgument:
+ // This may only be used when referring to a previous vector argument.
+ return D.getArgumentNumber() >= ArgTys.size() ||
+ !isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
+ VectorType::getHalfElementsVectorType(
+ cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
}
llvm_unreachable("unhandled");
}
diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp
index dc32dfa858..7b0a2b6c6d 100644
--- a/utils/TableGen/IntrinsicEmitter.cpp
+++ b/utils/TableGen/IntrinsicEmitter.cpp
@@ -250,7 +250,8 @@ enum IIT_Info {
IIT_TRUNC_ARG = 24,
IIT_ANYPTR = 25,
IIT_V1 = 26,
- IIT_VARARG = 27
+ IIT_VARARG = 27,
+ IIT_HALF_VEC_ARG = 28
};
@@ -296,6 +297,8 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
Sig.push_back(IIT_EXTEND_ARG);
else if (R->isSubClassOf("LLVMTruncatedType"))
Sig.push_back(IIT_TRUNC_ARG);
+ else if (R->isSubClassOf("LLVMHalfElementsVectorType"))
+ Sig.push_back(IIT_HALF_VEC_ARG);
else
Sig.push_back(IIT_ARG);
return Sig.push_back((Number << 2) | ArgCodes[Number]);