From 8d77555b1234a2620238125328160dbe88a5e487 Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Fri, 12 Nov 2021 16:19:56 +0000 Subject: [PATCH] [Analysis] Ensure getTypeLegalizationCost returns a simple VT for TypeScalarizeScalableVector When getTypeConversion returns TypeScalarizeScalableVector we were sometimes returning a non-simple type from getTypeLegalizationCost. However, many callers depend upon this being a simple type and will crash if not. This patch changes getTypeLegalizationCost to ensure that we always a return sensible simple VT. If the vector type contains unusual integer types, e.g. , then we just set the type to MVT::i64 as a reasonable default. A test has been added here that demonstrates the vectoriser can correctly calculate the cost of vectorising a "zext i3 to i64" instruction with a VF=vscale x 1: Transforms/LoopVectorize/AArch64/sve-inductions-unusual-types.ll Differential Revision: https://reviews.llvm.org/D113777 --- llvm/lib/CodeGen/TargetLoweringBase.cpp | 8 +++- .../AArch64/sve-inductions-unusual-types.ll | 46 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 0dd45be..c0a7eff 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1856,8 +1856,12 @@ TargetLoweringBase::getTypeLegalizationCost(const DataLayout &DL, while (true) { LegalizeKind LK = getTypeConversion(C, MTy); - if (LK.first == TypeScalarizeScalableVector) - return std::make_pair(InstructionCost::getInvalid(), MVT::getVT(Ty)); + if (LK.first == TypeScalarizeScalableVector) { + // Ensure we return a sensible simple VT here, since many callers of this + // function require it. + MVT VT = MTy.isSimple() ? MTy.getSimpleVT() : MVT::i64; + return std::make_pair(InstructionCost::getInvalid(), VT); + } if (LK.first == TypeLegal) return std::make_pair(Cost, MTy.getSimpleVT()); diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/sve-inductions-unusual-types.ll b/llvm/test/Transforms/LoopVectorize/AArch64/sve-inductions-unusual-types.ll index 712bf77..b31e779 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/sve-inductions-unusual-types.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/sve-inductions-unusual-types.ll @@ -48,4 +48,50 @@ for.end: ; preds = %for.body ret void } + +; DEBUG: Found an estimated cost of Invalid for VF vscale x 1 For instruction: %indvars.iv1294 = phi i3 [ %indvars.iv.next1295, %for.body ], [ 0, %entry ] +; DEBUG: Found an estimated cost of Invalid for VF vscale x 1 For instruction: %zexti3 = zext i3 %indvars.iv1294 to i64 +; DEBUG: Found an estimated cost of Invalid for VF vscale x 1 For instruction: %indvars.iv.next1295 = add i3 %indvars.iv1294, 1 + +define void @induction_i3_zext(i64* %dst) #0 { +; CHECK-LABEL: @induction_i3_zext( +; CHECK: vector.ph: +; CHECK: [[TMP4:%.*]] = call @llvm.experimental.stepvector.nxv2i8() +; CHECK: [[TMP5:%.*]] = trunc %4 to +; CHECK-NEXT: [[TMP6:%.*]] = add [[TMP5]], zeroinitializer +; CHECK-NEXT: [[TMP7:%.*]] = mul [[TMP6]], shufflevector ( insertelement ( poison, i3 1, i32 0), poison, zeroinitializer) +; CHECK-NEXT: [[INDUCTION:%.*]] = add zeroinitializer, [[TMP7]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %vector.body ] +; CHECK-NEXT: [[VEC_IND:%.*]] = phi [ [[INDUCTION]], %vector.ph ], [ [[VEC_IND_NEXT:%.*]], %vector.body ] +; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[INDEX]], 0 +; CHECK-NEXT: [[TMP10:%.*]] = zext [[VEC_IND]] to +; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[TMP9]] +; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i64, i64* [[TMP12]], i32 0 +; CHECK-NEXT: [[TMP14:%.*]] = bitcast i64* [[TMP13]] to * +; CHECK-NEXT: store [[TMP10]], * [[TMP14]], align 8 +; CHECK-NEXT: [[TMP15:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP16:%.*]] = mul i64 [[TMP15]], 2 +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP16]] +; CHECK-NEXT: [[VEC_IND_NEXT]] = add [[VEC_IND]], +; +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %indvars.iv1294 = phi i3 [ %indvars.iv.next1295, %for.body ], [ 0, %entry ] + %indvars.iv1286 = phi i64 [ %indvars.iv.next1287, %for.body ], [ 0, %entry ] + %zexti3 = zext i3 %indvars.iv1294 to i64 + %arrayidx = getelementptr inbounds i64, i64* %dst, i64 %indvars.iv1286 + store i64 %zexti3, i64* %arrayidx, align 8 + %indvars.iv.next1287 = add nuw nsw i64 %indvars.iv1286, 1 + %indvars.iv.next1295 = add i3 %indvars.iv1294, 1 + %exitcond = icmp eq i64 %indvars.iv.next1287, 64 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body + ret void +} + + attributes #0 = {"target-features"="+sve"} -- 2.7.4