-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[PowerPC] Support for Packed BCD conversion builtins #142723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-clang-codegen Author: None (Himadhith) ChangesSupport the following packed BCD builtins for PowerPC.
Design decision considered:
Prototypes:
The condition for the 2nd parameter is consistent over all the 3 prototypes (0 or 1 only).
Reference links: Full diff: https://github.com/llvm/llvm-project/pull/142723.diff 10 Files Affected:
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793e..0c8c7d3d1df13 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -567,6 +567,13 @@ TARGET_BUILTIN(__builtin_altivec_vextsh2w, "V4SiV8Ss", "", "power9-vector")
TARGET_BUILTIN(__builtin_altivec_vextsh2d, "V2SLLiV8Ss", "", "power9-vector")
TARGET_BUILTIN(__builtin_altivec_vextsw2d, "V2SLLiV4Si", "", "power9-vector")
+// P9 BCD builtins (the signature used here is for informational purposes only
+// as front-end emits custom codegens for these set of builtins.)
+TARGET_BUILTIN(__builtin_ppc_national2packed, "V16UcV16UcUc", "t", "power9-vector")
+TARGET_BUILTIN(__builtin_ppc_packed2national, "V16UcV16Uc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_ppc_packed2zoned, "V16UcV16UcUc", "t", "power9-vector")
+TARGET_BUILTIN(__builtin_ppc_zoned2packed, "V16UcV16UcUc", "t", "power9-vector")
+
// P10 Vector extend sign builtins.
TARGET_BUILTIN(__builtin_altivec_vextsd2q, "V1SLLLiV2SLLi", "",
"power10-vector")
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index e6ef0ecc526ba..1c3a49dd7d126 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -88,6 +88,12 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
}
static void defineXLCompatMacros(MacroBuilder &Builder) {
+ Builder.defineMacro("__builtin_national2packed",
+ "__builtin_ppc_national2packed");
+ Builder.defineMacro("__builtin_packed2national",
+ "__builtin_ppc_packed2national");
+ Builder.defineMacro("__builtin_packed2zoned", "__builtin_ppc_packed2zoned");
+ Builder.defineMacro("__builtin_zoned2packed", "__builtin_ppc_zoned2packed");
Builder.defineMacro("__cdtbcd", "__builtin_ppc_cdtbcd");
Builder.defineMacro("__cbcdtd", "__builtin_ppc_cbcdtd");
Builder.defineMacro("__addg6s", "__builtin_ppc_addg6s");
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index f9890285f0aab..7209b82372d4a 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -294,6 +294,34 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, Ops, "");
}
+ // BCD convert builtins for P9
+ case PPC::BI__builtin_ppc_national2packed:
+ case PPC::BI__builtin_ppc_packed2zoned:
+ case PPC::BI__builtin_ppc_zoned2packed: {
+ SmallVector<Value *, 3> Ops;
+ // Zero extending unsigned char to 32 bits by using Int32ty
+ llvm::Type *Int32Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+ Ops.push_back(EmitScalarExpr(E->getArg(0)));
+ Ops.push_back(EmitScalarExpr(E->getArg(1)));
+ Ops.push_back(Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(2)),
+ Int32Ty, "zext_mode"));
+
+ switch (BuiltinID) {
+ default:
+ llvm_unreachable("Unsupported BCD convert intrinsic!");
+ case PPC::BI__builtin_ppc_national2packed:
+ ID = Intrinsic::ppc_national2packed;
+ break;
+ case PPC::BI__builtin_ppc_packed2zoned:
+ ID = Intrinsic::ppc_packed2zoned;
+ break;
+ case PPC::BI__builtin_ppc_zoned2packed:
+ ID = Intrinsic::ppc_zoned2packed;
+ break;
+ }
+ return Builder.CreateIntrinsic(ID, Ops);
+ }
+
// vec_st, vec_xst_be
case PPC::BI__builtin_altivec_stvx:
case PPC::BI__builtin_altivec_stvxl:
diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp
index 9b4d82745f881..d5c83aedb3008 100644
--- a/clang/lib/Sema/SemaPPC.cpp
+++ b/clang/lib/Sema/SemaPPC.cpp
@@ -106,6 +106,10 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
switch (BuiltinID) {
default:
return false;
+ case PPC::BI__builtin_ppc_national2packed:
+ case PPC::BI__builtin_ppc_packed2zoned:
+ case PPC::BI__builtin_ppc_zoned2packed:
+ return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
case PPC::BI__builtin_altivec_crypto_vshasigmaw:
case PPC::BI__builtin_altivec_crypto_vshasigmad:
return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
diff --git a/clang/test/CodeGen/PowerPC/builtins-bcd-transform-negative.c b/clang/test/CodeGen/PowerPC/builtins-bcd-transform-negative.c
new file mode 100644
index 0000000000000..f76e0abed103e
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/builtins-bcd-transform-negative.c
@@ -0,0 +1,23 @@
+// Testfile for negative condition for BCD builtins national2packed, packed2zoned and zoned2packed.
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc64le-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+// CHECK: builtins-bcd-transform-negative.c:12:12: error: argument value 2 is outside the valid range [0, 1]
+vector unsigned char tBcd_National2packed_imm2(vector unsigned char a) {
+ return __builtin_ppc_national2packed (a,'\2');
+}
+
+// CHECK: builtins-bcd-transform-negative.c:17:12: error: argument value 2 is outside the valid range [0, 1]
+vector unsigned char tBcd_Packed2zoned_imm2(vector unsigned char a) {
+ return __builtin_ppc_packed2zoned (a,'\2');
+}
+
+// CHECK: builtins-bcd-transform-negative.c:22:12: error: argument value 2 is outside the valid range [0, 1]
+vector unsigned char tBcd_Zoned2packed_imm2(vector unsigned char a) {
+ return __builtin_ppc_zoned2packed (a,'\2');
+}
\ No newline at end of file
diff --git a/clang/test/CodeGen/PowerPC/builtins-bcd-transform.c b/clang/test/CodeGen/PowerPC/builtins-bcd-transform.c
new file mode 100644
index 0000000000000..025dcbce58118
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/builtins-bcd-transform.c
@@ -0,0 +1,57 @@
+// Testfile that verifies positive cases (0 or 1 only) for BCD builtins national2packed, packed2zoned and zoned2packed.
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: tBcd_National2packed_imm1
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 1)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_National2packed_imm1(vector unsigned char a) {
+ return __builtin_ppc_national2packed (a,'\1');
+}
+
+// CHECK-LABEL: tBcd_National2packed_imm0
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_National2packed_imm0(vector unsigned char a) {
+ return __builtin_ppc_national2packed (a,'\0');
+}
+
+// CHECK-LABEL: tBcd_Packed2national
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2national(<16 x i8> %a)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Packed2national(vector unsigned char a){
+ return __builtin_ppc_packed2national(a);
+}
+
+// CHECK-LABEL: tBcd_Packed2zoned_imm0
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Packed2zoned_imm0(vector unsigned char a){
+ return __builtin_ppc_packed2zoned(a,'\0');
+}
+
+// CHECK-LABEL: tBcd_Packed2zoned_imm1
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 1)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Packed2zoned_imm1(vector unsigned char a){
+ return __builtin_ppc_packed2zoned(a,'\1');
+}
+
+// CHECK-LABEL: tBcd_Zoned2packed_imm0
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Zoned2packed_imm0(vector unsigned char a){
+ return __builtin_ppc_zoned2packed(a,'\0');
+}
+
+// CHECK-LABEL: tBcd_Zoned2packed_imm1
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 1)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Zoned2packed_imm1(vector unsigned char a){
+ return __builtin_ppc_zoned2packed(a,'\1');
+}
\ No newline at end of file
diff --git a/clang/test/Sema/builtins-bcd-transform.c b/clang/test/Sema/builtins-bcd-transform.c
new file mode 100644
index 0000000000000..103a6be6452b5
--- /dev/null
+++ b/clang/test/Sema/builtins-bcd-transform.c
@@ -0,0 +1,30 @@
+// Testfile to verify the semantics and the error handling for BCD builtins national2packed, packed2zoned and zoned2packed.
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64-unknown-unknown -fsyntax-only -verify %s
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64le-unknown-unknown -fsyntax-only -verify %s
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc-unknown-unknown -fsyntax-only -verify %s
+
+#include <altivec.h>
+vector unsigned char test_national2packed(void)
+{
+ vector unsigned char a = {1,2,3,4};
+ vector unsigned char res_a = __builtin_ppc_national2packed(a, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ vector unsigned char res_b = __builtin_ppc_national2packed(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ return __builtin_ppc_national2packed(a, 0);
+}
+
+vector unsigned char test_packed2zoned(void)
+{
+ vector unsigned char a = {1,2,3,4};
+ vector unsigned char res_a = __builtin_ppc_packed2zoned(a,2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ vector unsigned char res_b = __builtin_ppc_packed2zoned(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ return __builtin_ppc_packed2zoned(a,1);
+}
+
+vector unsigned char test_zoned2packed(void)
+{
+ vector unsigned char a = {1,2,3,4};
+ vector unsigned char res_a = __builtin_ppc_zoned2packed(a,2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ vector unsigned char res_b = __builtin_ppc_zoned2packed(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ return __builtin_ppc_zoned2packed(a,0);
+}
\ No newline at end of file
diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 751628cee58c0..6ae0cf40d6120 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -655,6 +655,14 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
DefaultAttrsIntrinsic<[llvm_v1i128_ty],[llvm_v1i128_ty],[IntrNoMem]>;
// BCD intrinsics.
+ def int_ppc_national2packed: ClangBuiltin<"__builtin_ppc_national2packed">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_packed2national: ClangBuiltin<"__builtin_ppc_packed2national">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_packed2zoned: ClangBuiltin<"__builtin_ppc_packed2zoned">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_zoned2packed: ClangBuiltin<"__builtin_ppc_zoned2packed">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_cdtbcdd : ClangBuiltin<"__builtin_ppc_cdtbcd">,
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
def int_ppc_cbcdtdd: ClangBuiltin<"__builtin_ppc_cbcdtd">,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
index 386c94a324996..9a54e070629b7 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -1617,10 +1617,14 @@ class VX_VT5_EO5_VB5_XO9_o<bits<5> eo, bits<9> xo, string opc,
}
// Decimal Convert From/to National/Zoned/Signed-QWord
-def BCDCFN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<7, 385, "bcdcfn." , []>;
-def BCDCFZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<6, 385, "bcdcfz." , []>;
-def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." , []>;
-def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." , []>;
+def BCDCFN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<7, 385, "bcdcfn." ,
+ [(set v16i8:$VD, (int_ppc_national2packed v16i8:$VB, i32:$PS))]>;
+def BCDCFZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<6, 385, "bcdcfz." ,
+ [(set v16i8:$VD, (int_ppc_zoned2packed v16i8:$VB, i32:$PS))]>;
+def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." ,
+ [(set v16i8:$VD, (int_ppc_packed2national v16i8:$VB))]>;
+def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." ,
+ [(set v16i8:$VD, (int_ppc_packed2zoned v16i8:$VB, i32:$PS))]>;
def BCDCFSQ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<2, 385, "bcdcfsq.", []>;
def BCDCTSQ_rec : VX_VT5_EO5_VB5_XO9_o <0, 385, "bcdctsq.", []>;
diff --git a/llvm/test/CodeGen/PowerPC/builtins-bcd-transform.ll b/llvm/test/CodeGen/PowerPC/builtins-bcd-transform.ll
new file mode 100644
index 0000000000000..deb4656fcc718
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-bcd-transform.ll
@@ -0,0 +1,96 @@
+; Testfile that verifies positive case (0 or 1 only) for BCD builtins national2packed, packed2zoned and zoned2packed.
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; CHECK-LABEL: tBcd_National2packed_imm0
+; CHECK: bcdcfn. v2, v2, 0
+; CHECK-NEXT: blr
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.national2packed(<16 x i8>, i32 immarg)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <16 x i8> @tBcd_National2packed_imm0(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 0)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_National2packed_imm1
+; CHECK: bcdcfn. v2, v2, 1
+; CHECK-NEXT: blr
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <16 x i8> @tBcd_National2packed_imm1(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 1)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Packed2national
+; CHECK: bcdctn. v2, v2
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.packed2national(<16 x i8>)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <16 x i8> @tBcd_Packed2national(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.packed2national(<16 x i8> %a)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Packed2zoned_imm0
+; CHECK: bcdctz. v2, v2, 0
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.packed2zoned(<16 x i8>, i32 immarg)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Packed2zoned_imm0(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 0)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Packed2zoned_imm1
+; CHECK: bcdctz. v2, v2, 1
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Packed2zoned_imm1(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 1)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Zoned2packed_imm0
+; CHECK: bcdcfz. v2, v2, 0
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.zoned2packed(<16 x i8>, i32 immarg)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Zoned2packed_imm0(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 0)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Zoned2packed_imm1
+; CHECK: bcdcfz. v2, v2, 1
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Zoned2packed_imm1(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 1)
+ ret <16 x i8> %0
+}
\ No newline at end of file
|
@llvm/pr-subscribers-clang Author: None (Himadhith) ChangesSupport the following packed BCD builtins for PowerPC.
Design decision considered:
Prototypes:
The condition for the 2nd parameter is consistent over all the 3 prototypes (0 or 1 only).
Reference links: Full diff: https://github.com/llvm/llvm-project/pull/142723.diff 10 Files Affected:
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793e..0c8c7d3d1df13 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -567,6 +567,13 @@ TARGET_BUILTIN(__builtin_altivec_vextsh2w, "V4SiV8Ss", "", "power9-vector")
TARGET_BUILTIN(__builtin_altivec_vextsh2d, "V2SLLiV8Ss", "", "power9-vector")
TARGET_BUILTIN(__builtin_altivec_vextsw2d, "V2SLLiV4Si", "", "power9-vector")
+// P9 BCD builtins (the signature used here is for informational purposes only
+// as front-end emits custom codegens for these set of builtins.)
+TARGET_BUILTIN(__builtin_ppc_national2packed, "V16UcV16UcUc", "t", "power9-vector")
+TARGET_BUILTIN(__builtin_ppc_packed2national, "V16UcV16Uc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_ppc_packed2zoned, "V16UcV16UcUc", "t", "power9-vector")
+TARGET_BUILTIN(__builtin_ppc_zoned2packed, "V16UcV16UcUc", "t", "power9-vector")
+
// P10 Vector extend sign builtins.
TARGET_BUILTIN(__builtin_altivec_vextsd2q, "V1SLLLiV2SLLi", "",
"power10-vector")
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index e6ef0ecc526ba..1c3a49dd7d126 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -88,6 +88,12 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
}
static void defineXLCompatMacros(MacroBuilder &Builder) {
+ Builder.defineMacro("__builtin_national2packed",
+ "__builtin_ppc_national2packed");
+ Builder.defineMacro("__builtin_packed2national",
+ "__builtin_ppc_packed2national");
+ Builder.defineMacro("__builtin_packed2zoned", "__builtin_ppc_packed2zoned");
+ Builder.defineMacro("__builtin_zoned2packed", "__builtin_ppc_zoned2packed");
Builder.defineMacro("__cdtbcd", "__builtin_ppc_cdtbcd");
Builder.defineMacro("__cbcdtd", "__builtin_ppc_cbcdtd");
Builder.defineMacro("__addg6s", "__builtin_ppc_addg6s");
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index f9890285f0aab..7209b82372d4a 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -294,6 +294,34 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, Ops, "");
}
+ // BCD convert builtins for P9
+ case PPC::BI__builtin_ppc_national2packed:
+ case PPC::BI__builtin_ppc_packed2zoned:
+ case PPC::BI__builtin_ppc_zoned2packed: {
+ SmallVector<Value *, 3> Ops;
+ // Zero extending unsigned char to 32 bits by using Int32ty
+ llvm::Type *Int32Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+ Ops.push_back(EmitScalarExpr(E->getArg(0)));
+ Ops.push_back(EmitScalarExpr(E->getArg(1)));
+ Ops.push_back(Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(2)),
+ Int32Ty, "zext_mode"));
+
+ switch (BuiltinID) {
+ default:
+ llvm_unreachable("Unsupported BCD convert intrinsic!");
+ case PPC::BI__builtin_ppc_national2packed:
+ ID = Intrinsic::ppc_national2packed;
+ break;
+ case PPC::BI__builtin_ppc_packed2zoned:
+ ID = Intrinsic::ppc_packed2zoned;
+ break;
+ case PPC::BI__builtin_ppc_zoned2packed:
+ ID = Intrinsic::ppc_zoned2packed;
+ break;
+ }
+ return Builder.CreateIntrinsic(ID, Ops);
+ }
+
// vec_st, vec_xst_be
case PPC::BI__builtin_altivec_stvx:
case PPC::BI__builtin_altivec_stvxl:
diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp
index 9b4d82745f881..d5c83aedb3008 100644
--- a/clang/lib/Sema/SemaPPC.cpp
+++ b/clang/lib/Sema/SemaPPC.cpp
@@ -106,6 +106,10 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
switch (BuiltinID) {
default:
return false;
+ case PPC::BI__builtin_ppc_national2packed:
+ case PPC::BI__builtin_ppc_packed2zoned:
+ case PPC::BI__builtin_ppc_zoned2packed:
+ return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
case PPC::BI__builtin_altivec_crypto_vshasigmaw:
case PPC::BI__builtin_altivec_crypto_vshasigmad:
return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
diff --git a/clang/test/CodeGen/PowerPC/builtins-bcd-transform-negative.c b/clang/test/CodeGen/PowerPC/builtins-bcd-transform-negative.c
new file mode 100644
index 0000000000000..f76e0abed103e
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/builtins-bcd-transform-negative.c
@@ -0,0 +1,23 @@
+// Testfile for negative condition for BCD builtins national2packed, packed2zoned and zoned2packed.
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc64le-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+// CHECK: builtins-bcd-transform-negative.c:12:12: error: argument value 2 is outside the valid range [0, 1]
+vector unsigned char tBcd_National2packed_imm2(vector unsigned char a) {
+ return __builtin_ppc_national2packed (a,'\2');
+}
+
+// CHECK: builtins-bcd-transform-negative.c:17:12: error: argument value 2 is outside the valid range [0, 1]
+vector unsigned char tBcd_Packed2zoned_imm2(vector unsigned char a) {
+ return __builtin_ppc_packed2zoned (a,'\2');
+}
+
+// CHECK: builtins-bcd-transform-negative.c:22:12: error: argument value 2 is outside the valid range [0, 1]
+vector unsigned char tBcd_Zoned2packed_imm2(vector unsigned char a) {
+ return __builtin_ppc_zoned2packed (a,'\2');
+}
\ No newline at end of file
diff --git a/clang/test/CodeGen/PowerPC/builtins-bcd-transform.c b/clang/test/CodeGen/PowerPC/builtins-bcd-transform.c
new file mode 100644
index 0000000000000..025dcbce58118
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/builtins-bcd-transform.c
@@ -0,0 +1,57 @@
+// Testfile that verifies positive cases (0 or 1 only) for BCD builtins national2packed, packed2zoned and zoned2packed.
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-unknown-unknown -O2 -target-cpu pwr9 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: tBcd_National2packed_imm1
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 1)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_National2packed_imm1(vector unsigned char a) {
+ return __builtin_ppc_national2packed (a,'\1');
+}
+
+// CHECK-LABEL: tBcd_National2packed_imm0
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_National2packed_imm0(vector unsigned char a) {
+ return __builtin_ppc_national2packed (a,'\0');
+}
+
+// CHECK-LABEL: tBcd_Packed2national
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2national(<16 x i8> %a)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Packed2national(vector unsigned char a){
+ return __builtin_ppc_packed2national(a);
+}
+
+// CHECK-LABEL: tBcd_Packed2zoned_imm0
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Packed2zoned_imm0(vector unsigned char a){
+ return __builtin_ppc_packed2zoned(a,'\0');
+}
+
+// CHECK-LABEL: tBcd_Packed2zoned_imm1
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 1)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Packed2zoned_imm1(vector unsigned char a){
+ return __builtin_ppc_packed2zoned(a,'\1');
+}
+
+// CHECK-LABEL: tBcd_Zoned2packed_imm0
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 0)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Zoned2packed_imm0(vector unsigned char a){
+ return __builtin_ppc_zoned2packed(a,'\0');
+}
+
+// CHECK-LABEL: tBcd_Zoned2packed_imm1
+// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 1)
+// CHECK-NEXT: ret <16 x i8> [[TMP0]]
+vector unsigned char tBcd_Zoned2packed_imm1(vector unsigned char a){
+ return __builtin_ppc_zoned2packed(a,'\1');
+}
\ No newline at end of file
diff --git a/clang/test/Sema/builtins-bcd-transform.c b/clang/test/Sema/builtins-bcd-transform.c
new file mode 100644
index 0000000000000..103a6be6452b5
--- /dev/null
+++ b/clang/test/Sema/builtins-bcd-transform.c
@@ -0,0 +1,30 @@
+// Testfile to verify the semantics and the error handling for BCD builtins national2packed, packed2zoned and zoned2packed.
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64-unknown-unknown -fsyntax-only -verify %s
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc64le-unknown-unknown -fsyntax-only -verify %s
+// RUN: %clang_cc1 -target-feature +altivec -triple powerpc-unknown-unknown -fsyntax-only -verify %s
+
+#include <altivec.h>
+vector unsigned char test_national2packed(void)
+{
+ vector unsigned char a = {1,2,3,4};
+ vector unsigned char res_a = __builtin_ppc_national2packed(a, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ vector unsigned char res_b = __builtin_ppc_national2packed(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ return __builtin_ppc_national2packed(a, 0);
+}
+
+vector unsigned char test_packed2zoned(void)
+{
+ vector unsigned char a = {1,2,3,4};
+ vector unsigned char res_a = __builtin_ppc_packed2zoned(a,2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ vector unsigned char res_b = __builtin_ppc_packed2zoned(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ return __builtin_ppc_packed2zoned(a,1);
+}
+
+vector unsigned char test_zoned2packed(void)
+{
+ vector unsigned char a = {1,2,3,4};
+ vector unsigned char res_a = __builtin_ppc_zoned2packed(a,2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ vector unsigned char res_b = __builtin_ppc_zoned2packed(a, -1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+ return __builtin_ppc_zoned2packed(a,0);
+}
\ No newline at end of file
diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 751628cee58c0..6ae0cf40d6120 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -655,6 +655,14 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
DefaultAttrsIntrinsic<[llvm_v1i128_ty],[llvm_v1i128_ty],[IntrNoMem]>;
// BCD intrinsics.
+ def int_ppc_national2packed: ClangBuiltin<"__builtin_ppc_national2packed">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_packed2national: ClangBuiltin<"__builtin_ppc_packed2national">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_packed2zoned: ClangBuiltin<"__builtin_ppc_packed2zoned">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_zoned2packed: ClangBuiltin<"__builtin_ppc_zoned2packed">,
+ DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_cdtbcdd : ClangBuiltin<"__builtin_ppc_cdtbcd">,
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
def int_ppc_cbcdtdd: ClangBuiltin<"__builtin_ppc_cbcdtd">,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
index 386c94a324996..9a54e070629b7 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -1617,10 +1617,14 @@ class VX_VT5_EO5_VB5_XO9_o<bits<5> eo, bits<9> xo, string opc,
}
// Decimal Convert From/to National/Zoned/Signed-QWord
-def BCDCFN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<7, 385, "bcdcfn." , []>;
-def BCDCFZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<6, 385, "bcdcfz." , []>;
-def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." , []>;
-def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." , []>;
+def BCDCFN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<7, 385, "bcdcfn." ,
+ [(set v16i8:$VD, (int_ppc_national2packed v16i8:$VB, i32:$PS))]>;
+def BCDCFZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<6, 385, "bcdcfz." ,
+ [(set v16i8:$VD, (int_ppc_zoned2packed v16i8:$VB, i32:$PS))]>;
+def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." ,
+ [(set v16i8:$VD, (int_ppc_packed2national v16i8:$VB))]>;
+def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." ,
+ [(set v16i8:$VD, (int_ppc_packed2zoned v16i8:$VB, i32:$PS))]>;
def BCDCFSQ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<2, 385, "bcdcfsq.", []>;
def BCDCTSQ_rec : VX_VT5_EO5_VB5_XO9_o <0, 385, "bcdctsq.", []>;
diff --git a/llvm/test/CodeGen/PowerPC/builtins-bcd-transform.ll b/llvm/test/CodeGen/PowerPC/builtins-bcd-transform.ll
new file mode 100644
index 0000000000000..deb4656fcc718
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-bcd-transform.ll
@@ -0,0 +1,96 @@
+; Testfile that verifies positive case (0 or 1 only) for BCD builtins national2packed, packed2zoned and zoned2packed.
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc-unknown-unknown \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr9 -mtriple=powerpc64-ibm-aix-xcoff \
+; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s
+
+; CHECK-LABEL: tBcd_National2packed_imm0
+; CHECK: bcdcfn. v2, v2, 0
+; CHECK-NEXT: blr
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.national2packed(<16 x i8>, i32 immarg)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <16 x i8> @tBcd_National2packed_imm0(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 0)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_National2packed_imm1
+; CHECK: bcdcfn. v2, v2, 1
+; CHECK-NEXT: blr
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <16 x i8> @tBcd_National2packed_imm1(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.national2packed(<16 x i8> %a, i32 1)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Packed2national
+; CHECK: bcdctn. v2, v2
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.packed2national(<16 x i8>)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+define <16 x i8> @tBcd_Packed2national(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.packed2national(<16 x i8> %a)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Packed2zoned_imm0
+; CHECK: bcdctz. v2, v2, 0
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.packed2zoned(<16 x i8>, i32 immarg)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Packed2zoned_imm0(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 0)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Packed2zoned_imm1
+; CHECK: bcdctz. v2, v2, 1
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Packed2zoned_imm1(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.packed2zoned(<16 x i8> %a, i32 1)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Zoned2packed_imm0
+; CHECK: bcdcfz. v2, v2, 0
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare <16 x i8> @llvm.ppc.zoned2packed(<16 x i8>, i32 immarg)
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Zoned2packed_imm0(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 0)
+ ret <16 x i8> %0
+}
+
+; CHECK-LABEL: tBcd_Zoned2packed_imm1
+; CHECK: bcdcfz. v2, v2, 1
+; CHECK-NEXT: blr
+; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
+define dso_local <16 x i8> @tBcd_Zoned2packed_imm1(<16 x i8> noundef %a) {
+entry:
+ %0 = tail call <16 x i8> @llvm.ppc.zoned2packed(<16 x i8> %a, i32 1)
+ ret <16 x i8> %0
+}
\ No newline at end of file
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the description will be the git commit message, maybe it should just be a summary of what this patch implements.
llvm::Type *Int32Ty = llvm::IntegerType::get(getLLVMContext(), 32); | ||
Ops.push_back(EmitScalarExpr(E->getArg(0))); | ||
Ops.push_back(EmitScalarExpr(E->getArg(1))); | ||
Ops.push_back(Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(2)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just use CreateZExt()
?
case PPC::BI__builtin_ppc_packed2zoned: | ||
case PPC::BI__builtin_ppc_zoned2packed: { | ||
SmallVector<Value *, 3> Ops; | ||
// Zero extending unsigned char to 32 bits by using Int32ty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always opt to doc the intention of the code vs just doc what the code does.
// Zero extending unsigned char to 32 bits by using Int32ty | |
// Zero extend unsigned char to Int32ty to match BE intrinsic definition. |
def int_ppc_packed2zoned: ClangBuiltin<"__builtin_ppc_packed2zoned">, | ||
DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>; | ||
def int_ppc_zoned2packed: ClangBuiltin<"__builtin_ppc_zoned2packed">, | ||
DefaultAttrsIntrinsic<[llvm_v16i8_ty],[llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use llvm_any_ty
here instead of llvm_i32_ty
so we don't need to custom lower the arg in the FE?
@@ -0,0 +1,23 @@ | |||
// Testfile for negative condition for BCD builtins national2packed, packed2zoned and zoned2packed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between this and clang/test/Sema/builtins-bcd-transform.c
below?
I am not sure we need both.
def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." , | ||
[(set v16i8:$VD, (int_ppc_packed2national v16i8:$VB))]>; | ||
def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." , | ||
[(set v16i8:$VD, (int_ppc_packed2zoned v16i8:$VB, i32:$PS))]>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since PS is a constant of 0 or 1, can we not just use u1imm
?
Co-authored-by: Lei Huang <lei@ca.ibm.com>
Support the following packed BCD builtins for PowerPC.
Design decision considered:
national2packed, packed2zoned and zoned2packed
useunsigned char
. This is an illegal type in the LLVM backend(llvm_i8_ty
) and it has been custom lowered inPPC.cpp
file to fiti8
intoi32
by zero extending it.ImmArg<ArgIndex<1>>
was added toIntrinsicsPowerPC.td.
Prototypes:
vector unsigned char __builtin_national2packed(vector unsigned char a, unsigned char b);
vector unsigned char __builtin_packed2zoned(vector unsigned char, unsigned char);
vector unsigned char __builtin_zoned2packed(vector unsigned char, unsigned char);
The condition for the 2nd parameter is consistent over all the 3 prototypes (0 or 1 only).
vector unsigned char __builtin_packed2national(vector unsigned char);
Reference links: