diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 30077e2e8d03..238e56b6dfce 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -302,6 +302,10 @@ BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "") +// P10 Vector Clear Bytes built-ins. +BUILTIN(__builtin_altivec_vclrlb, "V16cV16cUi", "") +BUILTIN(__builtin_altivec_vclrrb, "V16cV16cUi", "") + // VSX built-ins. BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "") diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 1e1e57cd1ffc..385828aceced 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -16776,6 +16776,46 @@ static __inline__ vector unsigned long long __ATTRS_o_ai vec_pext(vector unsigned long long __a, vector unsigned long long __b) { return __builtin_altivec_vpextd(__a, __b); } + +/* vec_clrl */ + +static __inline__ vector signed char __ATTRS_o_ai +vec_clrl(vector signed char __a, unsigned int __n) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vclrrb(__a, __n); +#else + return __builtin_altivec_vclrlb( __a, __n); +#endif +} + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_clrl(vector unsigned char __a, unsigned int __n) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vclrrb((vector signed char)__a, __n); +#else + return __builtin_altivec_vclrlb((vector signed char)__a, __n); +#endif +} + +/* vec_clrr */ + +static __inline__ vector signed char __ATTRS_o_ai +vec_clrr(vector signed char __a, unsigned int __n) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vclrlb(__a, __n); +#else + return __builtin_altivec_vclrrb( __a, __n); +#endif +} + +static __inline__ vector unsigned char __ATTRS_o_ai +vec_clrr(vector unsigned char __a, unsigned int __n) { +#ifdef __LITTLE_ENDIAN__ + return __builtin_altivec_vclrlb((vector signed char)__a, __n); +#else + return __builtin_altivec_vclrrb((vector signed char)__a, __n); +#endif +} #endif /* __POWER10_VECTOR__ */ #undef __ATTRS_o_ai diff --git a/clang/test/CodeGen/builtins-ppc-p10vector.c b/clang/test/CodeGen/builtins-ppc-p10vector.c index 31c24f382f1e..829ef97435eb 100644 --- a/clang/test/CodeGen/builtins-ppc-p10vector.c +++ b/clang/test/CodeGen/builtins-ppc-p10vector.c @@ -5,7 +5,10 @@ #include +vector signed char vsca; +vector unsigned char vuca; vector unsigned long long vulla, vullb; +unsigned int uia; vector unsigned long long test_vpdepd(void) { // CHECK: @llvm.ppc.altivec.vpdepd(<2 x i64> @@ -18,3 +21,35 @@ vector unsigned long long test_vpextd(void) { // CHECK-NEXT: ret <2 x i64> return vec_pext(vulla, vullb); } + +vector signed char test_vec_vclrl_sc(void) { + // CHECK-BE: @llvm.ppc.altivec.vclrlb(<16 x i8> + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vclrrb(<16 x i8> + // CHECK-LE-NEXT: ret <16 x i8> + return vec_clrl(vsca, uia); +} + +vector unsigned char test_vec_clrl_uc(void) { + // CHECK-BE: @llvm.ppc.altivec.vclrlb(<16 x i8> + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vclrrb(<16 x i8> + // CHECK-LE-NEXT: ret <16 x i8> + return vec_clrl(vuca, uia); +} + +vector signed char test_vec_vclrr_sc(void) { + // CHECK-BE: @llvm.ppc.altivec.vclrrb(<16 x i8> + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vclrlb(<16 x i8> + // CHECK-LE-NEXT: ret <16 x i8> + return vec_clrr(vsca, uia); +} + +vector unsigned char test_vec_clrr_uc(void) { + // CHECK-BE: @llvm.ppc.altivec.vclrrb(<16 x i8> + // CHECK-BE-NEXT: ret <16 x i8> + // CHECK-LE: @llvm.ppc.altivec.vclrlb(<16 x i8> + // CHECK-LE-NEXT: ret <16 x i8> + return vec_clrr(vuca, uia); +} diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td index 79a3221f0141..2ca77d90e13c 100644 --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -417,6 +417,14 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.". def int_ppc_altivec_vpextd : GCCBuiltin<"__builtin_altivec_vpextd">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>; + + // P10 Vector Clear Bytes + def int_ppc_altivec_vclrlb : GCCBuiltin<"__builtin_altivec_vclrlb">, + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_ppc_altivec_vclrrb : GCCBuiltin<"__builtin_altivec_vclrrb">, + Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], + [IntrNoMem]>; } // Vector average. diff --git a/llvm/lib/Target/PowerPC/PPCInstrPrefix.td b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td index a90cba09c619..31fe57150bff 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrPrefix.td +++ b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td @@ -516,4 +516,12 @@ let Predicates = [IsISA3_1] in { def PEXTD : XForm_6<31, 188, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB), "pextd $rA, $rS, $rB", IIC_IntGeneral, [(set i64:$rA, (int_ppc_pextd i64:$rS, i64:$rB))]>; + def VCLRLB : VXForm_1<397, (outs vrrc:$vD), (ins vrrc:$vA, gprc:$rB), + "vclrlb $vD, $vA, $rB", IIC_VecGeneral, + [(set v16i8:$vD, + (int_ppc_altivec_vclrlb v16i8:$vA, i32:$rB))]>; + def VCLRRB : VXForm_1<461, (outs vrrc:$vD), (ins vrrc:$vA, gprc:$rB), + "vclrrb $vD, $vA, $rB", IIC_VecGeneral, + [(set v16i8:$vD, + (int_ppc_altivec_vclrrb v16i8:$vA, i32:$rB))]>; } diff --git a/llvm/test/CodeGen/PowerPC/p10-string-ops.ll b/llvm/test/CodeGen/PowerPC/p10-string-ops.ll new file mode 100644 index 000000000000..d89045cc0200 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/p10-string-ops.ll @@ -0,0 +1,29 @@ +; 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 + +; These test cases aim to test the vector string isolate builtins on Power10. + +declare <16 x i8> @llvm.ppc.altivec.vclrlb(<16 x i8>, i32) +declare <16 x i8> @llvm.ppc.altivec.vclrrb(<16 x i8>, i32) + +define <16 x i8> @test_vclrlb(<16 x i8> %a, i32 %n) { +; CHECK-LABEL: test_vclrlb: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vclrlb v2, v2, r5 +; CHECK-NEXT: blr +entry: + %tmp = tail call <16 x i8> @llvm.ppc.altivec.vclrlb(<16 x i8> %a, i32 %n) + ret <16 x i8> %tmp +} + +define <16 x i8> @test_vclrrb(<16 x i8> %a, i32 %n) { +; CHECK-LABEL: test_vclrrb: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vclrrb v2, v2, r5 +; CHECK-NEXT: blr +entry: + %tmp = tail call <16 x i8> @llvm.ppc.altivec.vclrrb(<16 x i8> %a, i32 %n) + ret <16 x i8> %tmp +} diff --git a/llvm/test/MC/Disassembler/PowerPC/p10insts.txt b/llvm/test/MC/Disassembler/PowerPC/p10insts.txt index ac95e30fbde5..bd83c5daca1f 100644 --- a/llvm/test/MC/Disassembler/PowerPC/p10insts.txt +++ b/llvm/test/MC/Disassembler/PowerPC/p10insts.txt @@ -12,3 +12,9 @@ # CHECK: pextd 1, 2, 4 0x7c 0x41 0x21 0x78 + +# CHECK: vclrlb 1, 4, 3 +0x10 0x24 0x19 0x8d + +# CHECK: vclrrb 1, 4, 3 +0x10 0x24 0x19 0xcd diff --git a/llvm/test/MC/PowerPC/p10.s b/llvm/test/MC/PowerPC/p10.s index d2b399c531b4..29a11c8756eb 100644 --- a/llvm/test/MC/PowerPC/p10.s +++ b/llvm/test/MC/PowerPC/p10.s @@ -15,3 +15,9 @@ # CHECK-BE: pextd 1, 2, 4 # encoding: [0x7c,0x41,0x21,0x78] # CHECK-LE: pextd 1, 2, 4 # encoding: [0x78,0x21,0x41,0x7c] pextd 1, 2, 4 +# CHECK-BE: vclrlb 1, 4, 3 # encoding: [0x10,0x24,0x19,0x8d] +# CHECK-LE: vclrlb 1, 4, 3 # encoding: [0x8d,0x19,0x24,0x10] + vclrlb 1, 4, 3 +# CHECK-BE: vclrrb 1, 4, 3 # encoding: [0x10,0x24,0x19,0xcd] +# CHECK-LE: vclrrb 1, 4, 3 # encoding: [0xcd,0x19,0x24,0x10] + vclrrb 1, 4, 3