diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td index 7dd9ff7f08b8b..33c6b3011dc67 100644 --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -1351,6 +1351,18 @@ def int_ppc_vsx_lxvll : def int_ppc_vsx_lxvp : DefaultAttrsIntrinsic<[llvm_v256i1_ty], [llvm_ptr_ty], [IntrReadMem, IntrArgMemOnly]>; +def int_ppc_vsx_lxvrl : + DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_ptr_ty, llvm_i64_ty], + [IntrReadMem, IntrArgMemOnly]>; +def int_ppc_vsx_lxvrll : + DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_ptr_ty, llvm_i64_ty], + [IntrReadMem, IntrArgMemOnly]>; +def int_ppc_vsx_lxvprl : + DefaultAttrsIntrinsic<[llvm_v256i1_ty], [llvm_ptr_ty, llvm_i64_ty], + [IntrReadMem, IntrArgMemOnly]>; +def int_ppc_vsx_lxvprll : + DefaultAttrsIntrinsic<[llvm_v256i1_ty], [llvm_ptr_ty, llvm_i64_ty], + [IntrReadMem, IntrArgMemOnly]>; // Vector store. def int_ppc_vsx_stxvw4x : Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], @@ -1370,6 +1382,19 @@ def int_ppc_vsx_stxvll : def int_ppc_vsx_stxvp : Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty], [IntrWriteMem, IntrArgMemOnly]>; +def int_ppc_vsx_stxvrl : + Intrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i64_ty], + [IntrWriteMem, IntrArgMemOnly]>; +def int_ppc_vsx_stxvrll : + Intrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i64_ty], + [IntrWriteMem, IntrArgMemOnly]>; +def int_ppc_vsx_stxvprl : + Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty, llvm_i64_ty], [IntrWriteMem, + IntrArgMemOnly]>; +def int_ppc_vsx_stxvprll : + Intrinsic<[], [llvm_v256i1_ty, llvm_ptr_ty, llvm_i64_ty], [IntrWriteMem, + IntrArgMemOnly]>; + // Vector and scalar maximum. def int_ppc_vsx_xvmaxdp : PowerPC_VSX_Vec_DDD_Intrinsic<"xvmaxdp">; def int_ppc_vsx_xvmaxsp : PowerPC_VSX_Vec_FFF_Intrinsic<"xvmaxsp">; diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td index 1ac91fadf6582..94028d82c2011 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td +++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td @@ -53,36 +53,52 @@ let Predicates = [IsISAFuture] in { let Predicates = [HasVSX, IsISAFuture] in { let mayLoad = 1 in { - def LXVRL : XX1Form_memOp<31, 525, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB), - "lxvrl $XT, $RA, $RB", IIC_LdStLoad, []>; - - def LXVRLL : XX1Form_memOp<31, 557, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB), - "lxvrll $XT, $RA, $RB", IIC_LdStLoad, []>; - - def LXVPRL : XForm_XTp5_XAB5<31, 589, (outs vsrprc:$XTp), - (ins memr:$RA, g8rc:$RB), - "lxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>; - - def LXVPRLL : XForm_XTp5_XAB5<31, 621, (outs vsrprc:$XTp), - (ins memr:$RA, g8rc:$RB), - "lxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>; + def LXVRL + : XX1Form_memOp<31, 525, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB), + "lxvrl $XT, $RA, $RB", IIC_LdStLoad, []>; + def LXVRLL + : XX1Form_memOp<31, 557, (outs vsrc:$XT), (ins memr:$RA, g8rc:$RB), + "lxvrll $XT, $RA, $RB", IIC_LdStLoad, []>; + def LXVPRL + : XForm_XTp5_XAB5<31, 589, (outs vsrprc:$XTp), (ins memr:$RA, g8rc:$RB), + "lxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>; + def LXVPRLL + : XForm_XTp5_XAB5<31, 621, (outs vsrprc:$XTp), (ins memr:$RA, g8rc:$RB), + "lxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>; } let mayStore = 1 in { - def STXVRL : XX1Form_memOp<31, 653, (outs), - (ins vsrc:$XT, memr:$RA, g8rc:$RB), - "stxvrl $XT, $RA, $RB", IIC_LdStLoad, []>; - - def STXVRLL : XX1Form_memOp<31, 685, (outs), - (ins vsrc:$XT, memr:$RA, g8rc:$RB), - "stxvrll $XT, $RA, $RB", IIC_LdStLoad, []>; - + def STXVRL + : XX1Form_memOp<31, 653, (outs), (ins vsrc:$XT, memr:$RA, g8rc:$RB), + "stxvrl $XT, $RA, $RB", IIC_LdStLoad, []>; + def STXVRLL + : XX1Form_memOp<31, 685, (outs), (ins vsrc:$XT, memr:$RA, g8rc:$RB), + "stxvrll $XT, $RA, $RB", IIC_LdStLoad, []>; def STXVPRL : XForm_XTp5_XAB5<31, 717, (outs), (ins vsrprc:$XTp, memr:$RA, g8rc:$RB), "stxvprl $XTp, $RA, $RB", IIC_LdStLFD, []>; - def STXVPRLL : XForm_XTp5_XAB5<31, 749, (outs), (ins vsrprc:$XTp, memr:$RA, g8rc:$RB), "stxvprll $XTp, $RA, $RB", IIC_LdStLFD, []>; } } + +// Load/Store VSX Vector with Right Length Left-justified. +foreach Ty = [v4i32, v2i64] in { + def : Pat<(Ty (int_ppc_vsx_lxvrl addr:$RA, i64:$RB)), + (LXVRL memr:$RA, g8rc:$RB)>; + def : Pat<(Ty (int_ppc_vsx_lxvrll addr:$RA, i64:$RB)), + (LXVRLL $RA, $RB)>; + def : Pat<(int_ppc_vsx_stxvrl Ty:$XT, addr:$RA, i64:$RB), + (STXVRL $XT, $RA, $RB)>; + def : Pat<(int_ppc_vsx_stxvrll Ty:$XT, addr:$RA, i64:$RB), + (STXVRLL $XT, $RA, $RB)>; +} + +// Load/Store VSX Vector pair with Right Length Left-justified. +def : Pat<(v256i1(int_ppc_vsx_lxvprl addr:$RA, i64:$RB)), (LXVPRL $RA, $RB)>; +def : Pat<(v256i1(int_ppc_vsx_lxvprll addr:$RA, i64:$RB)), (LXVPRLL $RA, $RB)>; +def : Pat<(int_ppc_vsx_stxvprl v256i1:$XTp, addr:$RA, i64:$RB), + (STXVPRL $XTp, $RA, $RB)>; +def : Pat<(int_ppc_vsx_stxvprll v256i1:$XTp, addr:$RA, i64:$RB), + (STXVPRLL $XTp, $RA, $RB)>; diff --git a/llvm/test/CodeGen/PowerPC/vsx-ldst-with-length.ll b/llvm/test/CodeGen/PowerPC/vsx-ldst-with-length.ll new file mode 100644 index 0000000000000..2cbaf3c548d28 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/vsx-ldst-with-length.ll @@ -0,0 +1,150 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr -mcpu=future < %s | \ +; RUN: FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-ibm-aix-xcoff \ +; RUN: -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr -mcpu=future < %s | \ +; RUN: FileCheck %s + +; Test for load/store to/from v4i32. + +define <4 x i32> @testLXVRL(ptr %a, i64 %b) { +; CHECK-LABEL: testLXVRL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxvrl v2, r3, r4 +; CHECK-NEXT: blr +entry: + %0 = tail call <4 x i32> @llvm.ppc.vsx.lxvrl(ptr %a, i64 %b) + ret <4 x i32> %0 +} +declare <4 x i32> @llvm.ppc.vsx.lxvrl(ptr, i64) + +define <4 x i32> @testLXVRLL(ptr %a, i64 %b) { +; CHECK-LABEL: testLXVRLL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxvrll v2, r3, r4 +; CHECK-NEXT: blr +entry: + %0 = tail call <4 x i32> @llvm.ppc.vsx.lxvrll(ptr %a, i64 %b) + ret <4 x i32> %0 +} +declare <4 x i32> @llvm.ppc.vsx.lxvrll(ptr, i64) + +define void @testSTXVRL(<4 x i32> %a, ptr %b, i64 %c) { +; CHECK-LABEL: testSTXVRL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stxvrl v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]] +; CHECK: blr +entry: + tail call void @llvm.ppc.vsx.stxvrl(<4 x i32> %a, ptr %b, i64 %c) + ret void +} +declare void @llvm.ppc.vsx.stxvrl(<4 x i32>, ptr, i64) + +define void @testSTXVRLL(<4 x i32> %a, ptr %b, i64 %c) { +; CHECK-LABEL: testSTXVRLL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stxvrll v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]] +; CHECK: blr +entry: + tail call void @llvm.ppc.vsx.stxvrll(<4 x i32> %a, ptr %b, i64 %c) + ret void +} +declare void @llvm.ppc.vsx.stxvrll(<4 x i32>, ptr, i64) + +; Test for load/store to/from v2i64. + +define <2 x i64> @testLXVRL2(ptr %a, i64 %b) { +; CHECK-LABEL: testLXVRL2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxvrl v2, r3, r4 +; CHECK-NEXT: blr +entry: + %0 = tail call <2 x i64> @llvm.ppc.vsx.lxvrl.v2i64(ptr %a, i64 %b) + ret <2 x i64> %0 +} +declare <2 x i64> @llvm.ppc.vsx.lxvrl.v2i64(ptr, i64) + +define <2 x i64> @testLXVRLL2(ptr %a, i64 %b) { +; CHECK-LABEL: testLXVRLL2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxvrll v2, r3, r4 +; CHECK-NEXT: blr +entry: + %0 = tail call <2 x i64> @llvm.ppc.vsx.lxvrll.v2i64(ptr %a, i64 %b) + ret <2 x i64> %0 +} +declare <2 x i64> @llvm.ppc.vsx.lxvrll.v2i64(ptr, i64) + +define void @testSTXVRL2(<2 x i64> %a, ptr %b, i64 %c) { +; CHECK-LABEL: testSTXVRL2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stxvrl v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]] +; CHECK: blr +entry: + tail call void @llvm.ppc.vsx.stxvrl.v2i64(<2 x i64> %a, ptr %b, i64 %c) + ret void +} +declare void @llvm.ppc.vsx.stxvrl.v2i64(<2 x i64>, ptr, i64) + +define void @testSTXVRLL2(<2 x i64> %a, ptr %b, i64 %c) { +; CHECK-LABEL: testSTXVRLL2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: stxvrll v2, [[REG:r[0-9]+]], [[REG1:r[0-9]+]] +; CHECK: blr +entry: + tail call void @llvm.ppc.vsx.stxvrll.v2i64(<2 x i64> %a, ptr %b, i64 %c) + ret void +} +declare void @llvm.ppc.vsx.stxvrll.v2i64(<2 x i64>, ptr, i64) + +; Test for load/store vectore pair. + +define <256 x i1> @testLXVPRL(ptr %vpp, i64 %b) { +; CHECK-LABEL: testLXVPRL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxvprl vsp34, r4, r5 +; CHECK: blr +entry: + %0 = tail call <256 x i1> @llvm.ppc.vsx.lxvprl(ptr %vpp, i64 %b) + ret <256 x i1> %0 +} +declare <256 x i1> @llvm.ppc.vsx.lxvprl(ptr, i64) + +define <256 x i1> @testLXVPRLL(ptr %vpp, i64 %b) { +; CHECK-LABEL: testLXVPRLL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxvprll vsp34, r4, r5 +; CHECK: blr +entry: + %0 = tail call <256 x i1> @llvm.ppc.vsx.lxvprll(ptr %vpp, i64 %b) + ret <256 x i1> %0 +} +declare <256 x i1> @llvm.ppc.vsx.lxvprll(ptr, i64) + +define void @testSTXVPRL(ptr %v, ptr %vp, i64 %len) { +; CHECK-LABEL: testSTXVPRL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxv v2 +; CHECK-NEXT: lxv v3 +; CHECK-NEXT: stxvprl vsp34, r4, r5 +; CHECK-NEXT: blr +entry: + %0 = load <256 x i1>, ptr %v, align 32 + tail call void @llvm.ppc.vsx.stxvprl(<256 x i1> %0, ptr %vp, i64 %len) + ret void +} +declare void @llvm.ppc.vsx.stxvprl(<256 x i1>, ptr, i64) + +define void @testSTXVPRLL(ptr %v, ptr %vp, i64 %len) { +; CHECK-LABEL: testSTXVPRLL: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lxv v2 +; CHECK-NEXT: lxv v3 +; CHECK-NEXT: stxvprll vsp34, r4, r5 +; CHECK-NEXT: blr +entry: + %0 = load <256 x i1>, ptr %v, align 32 + tail call void @llvm.ppc.vsx.stxvprll(<256 x i1> %0, ptr %vp, i64 %len) + ret void +} +declare void @llvm.ppc.vsx.stxvprll(<256 x i1>, ptr, i64)