diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2014-04-26 13:01:03 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2014-04-26 13:01:03 +0000 |
commit | c9827ab103a7da183a955f2d61b1b19ec0a0ae7d (patch) | |
tree | a8ea1ed3aa10fe051b4f6e557c27f1c91db1605b | |
parent | ad0168702a521404f381a1d7d1efa2183d1754da (diff) | |
download | bcm5719-llvm-c9827ab103a7da183a955f2d61b1b19ec0a0ae7d.tar.gz bcm5719-llvm-c9827ab103a7da183a955f2d61b1b19ec0a0ae7d.zip |
X86: Add patterns for MULHU/MULHS of v8i16 and v16i16.
This gets us pretty code for divs of i16 vectors. Turn the existing
intrinsics into the corresponding nodes.
llvm-svn: 207317
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrSSE.td | 8 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/vector-idiv.ll | 61 |
3 files changed, 79 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 9a419bb5269..ed2d7e6e8c0 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -941,6 +941,8 @@ void X86TargetLowering::resetOperationActions() { setOperationAction(ISD::MUL, MVT::v4i32, Custom); setOperationAction(ISD::MUL, MVT::v2i64, Custom); setOperationAction(ISD::UMUL_LOHI, MVT::v4i32, Custom); + setOperationAction(ISD::MULHU, MVT::v8i16, Legal); + setOperationAction(ISD::MULHS, MVT::v8i16, Legal); setOperationAction(ISD::SUB, MVT::v16i8, Legal); setOperationAction(ISD::SUB, MVT::v8i16, Legal); setOperationAction(ISD::SUB, MVT::v4i32, Legal); @@ -1225,6 +1227,8 @@ void X86TargetLowering::resetOperationActions() { // Don't lower v32i8 because there is no 128-bit byte mul setOperationAction(ISD::UMUL_LOHI, MVT::v8i32, Custom); + setOperationAction(ISD::MULHU, MVT::v16i16, Legal); + setOperationAction(ISD::MULHS, MVT::v16i16, Legal); setOperationAction(ISD::VSELECT, MVT::v32i8, Legal); } else { @@ -11725,6 +11729,16 @@ static SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) { return DAG.getNode(X86ISD::PMULUDQ, dl, Op.getValueType(), Op.getOperand(1), Op.getOperand(2)); + case Intrinsic::x86_sse2_pmulhu_w: + case Intrinsic::x86_avx2_pmulhu_w: + return DAG.getNode(ISD::MULHU, dl, Op.getValueType(), + Op.getOperand(1), Op.getOperand(2)); + + case Intrinsic::x86_sse2_pmulh_w: + case Intrinsic::x86_avx2_pmulh_w: + return DAG.getNode(ISD::MULHS, dl, Op.getValueType(), + Op.getOperand(1), Op.getOperand(2)); + // SSE2/AVX2 sub with unsigned saturation intrinsics case Intrinsic::x86_sse2_psubus_b: case Intrinsic::x86_sse2_psubus_w: diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index 3b0cc6bff2f..eb036f23eb7 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -4081,6 +4081,10 @@ defm PADDQ : PDI_binop_all<0xD4, "paddq", add, v2i64, v4i64, SSE_INTALUQ_ITINS_P, 1>; defm PMULLW : PDI_binop_all<0xD5, "pmullw", mul, v8i16, v16i16, SSE_INTMUL_ITINS_P, 1>; +defm PMULHUW : PDI_binop_all<0xE4, "pmulhuw", mulhu, v8i16, v16i16, + SSE_INTMUL_ITINS_P, 1>; +defm PMULHW : PDI_binop_all<0xE5, "pmulhw", mulhs, v8i16, v16i16, + SSE_INTMUL_ITINS_P, 1>; defm PSUBB : PDI_binop_all<0xF8, "psubb", sub, v16i8, v32i8, SSE_INTALU_ITINS_P, 0>; defm PSUBW : PDI_binop_all<0xF9, "psubw", sub, v8i16, v16i16, @@ -4115,10 +4119,6 @@ defm PADDUSB : PDI_binop_all_int<0xDC, "paddusb", int_x86_sse2_paddus_b, int_x86_avx2_paddus_b, SSE_INTALU_ITINS_P, 1>; defm PADDUSW : PDI_binop_all_int<0xDD, "paddusw", int_x86_sse2_paddus_w, int_x86_avx2_paddus_w, SSE_INTALU_ITINS_P, 1>; -defm PMULHUW : PDI_binop_all_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w, - int_x86_avx2_pmulhu_w, SSE_INTMUL_ITINS_P, 1>; -defm PMULHW : PDI_binop_all_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w, - int_x86_avx2_pmulh_w, SSE_INTMUL_ITINS_P, 1>; defm PMADDWD : PDI_binop_all_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd, int_x86_avx2_pmadd_wd, SSE_PMADD, 1>; defm PAVGB : PDI_binop_all_int<0xE0, "pavgb", int_x86_sse2_pavg_b, diff --git a/llvm/test/CodeGen/X86/vector-idiv.ll b/llvm/test/CodeGen/X86/vector-idiv.ll index 5b8153a9685..0d43b96163d 100644 --- a/llvm/test/CodeGen/X86/vector-idiv.ll +++ b/llvm/test/CodeGen/X86/vector-idiv.ll @@ -42,4 +42,65 @@ define <8 x i32> @test2(<8 x i32> %a) { ; AVX: vpsrld $2 } +define <8 x i16> @test3(<8 x i16> %a) { + %div = udiv <8 x i16> %a, <i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7> + ret <8 x i16> %div + +; SSE-LABEL: test3: +; SSE: pmulhuw +; SSE: psubw +; SSE: psrlw $1 +; SSE: paddw +; SSE: psrlw $2 + +; AVX-LABEL: test3: +; AVX: vpmulhuw +; AVX: vpsubw +; AVX: vpsrlw $1 +; AVX: vpaddw +; AVX: vpsrlw $2 +} + +define <16 x i16> @test4(<16 x i16> %a) { + %div = udiv <16 x i16> %a, <i16 7, i16 7, i16 7, i16 7,i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7,i16 7, i16 7, i16 7, i16 7> + ret <16 x i16> %div + +; AVX-LABEL: test4: +; AVX: vpmulhuw +; AVX: vpsubw +; AVX: vpsrlw $1 +; AVX: vpaddw +; AVX: vpsrlw $2 +; AVX-NOT: vpmulhuw +} + +define <8 x i16> @test5(<8 x i16> %a) { + %div = sdiv <8 x i16> %a, <i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7> + ret <8 x i16> %div + +; SSE-LABEL: test5: +; SSE: pmulhw +; SSE: psrlw $15 +; SSE: psraw $1 +; SSE: paddw + +; AVX-LABEL: test5: +; AVX: vpmulhw +; AVX: vpsrlw $15 +; AVX: vpsraw $1 +; AVX: vpaddw +} + +define <16 x i16> @test6(<16 x i16> %a) { + %div = sdiv <16 x i16> %a, <i16 7, i16 7, i16 7, i16 7,i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7,i16 7, i16 7, i16 7, i16 7> + ret <16 x i16> %div + +; AVX-LABEL: test6: +; AVX: vpmulhw +; AVX: vpsrlw $15 +; AVX: vpsraw $1 +; AVX: vpaddw +; AVX-NOT: vpmulhw +} + ; TODO: sdiv -> pmuldq |