From b7bde0e4f3d2ca9d2fb25f911ba7eb9d2a4cbd05 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 27 Nov 2020 13:09:34 -0600 Subject: [PATCH] [Hexagon] Improve check for HVX types Allow non-simple types, like <17 x i32> to be treated as HVX vector types. --- llvm/lib/Target/Hexagon/HexagonSubtarget.cpp | 29 +++++++++++++++++----- .../CodeGen/Hexagon/autohvx/non-simple-hvx-type.ll | 21 ++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 llvm/test/CodeGen/Hexagon/autohvx/non-simple-hvx-type.ll diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp index 76fe0be..b79e7c2 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp @@ -168,14 +168,31 @@ bool HexagonSubtarget::isTypeForHVX(Type *VecTy, bool IncludeBool) const { // Avoid types like <2 x i32*>. if (!cast(VecTy)->getElementType()->isIntegerTy()) return false; + // The given type may be something like <17 x i32>, which is not MVT, + // but can be represented as (non-simple) EVT. EVT Ty = EVT::getEVT(VecTy, /*HandleUnknown*/false); - if (!Ty.isSimple() || Ty.getSizeInBits() <= 64) + if (Ty.getSizeInBits() <= 64 || !Ty.getVectorElementType().isSimple()) return false; - if (isHVXVectorType(Ty.getSimpleVT(), IncludeBool)) - return true; - auto Action = - getTargetLowering()->getPreferredVectorAction(Ty.getSimpleVT()); - return Action == TargetLoweringBase::TypeWidenVector; + + auto isHvxTy = [this, IncludeBool](MVT SimpleTy) { + if (isHVXVectorType(SimpleTy, IncludeBool)) + return true; + auto Action = getTargetLowering()->getPreferredVectorAction(SimpleTy); + return Action == TargetLoweringBase::TypeWidenVector; + }; + + // Round up EVT to have power-of-2 elements, and keep checking if it + // qualifies for HVX, dividing it in half after each step. + MVT ElemTy = Ty.getVectorElementType().getSimpleVT(); + unsigned VecLen = PowerOf2Ceil(Ty.getVectorNumElements()); + while (ElemTy.getSizeInBits() * VecLen > 64) { + MVT SimpleTy = MVT::getVectorVT(ElemTy, VecLen); + if (SimpleTy.isValid() && isHvxTy(SimpleTy)) + return true; + VecLen /= 2; + } + + return false; } void HexagonSubtarget::UsrOverflowMutation::apply(ScheduleDAGInstrs *DAG) { diff --git a/llvm/test/CodeGen/Hexagon/autohvx/non-simple-hvx-type.ll b/llvm/test/CodeGen/Hexagon/autohvx/non-simple-hvx-type.ll new file mode 100644 index 0000000..18523cc --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/autohvx/non-simple-hvx-type.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -march=hexagon < %s | FileCheck %s + +; Check that <24 x i32> is treated as an HVX vector type. + +define <24 x i32> @f0(<24 x i32>* %a0, <24 x i32> %a1, <24 x i32> %a2) #0 { +; CHECK-LABEL: f0: +; CHECK: // %bb.0: +; CHECK-NEXT: { +; CHECK-NEXT: jumpr r31 +; CHECK-NEXT: v0 = vmemu(r0+#0) +; CHECK-NEXT: } + %v1 = icmp ne <24 x i32> %a1, zeroinitializer + %v2 = call <24 x i32> @llvm.masked.load.v24i1.p0v24i1(<24 x i32>* %a0, i32 4, <24 x i1> %v1, <24 x i32> undef) + ret <24 x i32> %v2 +} + +declare <24 x i32> @llvm.masked.load.v24i1.p0v24i1(<24 x i32>*, i32, <24 x i1>, <24 x i32>) + +attributes #0 = { nounwind readnone "target-cpu"="hexagonv62" "target-features"="+hvx,+hvx-length128b" } + -- 2.7.4