From c630ca1f5c0935f2658982d4fe87753b34d17abe Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Wed, 12 Aug 2020 09:23:05 -0500 Subject: [PATCH] [PowerPC] Implement Vector Extract Mask builtins in LLVM/Clang This patch implements the vec_extractm function prototypes in altivec.h in order to utilize the vector extract with mask instructions introduced in Power10. Differential Revision: https://reviews.llvm.org/D82675 --- include/llvm/IR/IntrinsicsPowerPC.td | 12 ++++ lib/Target/PowerPC/PPCInstrPrefix.td | 15 +++-- test/CodeGen/PowerPC/p10-vector-mask-ops.ll | 66 +++++++++++++++++++++ 3 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/PowerPC/p10-vector-mask-ops.ll diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index ae25bb400e4..ce4c98968a7 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/include/llvm/IR/IntrinsicsPowerPC.td @@ -434,6 +434,18 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". def int_ppc_altivec_vprtybq : GCCBuiltin<"__builtin_altivec_vprtybq">, Intrinsic<[llvm_v1i128_ty],[llvm_v1i128_ty],[IntrNoMem]>; + // P10 Vector Extract with Mask + def int_ppc_altivec_vextractbm : GCCBuiltin<"__builtin_altivec_vextractbm">, + Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>; + def int_ppc_altivec_vextracthm : GCCBuiltin<"__builtin_altivec_vextracthm">, + Intrinsic<[llvm_i32_ty], [llvm_v8i16_ty], [IntrNoMem]>; + def int_ppc_altivec_vextractwm : GCCBuiltin<"__builtin_altivec_vextractwm">, + Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty], [IntrNoMem]>; + def int_ppc_altivec_vextractdm : GCCBuiltin<"__builtin_altivec_vextractdm">, + Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty], [IntrNoMem]>; + def int_ppc_altivec_vextractqm : GCCBuiltin<"__builtin_altivec_vextractqm">, + Intrinsic<[llvm_i32_ty], [llvm_v1i128_ty], [IntrNoMem]>; + // P10 Vector Parallel Bits Deposit/Extract Doubleword Builtins. def int_ppc_altivec_vpdepd : GCCBuiltin<"__builtin_altivec_vpdepd">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], diff --git a/lib/Target/PowerPC/PPCInstrPrefix.td b/lib/Target/PowerPC/PPCInstrPrefix.td index e86e7828c07..5bd16324751 100644 --- a/lib/Target/PowerPC/PPCInstrPrefix.td +++ b/lib/Target/PowerPC/PPCInstrPrefix.td @@ -965,19 +965,24 @@ let Predicates = [IsISA3_1] in { RegConstraint<"$vDi = $vD">, NoEncode<"$vDi">; def VEXTRACTBM : VXForm_RD5_XO5_RS5<1602, 8, (outs gprc:$rD), (ins vrrc:$vB), "vextractbm $rD, $vB", IIC_VecGeneral, - []>; + [(set i32:$rD, + (int_ppc_altivec_vextractbm v16i8:$vB))]>; def VEXTRACTHM : VXForm_RD5_XO5_RS5<1602, 9, (outs gprc:$rD), (ins vrrc:$vB), "vextracthm $rD, $vB", IIC_VecGeneral, - []>; + [(set i32:$rD, + (int_ppc_altivec_vextracthm v8i16:$vB))]>; def VEXTRACTWM : VXForm_RD5_XO5_RS5<1602, 10, (outs gprc:$rD), (ins vrrc:$vB), "vextractwm $rD, $vB", IIC_VecGeneral, - []>; + [(set i32:$rD, + (int_ppc_altivec_vextractwm v4i32:$vB))]>; def VEXTRACTDM : VXForm_RD5_XO5_RS5<1602, 11, (outs gprc:$rD), (ins vrrc:$vB), "vextractdm $rD, $vB", IIC_VecGeneral, - []>; + [(set i32:$rD, + (int_ppc_altivec_vextractdm v2i64:$vB))]>; def VEXTRACTQM : VXForm_RD5_XO5_RS5<1602, 12, (outs gprc:$rD), (ins vrrc:$vB), "vextractqm $rD, $vB", IIC_VecGeneral, - []>; + [(set i32:$rD, + (int_ppc_altivec_vextractqm v1i128:$vB))]>; def VEXPANDBM : VXForm_RD5_XO5_RS5<1602, 0, (outs vrrc:$vD), (ins vrrc:$vB), "vexpandbm $vD, $vB", IIC_VecGeneral, []>; diff --git a/test/CodeGen/PowerPC/p10-vector-mask-ops.ll b/test/CodeGen/PowerPC/p10-vector-mask-ops.ll new file mode 100644 index 00000000000..2b1cf27c20e --- /dev/null +++ b/test/CodeGen/PowerPC/p10-vector-mask-ops.ll @@ -0,0 +1,66 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \ +; RUN: FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \ +; RUN: FileCheck %s + +; This test case aims to test the vector mask manipulation operations +; on Power10. + +declare i32 @llvm.ppc.altivec.vextractbm(<16 x i8>) +declare i32 @llvm.ppc.altivec.vextracthm(<8 x i16>) +declare i32 @llvm.ppc.altivec.vextractwm(<4 x i32>) +declare i32 @llvm.ppc.altivec.vextractdm(<2 x i64>) +declare i32 @llvm.ppc.altivec.vextractqm(<1 x i128>) + +define i32 @test_vextractbm(<16 x i8> %a) { +; CHECK-LABEL: test_vextractbm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vextractbm r3, v2 +; CHECK-NEXT: blr +entry: + %ext = tail call i32 @llvm.ppc.altivec.vextractbm(<16 x i8> %a) + ret i32 %ext +} + +define i32 @test_vextracthm(<8 x i16> %a) { +; CHECK-LABEL: test_vextracthm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vextracthm r3, v2 +; CHECK-NEXT: blr +entry: + %ext = tail call i32 @llvm.ppc.altivec.vextracthm(<8 x i16> %a) + ret i32 %ext +} + +define i32 @test_vextractwm(<4 x i32> %a) { +; CHECK-LABEL: test_vextractwm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vextractwm r3, v2 +; CHECK-NEXT: blr +entry: + %ext = tail call i32 @llvm.ppc.altivec.vextractwm(<4 x i32> %a) + ret i32 %ext +} + +define i32 @test_vextractdm(<2 x i64> %a) { +; CHECK-LABEL: test_vextractdm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vextractdm r3, v2 +; CHECK-NEXT: blr +entry: + %ext = tail call i32 @llvm.ppc.altivec.vextractdm(<2 x i64> %a) + ret i32 %ext +} + +define i32 @test_vextractqm(<1 x i128> %a) { +; CHECK-LABEL: test_vextractqm: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vextractqm r3, v2 +; CHECK-NEXT: blr +entry: + %ext = tail call i32 @llvm.ppc.altivec.vextractqm(<1 x i128> %a) + ret i32 %ext +}