]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
Intrinsics: expand semantics of LLVMExtendedVectorType (& trunc)
authorTim Northover <tnorthover@apple.com>
Fri, 28 Mar 2014 12:31:39 +0000 (12:31 +0000)
committerTim Northover <tnorthover@apple.com>
Fri, 28 Mar 2014 12:31:39 +0000 (12:31 +0000)
These are used in the ARM backends to aid type-checking on patterns involving
intrinsics. By making sure one argument is an extended/truncated version of
another.

However, there's no reason to limit them to just vectors types. For example
AArch64 has the instruction "uqshrn sD, dN, #imm" which would naturally use an
intrinsic taking an i64 and returning an i32.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205003 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/Intrinsics.h
include/llvm/IR/Intrinsics.td
include/llvm/IR/IntrinsicsAArch64.td
include/llvm/IR/IntrinsicsARM.td
lib/IR/Function.cpp
lib/IR/Verifier.cpp
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/IntrinsicEmitter.cpp

index 473e525d9b94253531797dc69133c288cfc3a226..b3e58b7cc40766f18603601319b6dcb793ca76e6 100644 (file)
@@ -79,7 +79,7 @@ namespace Intrinsic {
     enum IITDescriptorKind {
       Void, VarArg, MMX, Metadata, Half, Float, Double,
       Integer, Vector, Pointer, Struct,
-      Argument, ExtendVecArgument, TruncVecArgument
+      Argument, ExtendArgument, TruncArgument,
     } Kind;
     
     union {
@@ -98,13 +98,13 @@ namespace Intrinsic {
       AK_AnyPointer
     };
     unsigned getArgumentNumber() const {
-      assert(Kind == Argument || Kind == ExtendVecArgument || 
-             Kind == TruncVecArgument);
+      assert(Kind == Argument || Kind == ExtendArgument ||
+             Kind == TruncArgument);
       return Argument_Info >> 2;
     }
     ArgKind getArgumentKind() const {
-      assert(Kind == Argument || Kind == ExtendVecArgument || 
-             Kind == TruncVecArgument);
+      assert(Kind == Argument || Kind == ExtendArgument ||
+             Kind == TruncArgument);
       return (ArgKind)(Argument_Info&3);
     }
     
index 0c9cc3be3d79cd9316bcc2068e4f97c7018c75bc..91bf99eab2e863e3c611597c970a4ed2aed76814 100644 (file)
@@ -106,12 +106,12 @@ class LLVMMatchType<int num>
   int Number = num;
 }
 
-// Match the type of another intrinsic parameter that is expected to be
-// an integral vector type, but change the element size to be twice as wide
-// or half as wide as the other type.  This is only useful when the intrinsic
-// is overloaded, so the matched type should be declared as iAny.
-class LLVMExtendedElementVectorType<int num> : LLVMMatchType<num>;
-class LLVMTruncatedElementVectorType<int num> : LLVMMatchType<num>;
+// Match the type of another intrinsic parameter that is expected to be based on
+// an integral type (i.e. either iN or <N x iM>), but change the scalar size to
+// be twice as wide or half as wide as the other type.  This is only useful when
+// the intrinsic is overloaded, so the matched type should be declared as iAny.
+class LLVMExtendedType<int num> : LLVMMatchType<num>;
+class LLVMTruncatedType<int num> : LLVMMatchType<num>;
 
 def llvm_void_ty       : LLVMType<isVoid>;
 def llvm_anyint_ty     : LLVMType<iAny>;
index c052963bf983e69fbfc0e671fc6776073a9661c8..61c0e5d419f4b13810b4dbecc370bb9a591c37d4 100644 (file)
@@ -68,7 +68,7 @@ class Neon_N3V_Intrinsic
               [IntrNoMem]>;
 class Neon_N2V_Narrow_Intrinsic
   : Intrinsic<[llvm_anyvector_ty],
-              [LLVMExtendedElementVectorType<0>, llvm_i32_ty],
+              [LLVMExtendedType<0>, llvm_i32_ty],
               [IntrNoMem]>;
 
 // Vector rounding shift right by immediate (Signed)
index f70dbabd171f5e95ed464f29a54d85e2ecf69aad..482f98ef8953a6ccf76af554bb624ecd5ef22209 100644 (file)
@@ -131,20 +131,15 @@ def int_arm_sevl : Intrinsic<[], []>;
 class Neon_1Arg_Intrinsic
   : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
 class Neon_1Arg_Narrow_Intrinsic
-  : Intrinsic<[llvm_anyvector_ty],
-              [LLVMExtendedElementVectorType<0>], [IntrNoMem]>;
+  : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<0>], [IntrNoMem]>;
 class Neon_2Arg_Intrinsic
   : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
               [IntrNoMem]>;
 class Neon_2Arg_Narrow_Intrinsic
-  : Intrinsic<[llvm_anyvector_ty],
-              [LLVMExtendedElementVectorType<0>,
-               LLVMExtendedElementVectorType<0>],
+  : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<0>, LLVMExtendedType<0>],
               [IntrNoMem]>;
 class Neon_2Arg_Long_Intrinsic
-  : Intrinsic<[llvm_anyvector_ty],
-              [LLVMTruncatedElementVectorType<0>,
-               LLVMTruncatedElementVectorType<0>],
+  : Intrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>, LLVMTruncatedType<0>],
               [IntrNoMem]>;
 class Neon_3Arg_Intrinsic
   : Intrinsic<[llvm_anyvector_ty],
@@ -152,9 +147,7 @@ class Neon_3Arg_Intrinsic
               [IntrNoMem]>;
 class Neon_3Arg_Long_Intrinsic
   : Intrinsic<[llvm_anyvector_ty],
-              [LLVMMatchType<0>,
-               LLVMTruncatedElementVectorType<0>,
-               LLVMTruncatedElementVectorType<0>],
+              [LLVMMatchType<0>, LLVMTruncatedType<0>, LLVMTruncatedType<0>],
               [IntrNoMem]>;
 class Neon_CvtFxToFP_Intrinsic
   : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
index 865970c4690f9bab57c9603279dbcefe44db84ed..f690ee077695c54e192332c3cae4eee08ea59d58 100644 (file)
@@ -466,8 +466,8 @@ enum IIT_Info {
   IIT_STRUCT3 = 20,
   IIT_STRUCT4 = 21,
   IIT_STRUCT5 = 22,
-  IIT_EXTEND_VEC_ARG = 23,
-  IIT_TRUNC_VEC_ARG = 24,
+  IIT_EXTEND_ARG = 23,
+  IIT_TRUNC_ARG = 24,
   IIT_ANYPTR = 25,
   IIT_V1   = 26,
   IIT_VARARG = 27
@@ -556,15 +556,15 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
     OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
     return;
   }
-  case IIT_EXTEND_VEC_ARG: {
+  case IIT_EXTEND_ARG: {
     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
-    OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendVecArgument,
+    OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendArgument,
                                              ArgInfo));
     return;
   }
-  case IIT_TRUNC_VEC_ARG: {
+  case IIT_TRUNC_ARG: {
     unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
-    OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncVecArgument,
+    OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncArgument,
                                              ArgInfo));
     return;
   }
@@ -656,13 +656,22 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
 
   case IITDescriptor::Argument:
     return Tys[D.getArgumentNumber()];
-  case IITDescriptor::ExtendVecArgument:
-    return VectorType::getExtendedElementVectorType(cast<VectorType>(
-                                                  Tys[D.getArgumentNumber()]));
+  case IITDescriptor::ExtendArgument: {
+    Type *Ty = Tys[D.getArgumentNumber()];
+    if (VectorType *VTy = dyn_cast<VectorType>(Ty))
+      return VectorType::getExtendedElementVectorType(VTy);
 
-  case IITDescriptor::TruncVecArgument:
-    return VectorType::getTruncatedElementVectorType(cast<VectorType>(
-                                                  Tys[D.getArgumentNumber()]));
+    return IntegerType::get(Context, 2 * cast<IntegerType>(Ty)->getBitWidth());
+  }
+  case IITDescriptor::TruncArgument: {
+    Type *Ty = Tys[D.getArgumentNumber()];
+    if (VectorType *VTy = dyn_cast<VectorType>(Ty))
+      return VectorType::getTruncatedElementVectorType(VTy);
+
+    IntegerType *ITy = cast<IntegerType>(Ty);
+    assert(ITy->getBitWidth() % 2 == 0);
+    return IntegerType::get(Context, ITy->getBitWidth() / 2);
+  }
   }
   llvm_unreachable("unhandled");
 }
index f5c8ac623b135ecfe590158f6aa6e58cc0cfb8a7..aa84f230d015fc903d100dcbf07f1a8f58574039 100644 (file)
@@ -2176,19 +2176,36 @@ bool Verifier::VerifyIntrinsicType(Type *Ty,
     }
     llvm_unreachable("all argument kinds not covered");
 
-  case IITDescriptor::ExtendVecArgument:
+  case IITDescriptor::ExtendArgument: {
     // This may only be used when referring to a previous vector argument.
-    return D.getArgumentNumber() >= ArgTys.size() ||
-           !isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
-           VectorType::getExtendedElementVectorType(
-                       cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
+    if (D.getArgumentNumber() >= ArgTys.size())
+      return true;
+
+    Type *NewTy = ArgTys[D.getArgumentNumber()];
+    if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
+      NewTy = VectorType::getExtendedElementVectorType(VTy);
+    else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
+      NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
+    else
+      return true;
 
-  case IITDescriptor::TruncVecArgument:
+    return Ty != NewTy;
+  }
+  case IITDescriptor::TruncArgument: {
     // This may only be used when referring to a previous vector argument.
-    return D.getArgumentNumber() >= ArgTys.size() ||
-           !isa<VectorType>(ArgTys[D.getArgumentNumber()]) ||
-           VectorType::getTruncatedElementVectorType(
-                         cast<VectorType>(ArgTys[D.getArgumentNumber()])) != Ty;
+    if (D.getArgumentNumber() >= ArgTys.size())
+      return true;
+
+    Type *NewTy = ArgTys[D.getArgumentNumber()];
+    if (VectorType *VTy = dyn_cast<VectorType>(NewTy))
+      NewTy = VectorType::getTruncatedElementVectorType(VTy);
+    else if (IntegerType *ITy = dyn_cast<IntegerType>(NewTy))
+      NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
+    else
+      return true;
+
+    return Ty != NewTy;
+  }
   }
   llvm_unreachable("unhandled");
 }
index 884af4c7cb7ca97e24d92704977ddb5d8d5c7bdd..685c4bf07507640aca12400cb55687d92fb557dc 100644 (file)
@@ -498,8 +498,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
       // It only makes sense to use the extended and truncated vector element
       // variants with iAny types; otherwise, if the intrinsic is not
       // overloaded, all the types can be specified directly.
-      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
-               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+      assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedType")) ||
               VT == MVT::iAny || VT == MVT::vAny) &&
              "Expected iAny or vAny type");
     } else {
@@ -532,8 +532,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
       // It only makes sense to use the extended and truncated vector element
       // variants with iAny types; otherwise, if the intrinsic is not
       // overloaded, all the types can be specified directly.
-      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
-               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+      assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedType")) ||
               VT == MVT::iAny || VT == MVT::vAny) &&
              "Expected iAny or vAny type");
     } else
index 1b281288a4ed579c21d09ff6a6b36837b6e34e8c..dc32dfa858442906542c021bc7cbf1bd81ed6f9b 100644 (file)
@@ -246,8 +246,8 @@ enum IIT_Info {
   IIT_STRUCT3 = 20,
   IIT_STRUCT4 = 21,
   IIT_STRUCT5 = 22,
-  IIT_EXTEND_VEC_ARG = 23,
-  IIT_TRUNC_VEC_ARG = 24,
+  IIT_EXTEND_ARG = 23,
+  IIT_TRUNC_ARG = 24,
   IIT_ANYPTR = 25,
   IIT_V1   = 26,
   IIT_VARARG = 27
@@ -292,10 +292,10 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
   if (R->isSubClassOf("LLVMMatchType")) {
     unsigned Number = R->getValueAsInt("Number");
     assert(Number < ArgCodes.size() && "Invalid matching number!");
-    if (R->isSubClassOf("LLVMExtendedElementVectorType"))
-      Sig.push_back(IIT_EXTEND_VEC_ARG);
-    else if (R->isSubClassOf("LLVMTruncatedElementVectorType"))
-      Sig.push_back(IIT_TRUNC_VEC_ARG);
+    if (R->isSubClassOf("LLVMExtendedType"))
+      Sig.push_back(IIT_EXTEND_ARG);
+    else if (R->isSubClassOf("LLVMTruncatedType"))
+      Sig.push_back(IIT_TRUNC_ARG);
     else
       Sig.push_back(IIT_ARG);
     return Sig.push_back((Number << 2) | ArgCodes[Number]);