llvm.org GIT mirror llvm / b7de428
Intrinsics: expand semantics of LLVMExtendedVectorType (& trunc) 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 Tim Northover 6 years ago
8 changed file(s) with 76 addition(s) and 57 deletion(s). Raw diff Collapse all Expand all
7878 enum IITDescriptorKind {
7979 Void, VarArg, MMX, Metadata, Half, Float, Double,
8080 Integer, Vector, Pointer, Struct,
81 Argument, ExtendVecArgument, TruncVecArgument
81 Argument, ExtendArgument, TruncArgument,
8282 } Kind;
8383
8484 union {
9797 AK_AnyPointer
9898 };
9999 unsigned getArgumentNumber() const {
100 assert(Kind == Argument || Kind == ExtendVecArgument ||
101 Kind == TruncVecArgument);
100 assert(Kind == Argument || Kind == ExtendArgument ||
101 Kind == TruncArgument);
102102 return Argument_Info >> 2;
103103 }
104104 ArgKind getArgumentKind() const {
105 assert(Kind == Argument || Kind == ExtendVecArgument ||
106 Kind == TruncVecArgument);
105 assert(Kind == Argument || Kind == ExtendArgument ||
106 Kind == TruncArgument);
107107 return (ArgKind)(Argument_Info&3);
108108 }
109109
105105 int Number = num;
106106 }
107107
108 // Match the type of another intrinsic parameter that is expected to be
109 // an integral vector type, but change the element size to be twice as wide
110 // or half as wide as the other type. This is only useful when the intrinsic
111 // is overloaded, so the matched type should be declared as iAny.
112 class LLVMExtendedElementVectorType : LLVMMatchType;
113 class LLVMTruncatedElementVectorType : LLVMMatchType;
108 // Match the type of another intrinsic parameter that is expected to be based on
109 // an integral type (i.e. either iN or ), but change the scalar size to
110 // be twice as wide or half as wide as the other type. This is only useful when
111 // the intrinsic is overloaded, so the matched type should be declared as iAny.
112 class LLVMExtendedType : LLVMMatchType;
113 class LLVMTruncatedType : LLVMMatchType;
114114
115115 def llvm_void_ty : LLVMType;
116116 def llvm_anyint_ty : LLVMType;
6767 [IntrNoMem]>;
6868 class Neon_N2V_Narrow_Intrinsic
6969 : Intrinsic<[llvm_anyvector_ty],
70 [LLVMExtendedElementVectorType<0>, llvm_i32_ty],
70 [LLVMExtendedType<0>, llvm_i32_ty],
7171 [IntrNoMem]>;
7272
7373 // Vector rounding shift right by immediate (Signed)
130130 class Neon_1Arg_Intrinsic
131131 : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
132132 class Neon_1Arg_Narrow_Intrinsic
133 : Intrinsic<[llvm_anyvector_ty],
134 [LLVMExtendedElementVectorType<0>], [IntrNoMem]>;
133 : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<0>], [IntrNoMem]>;
135134 class Neon_2Arg_Intrinsic
136135 : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
137136 [IntrNoMem]>;
138137 class Neon_2Arg_Narrow_Intrinsic
139 : Intrinsic<[llvm_anyvector_ty],
140 [LLVMExtendedElementVectorType<0>,
141 LLVMExtendedElementVectorType<0>],
138 : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<0>, LLVMExtendedType<0>],
142139 [IntrNoMem]>;
143140 class Neon_2Arg_Long_Intrinsic
144 : Intrinsic<[llvm_anyvector_ty],
145 [LLVMTruncatedElementVectorType<0>,
146 LLVMTruncatedElementVectorType<0>],
141 : Intrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>, LLVMTruncatedType<0>],
147142 [IntrNoMem]>;
148143 class Neon_3Arg_Intrinsic
149144 : Intrinsic<[llvm_anyvector_ty],
151146 [IntrNoMem]>;
152147 class Neon_3Arg_Long_Intrinsic
153148 : Intrinsic<[llvm_anyvector_ty],
154 [LLVMMatchType<0>,
155 LLVMTruncatedElementVectorType<0>,
156 LLVMTruncatedElementVectorType<0>],
149 [LLVMMatchType<0>, LLVMTruncatedType<0>, LLVMTruncatedType<0>],
157150 [IntrNoMem]>;
158151 class Neon_CvtFxToFP_Intrinsic
159152 : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
465465 IIT_STRUCT3 = 20,
466466 IIT_STRUCT4 = 21,
467467 IIT_STRUCT5 = 22,
468 IIT_EXTEND_VEC_ARG = 23,
469 IIT_TRUNC_VEC_ARG = 24,
468 IIT_EXTEND_ARG = 23,
469 IIT_TRUNC_ARG = 24,
470470 IIT_ANYPTR = 25,
471471 IIT_V1 = 26,
472472 IIT_VARARG = 27
555555 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
556556 return;
557557 }
558 case IIT_EXTEND_VEC_ARG: {
558 case IIT_EXTEND_ARG: {
559559 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
560 OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendVecArgument,
560 OutputTable.push_back(IITDescriptor::get(IITDescriptor::ExtendArgument,
561561 ArgInfo));
562562 return;
563563 }
564 case IIT_TRUNC_VEC_ARG: {
564 case IIT_TRUNC_ARG: {
565565 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
566 OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncVecArgument,
566 OutputTable.push_back(IITDescriptor::get(IITDescriptor::TruncArgument,
567567 ArgInfo));
568568 return;
569569 }
655655
656656 case IITDescriptor::Argument:
657657 return Tys[D.getArgumentNumber()];
658 case IITDescriptor::ExtendVecArgument:
659 return VectorType::getExtendedElementVectorType(cast(
660 Tys[D.getArgumentNumber()]));
661
662 case IITDescriptor::TruncVecArgument:
663 return VectorType::getTruncatedElementVectorType(cast(
664 Tys[D.getArgumentNumber()]));
658 case IITDescriptor::ExtendArgument: {
659 Type *Ty = Tys[D.getArgumentNumber()];
660 if (VectorType *VTy = dyn_cast(Ty))
661 return VectorType::getExtendedElementVectorType(VTy);
662
663 return IntegerType::get(Context, 2 * cast(Ty)->getBitWidth());
664 }
665 case IITDescriptor::TruncArgument: {
666 Type *Ty = Tys[D.getArgumentNumber()];
667 if (VectorType *VTy = dyn_cast(Ty))
668 return VectorType::getTruncatedElementVectorType(VTy);
669
670 IntegerType *ITy = cast(Ty);
671 assert(ITy->getBitWidth() % 2 == 0);
672 return IntegerType::get(Context, ITy->getBitWidth() / 2);
673 }
665674 }
666675 llvm_unreachable("unhandled");
667676 }
21752175 }
21762176 llvm_unreachable("all argument kinds not covered");
21772177
2178 case IITDescriptor::ExtendVecArgument:
2178 case IITDescriptor::ExtendArgument: {
21792179 // This may only be used when referring to a previous vector argument.
2180 return D.getArgumentNumber() >= ArgTys.size() ||
2181 !isa(ArgTys[D.getArgumentNumber()]) ||
2182 VectorType::getExtendedElementVectorType(
2183 cast(ArgTys[D.getArgumentNumber()])) != Ty;
2184
2185 case IITDescriptor::TruncVecArgument:
2180 if (D.getArgumentNumber() >= ArgTys.size())
2181 return true;
2182
2183 Type *NewTy = ArgTys[D.getArgumentNumber()];
2184 if (VectorType *VTy = dyn_cast(NewTy))
2185 NewTy = VectorType::getExtendedElementVectorType(VTy);
2186 else if (IntegerType *ITy = dyn_cast(NewTy))
2187 NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
2188 else
2189 return true;
2190
2191 return Ty != NewTy;
2192 }
2193 case IITDescriptor::TruncArgument: {
21862194 // This may only be used when referring to a previous vector argument.
2187 return D.getArgumentNumber() >= ArgTys.size() ||
2188 !isa(ArgTys[D.getArgumentNumber()]) ||
2189 VectorType::getTruncatedElementVectorType(
2190 cast(ArgTys[D.getArgumentNumber()])) != Ty;
2195 if (D.getArgumentNumber() >= ArgTys.size())
2196 return true;
2197
2198 Type *NewTy = ArgTys[D.getArgumentNumber()];
2199 if (VectorType *VTy = dyn_cast(NewTy))
2200 NewTy = VectorType::getTruncatedElementVectorType(VTy);
2201 else if (IntegerType *ITy = dyn_cast(NewTy))
2202 NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
2203 else
2204 return true;
2205
2206 return Ty != NewTy;
2207 }
21912208 }
21922209 llvm_unreachable("unhandled");
21932210 }
497497 // It only makes sense to use the extended and truncated vector element
498498 // variants with iAny types; otherwise, if the intrinsic is not
499499 // overloaded, all the types can be specified directly.
500 assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
501 !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
500 assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
501 !TyEl->isSubClassOf("LLVMTruncatedType")) ||
502502 VT == MVT::iAny || VT == MVT::vAny) &&
503503 "Expected iAny or vAny type");
504504 } else {
531531 // It only makes sense to use the extended and truncated vector element
532532 // variants with iAny types; otherwise, if the intrinsic is not
533533 // overloaded, all the types can be specified directly.
534 assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
535 !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
534 assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
535 !TyEl->isSubClassOf("LLVMTruncatedType")) ||
536536 VT == MVT::iAny || VT == MVT::vAny) &&
537537 "Expected iAny or vAny type");
538538 } else
245245 IIT_STRUCT3 = 20,
246246 IIT_STRUCT4 = 21,
247247 IIT_STRUCT5 = 22,
248 IIT_EXTEND_VEC_ARG = 23,
249 IIT_TRUNC_VEC_ARG = 24,
248 IIT_EXTEND_ARG = 23,
249 IIT_TRUNC_ARG = 24,
250250 IIT_ANYPTR = 25,
251251 IIT_V1 = 26,
252252 IIT_VARARG = 27
291291 if (R->isSubClassOf("LLVMMatchType")) {
292292 unsigned Number = R->getValueAsInt("Number");
293293 assert(Number < ArgCodes.size() && "Invalid matching number!");
294 if (R->isSubClassOf("LLVMExtendedElementVectorType"))
295 Sig.push_back(IIT_EXTEND_VEC_ARG);
296 else if (R->isSubClassOf("LLVMTruncatedElementVectorType"))
297 Sig.push_back(IIT_TRUNC_VEC_ARG);
294 if (R->isSubClassOf("LLVMExtendedType"))
295 Sig.push_back(IIT_EXTEND_ARG);
296 else if (R->isSubClassOf("LLVMTruncatedType"))
297 Sig.push_back(IIT_TRUNC_ARG);
298298 else
299299 Sig.push_back(IIT_ARG);
300300 return Sig.push_back((Number << 2) | ArgCodes[Number]);