From fb625eadf9b7257a3cfb887da3c1b0bcf8a749c7 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 26 Apr 2014 13:01:03 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207317 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 14 +++++++ lib/Target/X86/X86InstrSSE.td | 8 ++-- test/CodeGen/X86/vector-idiv.ll | 61 ++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 9a419bb5269..ed2d7e6e8c0 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/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/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 3b0cc6bff2f..eb036f23eb7 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/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/test/CodeGen/X86/vector-idiv.ll b/test/CodeGen/X86/vector-idiv.ll index 5b8153a9685..0d43b96163d 100644 --- a/test/CodeGen/X86/vector-idiv.ll +++ b/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, + 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, + 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, + 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, + ret <16 x i16> %div + +; AVX-LABEL: test6: +; AVX: vpmulhw +; AVX: vpsrlw $15 +; AVX: vpsraw $1 +; AVX: vpaddw +; AVX-NOT: vpmulhw +} + ; TODO: sdiv -> pmuldq