llvm.org GIT mirror llvm / 7096836
[codegen,aarch64] Add a target hook to the code generator to control vector type legalization strategies in a more fine grained manner, and change the legalization of several v1iN types and v1f32 to be widening rather than scalarization on AArch64. This fixes an assertion failure caused by scalarizing nodes like "v1i32 trunc v1i64". As v1i64 is legal it will fail to scalarize v1i32. This also provides a foundation for other targets to have more granular control over how vector types are legalized. Patch by Hao Liu, reviewed by Tim Northover. I'm committing it to allow some work to start taking place on top of this patch as it adds some really important hooks to the backend that I'd like to immediately start using. =] http://reviews.llvm.org/D4322 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212242 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 6 years ago
10 changed file(s) with 100 addition(s) and 61 deletion(s). Raw diff Collapse all Expand all
184184 /// Return true if the target has BitExtract instructions.
185185 bool hasExtractBitsInsn() const { return HasExtractBitsInsn; }
186186
187 /// Return true if a vector of the given type should be split
188 /// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type
189 /// legalization.
190 virtual bool shouldSplitVectorType(EVT /*VT*/) const { return false; }
187 /// Return the preferred vector type legalization action.
188 virtual TargetLoweringBase::LegalizeTypeAction
189 getPreferredVectorAction(EVT VT) const {
190 // The default action for one element vectors is to scalarize
191 if (VT.getVectorNumElements() == 1)
192 return TypeScalarizeVector;
193 // The default action for other vectors is to promote
194 return TypePromoteInteger;
195 }
191196
192197 // There are two general methods for expanding a BUILD_VECTOR node:
193198 // 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle
10831083 // Loop over all of the vector value types to see which need transformations.
10841084 for (unsigned i = MVT::FIRST_VECTOR_VALUETYPE;
10851085 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
1086 MVT VT = (MVT::SimpleValueType)i;
1087 if (isTypeLegal(VT)) continue;
1088
1089 // Determine if there is a legal wider type. If so, we should promote to
1090 // that wider vector type.
1086 MVT VT = (MVT::SimpleValueType) i;
1087 if (isTypeLegal(VT))
1088 continue;
1089
10911090 MVT EltVT = VT.getVectorElementType();
10921091 unsigned NElts = VT.getVectorNumElements();
1093 if (NElts != 1 && !shouldSplitVectorType(VT)) {
1094 bool IsLegalWiderType = false;
1095 // First try to promote the elements of integer vectors. If no legal
1096 // promotion was found, fallback to the widen-vector method.
1097 for (unsigned nVT = i+1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
1098 MVT SVT = (MVT::SimpleValueType)nVT;
1092 bool IsLegalWiderType = false;
1093 LegalizeTypeAction PreferredAction = getPreferredVectorAction(VT);
1094 switch (PreferredAction) {
1095 case TypePromoteInteger: {
1096 // Try to promote the elements of integer vectors. If no legal
1097 // promotion was found, fall through to the widen-vector method.
1098 for (unsigned nVT = i + 1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
1099 MVT SVT = (MVT::SimpleValueType) nVT;
10991100 // Promote vectors of integers to vectors with the same number
11001101 // of elements, with a wider element type.
11011102 if (SVT.getVectorElementType().getSizeInBits() > EltVT.getSizeInBits()
1102 && SVT.getVectorNumElements() == NElts &&
1103 isTypeLegal(SVT) && SVT.getScalarType().isInteger()) {
1103 && SVT.getVectorNumElements() == NElts && isTypeLegal(SVT)
1104 && SVT.getScalarType().isInteger()) {
11041105 TransformToType[i] = SVT;
11051106 RegisterTypeForVT[i] = SVT;
11061107 NumRegistersForVT[i] = 1;
11091110 break;
11101111 }
11111112 }
1112
1113 if (IsLegalWiderType) continue;
1114
1113 if (IsLegalWiderType)
1114 break;
1115 }
1116 case TypeWidenVector: {
11151117 // Try to widen the vector.
1116 for (unsigned nVT = i+1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
1117 MVT SVT = (MVT::SimpleValueType)nVT;
1118 if (SVT.getVectorElementType() == EltVT &&
1119 SVT.getVectorNumElements() > NElts &&
1120 isTypeLegal(SVT)) {
1118 for (unsigned nVT = i + 1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
1119 MVT SVT = (MVT::SimpleValueType) nVT;
1120 if (SVT.getVectorElementType() == EltVT
1121 && SVT.getVectorNumElements() > NElts && isTypeLegal(SVT)) {
11211122 TransformToType[i] = SVT;
11221123 RegisterTypeForVT[i] = SVT;
11231124 NumRegistersForVT[i] = 1;
11261127 break;
11271128 }
11281129 }
1129 if (IsLegalWiderType) continue;
1130 if (IsLegalWiderType)
1131 break;
11301132 }
1131
1132 MVT IntermediateVT;
1133 MVT RegisterVT;
1134 unsigned NumIntermediates;
1135 NumRegistersForVT[i] =
1136 getVectorTypeBreakdownMVT(VT, IntermediateVT, NumIntermediates,
1137 RegisterVT, this);
1138 RegisterTypeForVT[i] = RegisterVT;
1139
1140 MVT NVT = VT.getPow2VectorType();
1141 if (NVT == VT) {
1142 // Type is already a power of 2. The default action is to split.
1143 TransformToType[i] = MVT::Other;
1144 unsigned NumElts = VT.getVectorNumElements();
1145 ValueTypeActions.setTypeAction(VT,
1146 NumElts > 1 ? TypeSplitVector : TypeScalarizeVector);
1147 } else {
1148 TransformToType[i] = NVT;
1149 ValueTypeActions.setTypeAction(VT, TypeWidenVector);
1133 case TypeSplitVector:
1134 case TypeScalarizeVector: {
1135 MVT IntermediateVT;
1136 MVT RegisterVT;
1137 unsigned NumIntermediates;
1138 NumRegistersForVT[i] = getVectorTypeBreakdownMVT(VT, IntermediateVT,
1139 NumIntermediates, RegisterVT, this);
1140 RegisterTypeForVT[i] = RegisterVT;
1141
1142 MVT NVT = VT.getPow2VectorType();
1143 if (NVT == VT) {
1144 // Type is already a power of 2. The default action is to split.
1145 TransformToType[i] = MVT::Other;
1146 if (PreferredAction == TypeScalarizeVector)
1147 ValueTypeActions.setTypeAction(VT, TypeScalarizeVector);
1148 else
1149 ValueTypeActions.setTypeAction(VT, TypeSplitVector);
1150 } else {
1151 TransformToType[i] = NVT;
1152 ValueTypeActions.setTypeAction(VT, TypeWidenVector);
1153 }
1154 break;
1155 }
1156 default:
1157 llvm_unreachable("Unknown vector legalization action!");
11501158 }
11511159 }
11521160
78857885 return Inst->getType()->getPrimitiveSizeInBits() <= 128;
78867886 }
78877887
7888 TargetLoweringBase::LegalizeTypeAction
7889 AArch64TargetLowering::getPreferredVectorAction(EVT VT) const {
7890 MVT SVT = VT.getSimpleVT();
7891 // During type legalization, we prefer to widen v1i8, v1i16, v1i32 to v8i8,
7892 // v4i16, v2i32 instead of to promote.
7893 if (SVT == MVT::v1i8 || SVT == MVT::v1i16 || SVT == MVT::v1i32
7894 || SVT == MVT::v1f32)
7895 return TypeWidenVector;
7896
7897 return TargetLoweringBase::getPreferredVectorAction(VT);
7898 }
7899
78887900 Value *AArch64TargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
78897901 AtomicOrdering Ord) const {
78907902 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
322322 Value *Addr, AtomicOrdering Ord) const override;
323323
324324 bool shouldExpandAtomicInIR(Instruction *Inst) const override;
325
326 TargetLoweringBase::LegalizeTypeAction
327 getPreferredVectorAction(EVT VT) const override;
325328
326329 private:
327330 /// Subtarget - Keep a pointer to the AArch64Subtarget around so that we can
472472 }
473473 }
474474
475 bool NVPTXTargetLowering::shouldSplitVectorType(EVT VT) const {
476 return VT.getScalarType() == MVT::i1;
475 TargetLoweringBase::LegalizeTypeAction
476 NVPTXTargetLowering::getPreferredVectorAction(EVT VT) const {
477 if (VT.getVectorNumElements() != 1 && VT.getScalarType() == MVT::i1)
478 return TypeSplitVector;
479
480 return TargetLoweringBase::getPreferredVectorAction(VT);
477481 }
478482
479483 SDValue
241241 // PTX always uses 32-bit shift amounts
242242 MVT getScalarShiftAmountTy(EVT LHSTy) const override { return MVT::i32; }
243243
244 bool shouldSplitVectorType(EVT VT) const override;
244 TargetLoweringBase::LegalizeTypeAction
245 getPreferredVectorAction(EVT VT) const override;
245246
246247 private:
247248 const NVPTXSubtarget &nvptxSubtarget; // cache the subtarget here
269269 return VT.bitsGT(MVT::i32);
270270 }
271271
272 bool SITargetLowering::shouldSplitVectorType(EVT VT) const {
273 return VT.getScalarType().bitsLE(MVT::i16);
272 TargetLoweringBase::LegalizeTypeAction
273 SITargetLowering::getPreferredVectorAction(EVT VT) const {
274 if (VT.getVectorNumElements() != 1 && VT.getScalarType().bitsLE(MVT::i16))
275 return TypeSplitVector;
276
277 return TargetLoweringBase::getPreferredVectorAction(VT);
274278 }
275279
276280 bool SITargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
4949 SITargetLowering(TargetMachine &tm);
5050 bool allowsUnalignedMemoryAccesses(EVT VT, unsigned AS,
5151 bool *IsFast) const override;
52 bool shouldSplitVectorType(EVT VT) const override;
52
53 TargetLoweringBase::LegalizeTypeAction
54 getPreferredVectorAction(EVT VT) const override;
5355
5456 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
5557 Type *Ty) const override;
841841
842842 define <8 x i8> @testDUP.v1i8(<1 x i8> %a) {
843843 ; CHECK-LABEL: testDUP.v1i8:
844 ; CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
844 ; CHECK: dup v0.8b, v0.b[0]
845845 %b = extractelement <1 x i8> %a, i32 0
846846 %c = insertelement <8 x i8> undef, i8 %b, i32 0
847847 %d = insertelement <8 x i8> %c, i8 %b, i32 1
856856
857857 define <8 x i16> @testDUP.v1i16(<1 x i16> %a) {
858858 ; CHECK-LABEL: testDUP.v1i16:
859 ; CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
859 ; CHECK: dup v0.8h, v0.h[0]
860860 %b = extractelement <1 x i16> %a, i32 0
861861 %c = insertelement <8 x i16> undef, i16 %b, i32 0
862862 %d = insertelement <8 x i16> %c, i16 %b, i32 1
871871
872872 define <4 x i32> @testDUP.v1i32(<1 x i32> %a) {
873873 ; CHECK-LABEL: testDUP.v1i32:
874 ; CHECK: dup {{v[0-9]+}}.4s, {{w[0-9]+}}
874 ; CHECK: dup v0.4s, v0.s[0]
875875 %b = extractelement <1 x i32> %a, i32 0
876876 %c = insertelement <4 x i32> undef, i32 %b, i32 0
877877 %d = insertelement <4 x i32> %c, i32 %b, i32 1
14101410
14111411 define <4 x i16> @concat_vector_v4i16(<1 x i16> %a) {
14121412 ; CHECK-LABEL: concat_vector_v4i16:
1413 ; CHECK: dup {{v[0-9]+}}.4h, {{w[0-9]+}}
1413 ; CHECK: dup v0.4h, v0.h[0]
14141414 %r = shufflevector <1 x i16> %a, <1 x i16> undef, <4 x i32> zeroinitializer
14151415 ret <4 x i16> %r
14161416 }
14171417
14181418 define <4 x i32> @concat_vector_v4i32(<1 x i32> %a) {
14191419 ; CHECK-LABEL: concat_vector_v4i32:
1420 ; CHECK: dup {{v[0-9]+}}.4s, {{w[0-9]+}}
1420 ; CHECK: dup v0.4s, v0.s[0]
14211421 %r = shufflevector <1 x i32> %a, <1 x i32> undef, <4 x i32> zeroinitializer
14221422 ret <4 x i32> %r
14231423 }
14241424
14251425 define <8 x i8> @concat_vector_v8i8(<1 x i8> %a) {
14261426 ; CHECK-LABEL: concat_vector_v8i8:
1427 ; CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
1427 ; CHECK: dup v0.8b, v0.b[0]
14281428 %r = shufflevector <1 x i8> %a, <1 x i8> undef, <8 x i32> zeroinitializer
14291429 ret <8 x i8> %r
14301430 }
14311431
14321432 define <8 x i16> @concat_vector_v8i16(<1 x i16> %a) {
14331433 ; CHECK-LABEL: concat_vector_v8i16:
1434 ; CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
1434 ; CHECK: dup v0.8h, v0.h[0]
14351435 %r = shufflevector <1 x i16> %a, <1 x i16> undef, <8 x i32> zeroinitializer
14361436 ret <8 x i16> %r
14371437 }
14381438
14391439 define <16 x i8> @concat_vector_v16i8(<1 x i8> %a) {
14401440 ; CHECK-LABEL: concat_vector_v16i8:
1441 ; CHECK: dup {{v[0-9]+}}.16b, {{w[0-9]+}}
1441 ; CHECK: dup v0.16b, v0.b[0]
14421442 %r = shufflevector <1 x i8> %a, <1 x i8> undef, <16 x i32> zeroinitializer
14431443 ret <16 x i8> %r
14441444 }
135135
136136 define <1 x float> @test_select_cc_v1f32(float %a, float %b, <1 x float> %c, <1 x float> %d ) {
137137 ; CHECK-LABEL: test_select_cc_v1f32:
138 ; CHECK: fcmp s0, s1
139 ; CHECK-NEXT: fcsel s0, s2, s3, eq
138 ; CHECK: fcmeq [[MASK:v[0-9]+]].2s, v0.2s, v1.2s
139 ; CHECK-NEXT: bsl [[MASK]].8b, v2.8b, v3.8b
140140 %cmp31 = fcmp oeq float %a, %b
141141 %e = select i1 %cmp31, <1 x float> %c, <1 x float> %d
142142 ret <1 x float> %e