From: Krzysztof Parzyszek Date: Mon, 18 Dec 2017 18:32:27 +0000 (+0000) Subject: [Hexagon] Generate HVX code for vector sign-, zero- and any-extends X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=228589c54a003ce63ebe8363cca0068c6ab72850;p=llvm [Hexagon] Generate HVX code for vector sign-, zero- and any-extends Implement any-extend as zero-extend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321004 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index 6387ac2ef67..dc9eed51f45 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -2013,6 +2013,11 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ADD, T, Legal); setOperationAction(ISD::SUB, T, Legal); setOperationAction(ISD::VSELECT, T, Legal); + if (T != ByteV) { + setOperationAction(ISD::ANY_EXTEND_VECTOR_INREG, T, Legal); + setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, T, Legal); + setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Legal); + } setOperationAction(ISD::MUL, T, Custom); setOperationAction(ISD::SETCC, T, Custom); diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h index 2705fcbf8d6..0619e2e4e7f 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.h +++ b/lib/Target/Hexagon/HexagonISelLowering.h @@ -351,6 +351,7 @@ namespace HexagonISD { SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const; SDValue LowerHvxMul(SDValue Op, SelectionDAG &DAG) const; SDValue LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const; std::pair findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) diff --git a/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp index 652dffce841..c1d44cb0e7d 100644 --- a/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp +++ b/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp @@ -454,3 +454,10 @@ HexagonTargetLowering::LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const { return Negate ? getNode(Hexagon::V6_pred_not, dl, ResTy, {CmpV}, DAG) : CmpV; } + +SDValue +HexagonTargetLowering::LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const { + // Sign- and zero-extends are legal. + assert(Op.getOpcode() == ISD::ANY_EXTEND_VECTOR_INREG); + return DAG.getZeroExtendVectorInReg(Op.getOperand(0), SDLoc(Op), ty(Op)); +} diff --git a/lib/Target/Hexagon/HexagonPatterns.td b/lib/Target/Hexagon/HexagonPatterns.td index f8507036bbf..e2120d3de2e 100644 --- a/lib/Target/Hexagon/HexagonPatterns.td +++ b/lib/Target/Hexagon/HexagonPatterns.td @@ -2910,6 +2910,9 @@ def HexagonVINSERTW0 : SDNode<"HexagonISD::VINSERTW0", SDTHexagonVINSERTW0>; def Combinev: OutPatFrag<(ops node:$Rs, node:$Rt), (REG_SEQUENCE HvxWR, $Rs, vsub_hi, $Rt, vsub_lo)>; +def LoVec: OutPatFrag<(ops node:$Vs), (EXTRACT_SUBREG $Vs, vsub_lo)>; +def HiVec: OutPatFrag<(ops node:$Vs), (EXTRACT_SUBREG $Vs, vsub_hi)>; + let Predicates = [UseHVX] in { def: OpR_RR_pat, VecI8, HVI8>; def: OpR_RR_pat, VecI8, HVI8>; @@ -2957,4 +2960,26 @@ let Predicates = [UseHVX] in { (V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>; def: Pat<(vselect HQ32:$Qu, HVI32:$Vs, HVI32:$Vt), (V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>; + + def: Pat<(VecPI16 (sext HVI8:$Vs)), (V6_vsb HvxVR:$Vs)>; + def: Pat<(VecPI32 (sext HVI16:$Vs)), (V6_vsh HvxVR:$Vs)>; + def: Pat<(VecPI16 (zext HVI8:$Vs)), (V6_vzb HvxVR:$Vs)>; + def: Pat<(VecPI32 (zext HVI16:$Vs)), (V6_vzh HvxVR:$Vs)>; + + def: Pat<(sext_inreg HVI32:$Vs, v16i16), + (V6_vpackeb (LoVec (V6_vsh HvxVR:$Vs)), + (HiVec (V6_vsh HvxVR:$Vs)))>; + def: Pat<(sext_inreg HVI32:$Vs, v32i16), + (V6_vpackeb (LoVec (V6_vsh HvxVR:$Vs)), + (HiVec (V6_vsh HvxVR:$Vs)))>; + + def: Pat<(VecI16 (sext_invec HVI8:$Vs)), (LoVec (V6_vsb HvxVR:$Vs))>; + def: Pat<(VecI32 (sext_invec HVI16:$Vs)), (LoVec (V6_vsh HvxVR:$Vs))>; + def: Pat<(VecI32 (sext_invec HVI8:$Vs)), + (LoVec (V6_vsh (LoVec (V6_vsb HvxVR:$Vs))))>; + + def: Pat<(VecI16 (zext_invec HVI8:$Vs)), (LoVec (V6_vzb HvxVR:$Vs))>; + def: Pat<(VecI32 (zext_invec HVI16:$Vs)), (LoVec (V6_vzh HvxVR:$Vs))>; + def: Pat<(VecI32 (zext_invec HVI8:$Vs)), + (LoVec (V6_vzh (LoVec (V6_vzb HvxVR:$Vs))))>; } diff --git a/test/CodeGen/Hexagon/autohvx/isel-vec-ext.ll b/test/CodeGen/Hexagon/autohvx/isel-vec-ext.ll new file mode 100644 index 00000000000..d7574a277de --- /dev/null +++ b/test/CodeGen/Hexagon/autohvx/isel-vec-ext.ll @@ -0,0 +1,30 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048" +target triple = "hexagon" + +; CHECK-LABEL: danny: +; CHECK: vsxt +; CHECK-NOT: vinsert +define void @danny() local_unnamed_addr #0 { +b2: + %v16 = select <16 x i1> undef, <16 x i16> undef, <16 x i16> zeroinitializer + %v17 = sext <16 x i16> %v16 to <16 x i32> + store <16 x i32> %v17, <16 x i32>* undef, align 128 + unreachable +} + +; CHECK-LABEL: sammy: +; CHECK: vsxt +; CHECK-NOT: vinsert +define void @sammy() local_unnamed_addr #1 { +b2: + %v16 = select <32 x i1> undef, <32 x i16> undef, <32 x i16> zeroinitializer + %v17 = sext <32 x i16> %v16 to <32 x i32> + store <32 x i32> %v17, <32 x i32>* undef, align 128 + unreachable +} + + +attributes #0 = { noinline norecurse nounwind "target-cpu"="hexagonv60" "target-features"="+hvx-length64b,+hvxv60" } +attributes #1 = { noinline norecurse nounwind "target-cpu"="hexagonv60" "target-features"="+hvx-length128b,+hvxv60" } diff --git a/test/CodeGen/Hexagon/autohvx/vext-128b.ll b/test/CodeGen/Hexagon/autohvx/vext-128b.ll new file mode 100644 index 00000000000..6ddab1d5593 --- /dev/null +++ b/test/CodeGen/Hexagon/autohvx/vext-128b.ll @@ -0,0 +1,50 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; CHECK-LABEL: test_00: +; CHECK: v1:0.h = vsxt(v0.b) +define <128 x i16> @test_00(<128 x i8> %v0) #0 { + %p = sext <128 x i8> %v0 to <128 x i16> + ret <128 x i16> %p +} + +; CHECK-LABEL: test_01: +; CHECK: v1:0.w = vsxt(v0.h) +define <64 x i32> @test_01(<64 x i16> %v0) #0 { + %p = sext <64 x i16> %v0 to <64 x i32> + ret <64 x i32> %p +} + +; CHECK-LABEL: test_02: +; CHECK: v1:0.uh = vzxt(v0.ub) +define <128 x i16> @test_02(<128 x i8> %v0) #0 { + %p = zext <128 x i8> %v0 to <128 x i16> + ret <128 x i16> %p +} + +; CHECK-LABEL: test_03: +; CHECK: v1:0.uw = vzxt(v0.uh) +define <64 x i32> @test_03(<64 x i16> %v0) #0 { + %p = zext <64 x i16> %v0 to <64 x i32> + ret <64 x i32> %p +} + +; CHECK-LABEL: test_04: +; CHECK: v[[H40:[0-9]+]]:[[L40:[0-9]+]].h = vsxt(v0.b) +; CHECK: v1:0.w = vsxt(v[[L40]].h) +define <32 x i32> @test_04(<128 x i8> %v0) #0 { + %x = sext <128 x i8> %v0 to <128 x i32> + %p = shufflevector <128 x i32> %x, <128 x i32> undef, <32 x i32> + ret <32 x i32> %p +} + +; CHECK-LABEL: test_05: +; CHECK: v[[H40:[0-9]+]]:[[L40:[0-9]+]].uh = vzxt(v0.ub) +; CHECK: v1:0.uw = vzxt(v[[L40]].uh) +define <32 x i32> @test_05(<128 x i8> %v0) #0 { + %x = zext <128 x i8> %v0 to <128 x i32> + %p = shufflevector <128 x i32> %x, <128 x i32> undef, <32 x i32> + ret <32 x i32> %p +} + +attributes #0 = { nounwind readnone "target-cpu"="hexagonv60" "target-features"="+hvx,+hvx-length128b" } + diff --git a/test/CodeGen/Hexagon/autohvx/vext-64b.ll b/test/CodeGen/Hexagon/autohvx/vext-64b.ll new file mode 100644 index 00000000000..a3df0edc28e --- /dev/null +++ b/test/CodeGen/Hexagon/autohvx/vext-64b.ll @@ -0,0 +1,50 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +; CHECK-LABEL: test_00: +; CHECK: v1:0.h = vsxt(v0.b) +define <64 x i16> @test_00(<64 x i8> %v0) #0 { + %p = sext <64 x i8> %v0 to <64 x i16> + ret <64 x i16> %p +} + +; CHECK-LABEL: test_01: +; CHECK: v1:0.w = vsxt(v0.h) +define <32 x i32> @test_01(<32 x i16> %v0) #0 { + %p = sext <32 x i16> %v0 to <32 x i32> + ret <32 x i32> %p +} + +; CHECK-LABEL: test_02: +; CHECK: v1:0.uh = vzxt(v0.ub) +define <64 x i16> @test_02(<64 x i8> %v0) #0 { + %p = zext <64 x i8> %v0 to <64 x i16> + ret <64 x i16> %p +} + +; CHECK-LABEL: test_03: +; CHECK: v1:0.uw = vzxt(v0.uh) +define <32 x i32> @test_03(<32 x i16> %v0) #0 { + %p = zext <32 x i16> %v0 to <32 x i32> + ret <32 x i32> %p +} + +; CHECK-LABEL: test_04: +; CHECK: v[[H40:[0-9]+]]:[[L40:[0-9]+]].h = vsxt(v0.b) +; CHECK: v1:0.w = vsxt(v[[L40]].h) +define <16 x i32> @test_04(<64 x i8> %v0) #0 { + %x = sext <64 x i8> %v0 to <64 x i32> + %p = shufflevector <64 x i32> %x, <64 x i32> undef, <16 x i32> + ret <16 x i32> %p +} + +; CHECK-LABEL: test_05: +; CHECK: v[[H40:[0-9]+]]:[[L40:[0-9]+]].uh = vzxt(v0.ub) +; CHECK: v1:0.uw = vzxt(v[[L40]].uh) +define <16 x i32> @test_05(<64 x i8> %v0) #0 { + %x = zext <64 x i8> %v0 to <64 x i32> + %p = shufflevector <64 x i32> %x, <64 x i32> undef, <16 x i32> + ret <16 x i32> %p +} + +attributes #0 = { nounwind readnone "target-cpu"="hexagonv60" "target-features"="+hvx,+hvx-length64b" } +