From: Krzysztof Parzyszek Date: Wed, 6 Dec 2017 22:41:49 +0000 (+0000) Subject: [Hexagon] Recognize vdealb, vdealh, vshuffb and vshuffh specifically X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7ef89ebab96cd96d43645b04820ab310d1a2ca0d;p=llvm [Hexagon] Recognize vdealb, vdealh, vshuffb and vshuffh specifically git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319978 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp index 924639ad092..835b088050e 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp @@ -1538,8 +1538,6 @@ OpRef HvxSelector::perfect(ShuffleMask SM, OpRef Va, ResultStack &Results) { // V6_vshuffvdd (V6_vshuff) // V6_dealvdd (V6_vdeal) - // TODO Recognize patterns for V6_vdeal{b,h} and V6_vshuff{b,h}. - int VecLen = SM.Mask.size(); assert(isPowerOf2_32(VecLen) && Log2_32(VecLen) <= 8); unsigned LogLen = Log2_32(VecLen); @@ -1708,6 +1706,32 @@ OpRef HvxSelector::perfect(ShuffleMask SM, OpRef Va, ResultStack &Results) { return NewC; }; + auto pfs = [](const std::set &Cs, unsigned Len) { + // Ordering: shuff: 5 0 1 2 3 4, deal: 5 4 3 2 1 0 (for Log=6), + // for bytes zero is included, for halfwords is not. + if (Cs.size() != 1) + return 0u; + const CycleType &C = *Cs.begin(); + if (C[0] != Len-1) + return 0u; + int D = Len - C.size(); + if (D != 0 && D != 1) + return 0u; + + bool IsDeal = true, IsShuff = true; + for (unsigned I = 1; I != Len-D; ++I) { + if (C[I] != Len-1-I) + IsDeal = false; + if (C[I] != I-(1-D)) // I-1, I + IsShuff = false; + } + // At most one, IsDeal or IsShuff, can be non-zero. + assert(!(IsDeal || IsShuff) || IsDeal != IsShuff); + static unsigned Deals[] = { Hexagon::V6_vdealb, Hexagon::V6_vdealh }; + static unsigned Shufs[] = { Hexagon::V6_vshuffb, Hexagon::V6_vshuffh }; + return IsDeal ? Deals[D] : (IsShuff ? Shufs[D] : 0); + }; + while (!All.empty()) { unsigned A = *All.begin(); All.erase(A); @@ -1722,6 +1746,17 @@ OpRef HvxSelector::perfect(ShuffleMask SM, OpRef Va, ResultStack &Results) { Cycles.insert(canonicalize(C)); } + MVT SingleTy = getSingleVT(MVT::i8); + MVT PairTy = getPairVT(MVT::i8); + + // Recognize patterns for V6_vdeal{b,h} and V6_vshuff{b,h}. + if (unsigned(VecLen) == HwLen) { + if (unsigned SingleOpc = pfs(Cycles, LogLen)) { + Results.push(SingleOpc, SingleTy, {Va}); + return OpRef::res(Results.top()); + } + } + SmallVector SwapElems; if (HwLen == unsigned(VecLen)) SwapElems.push_back(LogLen-1); @@ -1733,8 +1768,6 @@ OpRef HvxSelector::perfect(ShuffleMask SM, OpRef Va, ResultStack &Results) { SwapElems.push_back(C[0]); } - MVT SingleTy = getSingleVT(MVT::i8); - MVT PairTy = getPairVT(MVT::i8); const SDLoc &dl(Results.InpNode); OpRef Arg = !Extend ? Va : concat(Va, OpRef::undef(SingleTy), Results); diff --git a/test/CodeGen/Hexagon/autohvx/shuff-single.ll b/test/CodeGen/Hexagon/autohvx/shuff-single.ll new file mode 100644 index 00000000000..677b170a565 --- /dev/null +++ b/test/CodeGen/Hexagon/autohvx/shuff-single.ll @@ -0,0 +1,62 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; CHECK-LABEL: test_vdealb_64: +; CHECK: v0.b = vdeal(v0.b) +define <64 x i8> @test_vdealb_64(<64 x i8> %v0) #0 { + %p = shufflevector <64 x i8> %v0, <64 x i8> undef, <64 x i32> + ret <64 x i8> %p +} + +; CHECK-LABEL: test_vdealh_64: +; CHECK: v0.h = vdeal(v0.h) +define <64 x i8> @test_vdealh_64(<64 x i8> %v0) #0 { + %p = shufflevector <64 x i8> %v0, <64 x i8> undef, <64 x i32> + ret <64 x i8> %p +} + +; CHECK-LABEL: test_vshuffb_64: +; CHECK: v0.b = vshuff(v0.b) +define <64 x i8> @test_vshuffb_64(<64 x i8> %v0) #0 { + %p = shufflevector <64 x i8> %v0, <64 x i8> undef, <64 x i32> + ret <64 x i8> %p +} + +; CHECK-LABEL: test_vshuffh_64: +; CHECK: v0.h = vshuff(v0.h) +define <64 x i8> @test_vshuffh_64(<64 x i8> %v0) #0 { + %p = shufflevector <64 x i8> %v0, <64 x i8> undef, <64 x i32> + ret <64 x i8> %p +} + + +; CHECK-LABEL: test_vdealb_128: +; CHECK: v0.b = vdeal(v0.b) +define <128 x i8> @test_vdealb_128(<128 x i8> %v0) #1 { + %p = shufflevector <128 x i8> %v0, <128 x i8> undef, <128 x i32> + ret <128 x i8> %p +} + +; CHECK-LABEL: test_vdealh_128: +; CHECK: v0.h = vdeal(v0.h) +define <128 x i8> @test_vdealh_128(<128 x i8> %v0) #1 { + %p = shufflevector <128 x i8> %v0, <128 x i8> undef, <128 x i32> + ret <128 x i8> %p +} + +; CHECK-LABEL: test_vshuffb_128: +; CHECK: v0.b = vshuff(v0.b) +define <128 x i8> @test_vshuffb_128(<128 x i8> %v0) #1 { + %p = shufflevector <128 x i8> %v0, <128 x i8> undef, <128 x i32> + ret <128 x i8> %p +} + +; CHECK-LABEL: test_vshuffh_128: +; CHECK: v0.h = vshuff(v0.h) +define <128 x i8> @test_vshuffh_128(<128 x i8> %v0) #1 { + %p = shufflevector <128 x i8> %v0, <128 x i8> undef, <128 x i32> + ret <128 x i8> %p +} + +attributes #0 = { readnone nounwind "target-cpu"="hexagonv60" "target-features"="+hvx,+hvx-length64b" } +attributes #1 = { readnone nounwind "target-cpu"="hexagonv60" "target-features"="+hvx,+hvx-length128b" } +