From 6098b33515cc8c4f0cdbc8673403c64d17c428ba Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 27 Sep 2013 13:36:54 +0000 Subject: [PATCH] [mips][msa] Implemented insert.d intrinsic. This intrinsic is lowered into an equivalent INSERT_VECTOR_ELT which is further lowered into a sequence of insert.w's on MIPS32. llvm-svn: 191521 --- llvm/include/llvm/IR/IntrinsicsMips.td | 3 + llvm/lib/Target/Mips/MipsSEISelLowering.cpp | 17 +--- llvm/test/CodeGen/Mips/msa/elm_insv.ll | 88 ++++++++++++++------- 3 files changed, 66 insertions(+), 42 deletions(-) diff --git a/llvm/include/llvm/IR/IntrinsicsMips.td b/llvm/include/llvm/IR/IntrinsicsMips.td index 53e21428bf4e..5d8a7be7947b 100644 --- a/llvm/include/llvm/IR/IntrinsicsMips.td +++ b/llvm/include/llvm/IR/IntrinsicsMips.td @@ -1208,6 +1208,9 @@ def int_mips_insert_h : GCCBuiltin<"__builtin_msa_insert_h">, def int_mips_insert_w : GCCBuiltin<"__builtin_msa_insert_w">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_mips_insert_d : GCCBuiltin<"__builtin_msa_insert_d">, + Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty, llvm_i64_ty], + [IntrNoMem]>; def int_mips_insve_b : GCCBuiltin<"__builtin_msa_insve_b">, Intrinsic<[llvm_v16i8_ty], diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp index b05ab343413f..52509b72d1b3 100644 --- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp @@ -1048,19 +1048,6 @@ static SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { return Result; } -// Lower an MSA insert intrinsic into the specified SelectionDAG node -static SDValue lowerMSAInsertIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { - SDLoc DL(Op); - SDValue Op0 = Op->getOperand(1); - SDValue Op1 = Op->getOperand(2); - SDValue Op2 = Op->getOperand(3); - EVT ResTy = Op->getValueType(0); - - SDValue Result = DAG.getNode(Opc, DL, ResTy, Op0, Op2, Op1); - - return Result; -} - static SDValue lowerMSASplatImm(SDLoc DL, EVT ResTy, SDValue ImmOp, SelectionDAG &DAG) { EVT ViaVecTy = ResTy; @@ -1381,7 +1368,9 @@ SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::mips_insert_b: case Intrinsic::mips_insert_h: case Intrinsic::mips_insert_w: - return lowerMSAInsertIntr(Op, DAG, ISD::INSERT_VECTOR_ELT); + case Intrinsic::mips_insert_d: + return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(Op), Op->getValueType(0), + Op->getOperand(1), Op->getOperand(3), Op->getOperand(2)); case Intrinsic::mips_ldi_b: case Intrinsic::mips_ldi_h: case Intrinsic::mips_ldi_w: diff --git a/llvm/test/CodeGen/Mips/msa/elm_insv.ll b/llvm/test/CodeGen/Mips/msa/elm_insv.ll index 409503eb7cd6..a34002a375c5 100644 --- a/llvm/test/CodeGen/Mips/msa/elm_insv.ll +++ b/llvm/test/CodeGen/Mips/msa/elm_insv.ll @@ -19,10 +19,10 @@ entry: declare <16 x i8> @llvm.mips.insert.b(<16 x i8>, i32, i32) nounwind ; CHECK: llvm_mips_insert_b_test: -; CHECK: lw -; CHECK: ld.b -; CHECK: insert.b -; CHECK: st.b +; CHECK-DAG: lw [[R1:\$[0-9]+]], 0( +; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0( +; CHECK-DAG: insert.b [[R2]][1], [[R1]] +; CHECK-DAG: st.b [[R2]], 0( ; CHECK: .size llvm_mips_insert_b_test ; @llvm_mips_insert_h_ARG1 = global <8 x i16> , align 16 @@ -41,10 +41,10 @@ entry: declare <8 x i16> @llvm.mips.insert.h(<8 x i16>, i32, i32) nounwind ; CHECK: llvm_mips_insert_h_test: -; CHECK: lw -; CHECK: ld.h -; CHECK: insert.h -; CHECK: st.h +; CHECK-DAG: lw [[R1:\$[0-9]+]], 0( +; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0( +; CHECK-DAG: insert.h [[R2]][1], [[R1]] +; CHECK-DAG: st.h [[R2]], 0( ; CHECK: .size llvm_mips_insert_h_test ; @llvm_mips_insert_w_ARG1 = global <4 x i32> , align 16 @@ -63,12 +63,36 @@ entry: declare <4 x i32> @llvm.mips.insert.w(<4 x i32>, i32, i32) nounwind ; CHECK: llvm_mips_insert_w_test: -; CHECK: lw -; CHECK: ld.w -; CHECK: insert.w -; CHECK: st.w +; CHECK-DAG: lw [[R1:\$[0-9]+]], 0( +; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0( +; CHECK-DAG: insert.w [[R2]][1], [[R1]] +; CHECK-DAG: st.w [[R2]], 0( ; CHECK: .size llvm_mips_insert_w_test ; +@llvm_mips_insert_d_ARG1 = global <2 x i64> , align 16 +@llvm_mips_insert_d_ARG3 = global i64 27, align 16 +@llvm_mips_insert_d_RES = global <2 x i64> , align 16 + +define void @llvm_mips_insert_d_test() nounwind { +entry: + %0 = load <2 x i64>* @llvm_mips_insert_d_ARG1 + %1 = load i64* @llvm_mips_insert_d_ARG3 + %2 = tail call <2 x i64> @llvm.mips.insert.d(<2 x i64> %0, i32 1, i64 %1) + store <2 x i64> %2, <2 x i64>* @llvm_mips_insert_d_RES + ret void +} + +declare <2 x i64> @llvm.mips.insert.d(<2 x i64>, i32, i64) nounwind + +; CHECK: llvm_mips_insert_d_test: +; CHECK-DAG: lw [[R1:\$[0-9]+]], 0( +; CHECK-DAG: lw [[R2:\$[0-9]+]], 4( +; CHECK-DAG: ld.w [[R3:\$w[0-9]+]], +; CHECK-DAG: insert.w [[R3]][2], [[R1]] +; CHECK-DAG: insert.w [[R3]][3], [[R2]] +; CHECK-DAG: st.w [[R3]], +; CHECK: .size llvm_mips_insert_d_test +; @llvm_mips_insve_b_ARG1 = global <16 x i8> , align 16 @llvm_mips_insve_b_ARG3 = global <16 x i8> , align 16 @llvm_mips_insve_b_RES = global <16 x i8> , align 16 @@ -85,10 +109,12 @@ entry: declare <16 x i8> @llvm.mips.insve.b(<16 x i8>, i32, <16 x i8>) nounwind ; CHECK: llvm_mips_insve_b_test: -; CHECK: ld.b -; CHECK: ld.b -; CHECK: insve.b -; CHECK: st.b +; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_insve_b_ARG1)( +; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_insve_b_ARG3)( +; CHECK-DAG: ld.b [[R3:\$w[0-9]+]], 0([[R1]]) +; CHECK-DAG: ld.b [[R4:\$w[0-9]+]], 0([[R2]]) +; CHECK-DAG: insve.b [[R3]][1], [[R4]][0] +; CHECK-DAG: st.b [[R3]], ; CHECK: .size llvm_mips_insve_b_test ; @llvm_mips_insve_h_ARG1 = global <8 x i16> , align 16 @@ -107,10 +133,12 @@ entry: declare <8 x i16> @llvm.mips.insve.h(<8 x i16>, i32, <8 x i16>) nounwind ; CHECK: llvm_mips_insve_h_test: -; CHECK: ld.h -; CHECK: ld.h -; CHECK: insve.h -; CHECK: st.h +; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_insve_h_ARG1)( +; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_insve_h_ARG3)( +; CHECK-DAG: ld.h [[R3:\$w[0-9]+]], 0([[R1]]) +; CHECK-DAG: ld.h [[R4:\$w[0-9]+]], 0([[R2]]) +; CHECK-DAG: insve.h [[R3]][1], [[R4]][0] +; CHECK-DAG: st.h [[R3]], ; CHECK: .size llvm_mips_insve_h_test ; @llvm_mips_insve_w_ARG1 = global <4 x i32> , align 16 @@ -129,10 +157,12 @@ entry: declare <4 x i32> @llvm.mips.insve.w(<4 x i32>, i32, <4 x i32>) nounwind ; CHECK: llvm_mips_insve_w_test: -; CHECK: ld.w -; CHECK: ld.w -; CHECK: insve.w -; CHECK: st.w +; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_insve_w_ARG1)( +; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_insve_w_ARG3)( +; CHECK-DAG: ld.w [[R3:\$w[0-9]+]], 0([[R1]]) +; CHECK-DAG: ld.w [[R4:\$w[0-9]+]], 0([[R2]]) +; CHECK-DAG: insve.w [[R3]][1], [[R4]][0] +; CHECK-DAG: st.w [[R3]], ; CHECK: .size llvm_mips_insve_w_test ; @llvm_mips_insve_d_ARG1 = global <2 x i64> , align 16 @@ -151,9 +181,11 @@ entry: declare <2 x i64> @llvm.mips.insve.d(<2 x i64>, i32, <2 x i64>) nounwind ; CHECK: llvm_mips_insve_d_test: -; CHECK: ld.d -; CHECK: ld.d -; CHECK: insve.d -; CHECK: st.d +; CHECK-DAG: lw [[R1:\$[0-9]+]], %got(llvm_mips_insve_d_ARG1)( +; CHECK-DAG: lw [[R2:\$[0-9]+]], %got(llvm_mips_insve_d_ARG3)( +; CHECK-DAG: ld.d [[R3:\$w[0-9]+]], 0([[R1]]) +; CHECK-DAG: ld.d [[R4:\$w[0-9]+]], 0([[R2]]) +; CHECK-DAG: insve.d [[R3]][1], [[R4]][0] +; CHECK-DAG: st.d [[R3]], ; CHECK: .size llvm_mips_insve_d_test ;