Skip to content

[PPC] Implement BCD assist builtins #101390

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

Merged
merged 5 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/BuiltinsPPC.def
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,16 @@ TARGET_BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "", "power9-vector")
TARGET_BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "", "power9-vector")
TARGET_BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "", "power9-vector")

// P7 BCD builtins.
TARGET_BUILTIN(__builtin_cdtbcd, "UiUi", "", "isa-v206-instructions")
TARGET_BUILTIN(__builtin_cbcdtd, "UiUi", "", "isa-v206-instructions")
TARGET_BUILTIN(__builtin_addg6s, "UiUiUi", "", "isa-v206-instructions")
Comment on lines +519 to +521
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's surprising that __builtin_xxx and __builtin_ppc_xxx has difference in signature. Does XL have these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, XL currently have these builtins and __buitin_ppc_xxx are implemented to be compat with XL.


// P7 XL Compat BCD builtins.
TARGET_BUILTIN(__builtin_ppc_cdtbcd, "LLiLLi", "", "isa-v206-instructions")
TARGET_BUILTIN(__builtin_ppc_cbcdtd, "LLiLLi", "", "isa-v206-instructions")
TARGET_BUILTIN(__builtin_ppc_addg6s, "LLiLLiLLi", "", "isa-v206-instructions")

// P8 BCD builtins.
TARGET_BUILTIN(__builtin_ppc_bcdadd, "V16UcV16UcV16UcIi", "",
"isa-v207-instructions")
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Targets/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
}

static void defineXLCompatMacros(MacroBuilder &Builder) {
Builder.defineMacro("__cdtbcd", "__builtin_ppc_cdtbcd");
Builder.defineMacro("__cbcdtd", "__builtin_ppc_cbcdtd");
Builder.defineMacro("__addg6s", "__builtin_ppc_addg6s");
Builder.defineMacro("__popcntb", "__builtin_ppc_popcntb");
Builder.defineMacro("__poppar4", "__builtin_ppc_poppar4");
Builder.defineMacro("__poppar8", "__builtin_ppc_poppar8");
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaPPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
case PPC::BI__builtin_bpermd:
case PPC::BI__builtin_pdepd:
case PPC::BI__builtin_pextd:
case PPC::BI__builtin_ppc_cdtbcd:
case PPC::BI__builtin_ppc_cbcdtd:
case PPC::BI__builtin_ppc_addg6s:
case PPC::BI__builtin_ppc_ldarx:
case PPC::BI__builtin_ppc_stdcx:
case PPC::BI__builtin_ppc_tdw:
Expand Down
58 changes: 58 additions & 0 deletions clang/test/CodeGen/PowerPC/builtins-bcd-assist.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -triple powerpc64le-unknown-linux -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s

// CHECK-LABEL: define{{.*}} i64 @cdtbcd_test(i64
// CHECK: [[CONV:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cdtbcd(i32 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[TMP0]] to i64
// CHECK-NEXT: ret i64 [[CONV1]]
long long cdtbcd_test(long long ll) {
return __builtin_cdtbcd (ll);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, for compatibility with GCC, maybe this is right. But this is not good as in clang we are also providing __cdtbcd() for 64 bit inputs. Using GCC's 32-bit version will cause sacrifice of accuracy. I am not sure, for this case, should we add at least a warning and remind the user the other one can be used?

Copy link
Contributor Author

@lei137 lei137 Aug 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are only providing __xxx() in 64bit for backward compat to XL. Doc will be updated to ask user to use __builtin_xxx() for 32bit when migrating to OpenXL. GCC __builtin_xxx() only provide support for unsigned int. Do we really want to direct user to a functiont that takes signed long long type?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to direct user to a functiont that takes signed long long type?

Some users can benefit from the XL version of the functions even if they are not migrating from XL; however, they would need to be willing to have code that is specific to 64-bit IBM XL and Clang. The 64-bit versions of __cbcdtd and __cdtbcd operate on two 32-bit operands at the same time. The 64-bit version of addg6s operates on wider BCD operands.

Also, to be clear, we are only redirecting users of __cbcdtd and __cdtbcd in 32-bit mode to the GCC versions (where they might need to call the GCC built-in twice if they had a 64-bit input: once for the high 32-bits and once for the low 32-bits).

__addg6s was always 64-bit only for IBM XL, so there is no migration-from-IBM-XL scenario involving 32-bit __addg6s.

Copy link
Collaborator

@chenzheng1030 chenzheng1030 Aug 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to direct user to a function that takes signed long long type?

My comment above is for case when a user wants to call cdtbcd for a 64-bit input for 64-bit mode(for new codes). If the GCC compat one __builtin_cdtbcd() is chosen by accident(this is not rejected in this patch, although GCC builtin should only accept 32-bit input), the input will be trunc so the output will be not accurate(?). But if the XLC compat one __cdtbcd() is used, I think the output is accurate?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this patch doesn't reject 64-bit input for __builtin_cdtbcd like it rejects 32-bit input for __cdtbcd?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like it rejects 32-bit input for __cdtbcd

It does not do so though. It accepts (and converts) 32-bit arguments (in the C/C++ code) for __cdtbcd (in 64-bit mode).

}

// CHECK-LABEL: define{{.*}} i32 @cdtbcd_test_ui(i32
// CHECK: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cdtbcd(i32
// CHECK-NEXT: ret i32 [[TMP0]]
unsigned int cdtbcd_test_ui(unsigned int ui) {
return __builtin_cdtbcd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @cbcdtd_test(i64
// CHECK: [[CONV:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cbcdtd(i32 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[TMP0]] to i64
// CHECK-NEXT: ret i64 [[CONV1]]
long long cbcdtd_test(long long ll) {
return __builtin_cbcdtd (ll);
}

// CHECK-LABEL: define{{.*}} i32 @cbcdtd_test_ui(i32
// CHECK: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cbcdtd(i32
// CHECK-NEXT: ret i32 [[TMP0]]
unsigned int cbcdtd_test_ui(unsigned int ui) {
return __builtin_cbcdtd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @addg6s_test(i64
// CHECK: [[CONV:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[CONV1:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.addg6s(i32 [[CONV]], i32 [[CONV1]])
// CHECK-NEXT: [[CONV2:%.*]] = zext i32 [[TMP0]] to i64
// CHECK-NEXT: ret i64 [[CONV2]]
//
long long addg6s_test(long long ll, long long ll2) {
return __builtin_addg6s (ll, ll2);
}

// CHECK-LABEL: define{{.*}} i32 @addg6s_test_ui(i32
// CHECK: [[TMP0:%.*]] = tail call i32 @llvm.ppc.addg6s(i32 {{.*}}, i32
// CHECK-NEXT: ret i32 [[TMP0]]
unsigned int addg6s_test_ui(unsigned int ui, unsigned int ui2) {
return __builtin_addg6s (ui, ui2);
}
75 changes: 75 additions & 0 deletions clang/test/CodeGen/PowerPC/builtins-ppc-bcd-assist.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -triple powerpc64le-unknown-linux -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: not %clang_cc1 -triple powerpc-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-32-ERROR

// CHECK-LABEL: define{{.*}} i64 @cdtbcd_test(i64
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cdtbcdd(i64
// CHECK-NEXT: ret i64 [[TMP0]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cdtbcd __builtin_ppc_cdtbcd
long long cdtbcd_test(long long ll) {
return __cdtbcd (ll);
}

// CHECK-LABEL: define{{.*}} i32 @cdtbcd_test_ui(i32
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[CONV:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cdtbcdd(i64 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: ret i32 [[CONV1]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cdtbcd __builtin_ppc_cdtbcd
unsigned int cdtbcd_test_ui(unsigned int ui) {
return __cdtbcd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @cbcdtd_test(i64
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cbcdtdd(i64
// CHECK-NEXT: ret i64 [[TMP0]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cbcdtd __builtin_ppc_cbcdtd
long long cbcdtd_test(long long ll) {
return __cbcdtd (ll);
}

// CHECK-LABEL: define{{.*}} i32 @cbcdtd_test_ui(i32
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[CONV:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cbcdtdd(i64 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: ret i32 [[CONV1]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cbcdtd __builtin_ppc_cbcdtd
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For __cbcdtd, 32-bit input is rejected. Otherwise, we may also need sign-ext before the cbcdtd instruction?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For __cbcdtd, we reject it (no matter the input) in 32-bit mode because its semantic is to operate on two 32-bit words (stored in a 64-bit type). That is, if we were to accept it in 32-bit mode, it would involve two cbcdtd instructions (and not just one): this may be a surprise for users.

unsigned int cbcdtd_test_ui(unsigned int ui) {
return __cbcdtd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @addg6s_test(i64
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.addg6sd(i64 {{.*}}, i64 {{.*}})
// CHECK-NEXT: ret i64 [[TMP0]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __addg6s __builtin_ppc_addg6s
long long addg6s_test(long long ll, long long ll2) {
return __addg6s (ll, ll2);
}

// CHECK-LABEL: define{{.*}} i32 @addg6s_test_ui(i32
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[CONV:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[CONV1:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.addg6sd(i64 {{.*}}, i64
// CHECK-NEXT: [[CONV2:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: ret i32 [[CONV2]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __addg6s __builtin_ppc_addg6s
unsigned int addg6s_test_ui(unsigned int ui, unsigned int ui2) {
return __addg6s (ui, ui2);
}
13 changes: 13 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsPowerPC.td
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,19 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
DefaultAttrsIntrinsic<[llvm_v1i128_ty],[llvm_v1i128_ty],[IntrNoMem]>;

// BCD intrinsics.
def int_ppc_cdtbcdd : ClangBuiltin<"__builtin_ppc_cdtbcd">,
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
def int_ppc_cbcdtdd: ClangBuiltin<"__builtin_ppc_cbcdtd">,
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
def int_ppc_addg6sd: ClangBuiltin<"__builtin_ppc_addg6s">,
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
def int_ppc_cdtbcd : ClangBuiltin<"__builtin_cdtbcd">,
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_ppc_cbcdtd: ClangBuiltin<"__builtin_cbcdtd">,
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_ppc_addg6s: ClangBuiltin<"__builtin_addg6s">,
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;

def int_ppc_bcdadd : ClangBuiltin<"__builtin_ppc_bcdadd">,
DefaultAttrsIntrinsic<
[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/Target/PowerPC/PPCInstr64Bit.td
Original file line number Diff line number Diff line change
Expand Up @@ -1014,12 +1014,14 @@ def POPCNTB8 : XForm_11<31, 122, (outs g8rc:$RA), (ins g8rc:$RST),
[(set i64:$RA, (int_ppc_popcntb i64:$RST))]>;

def CDTBCD8 : XForm_11<31, 282, (outs g8rc:$RA), (ins g8rc:$RST),
"cdtbcd $RA, $RST", IIC_IntGeneral, []>;
"cdtbcd $RA, $RST", IIC_IntGeneral,
[(set i64:$RA, (int_ppc_cdtbcdd i64:$RST))]>;
def CBCDTD8 : XForm_11<31, 314, (outs g8rc:$RA), (ins g8rc:$RST),
"cbcdtd $RA, $RST", IIC_IntGeneral, []>;

"cbcdtd $RA, $RST", IIC_IntGeneral,
[(set i64:$RA, (int_ppc_cbcdtdd i64:$RST))]>;
def ADDG6S8 : XOForm_1<31, 74, 0, (outs g8rc:$RT), (ins g8rc:$RA, g8rc:$RB),
"addg6s $RT, $RA, $RB", IIC_IntGeneral, []>;
"addg6s $RT, $RA, $RB", IIC_IntGeneral,
[(set i64:$RT, (int_ppc_addg6sd i64:$RA, i64:$RB))]>;
}

defm DIVD : XOForm_1rcr<31, 489, 0, (outs g8rc:$RT), (ins g8rc:$RA, g8rc:$RB),
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1931,12 +1931,14 @@ def POPCNTB : XForm_11<31, 122, (outs gprc:$RA), (ins gprc:$RST),
[(set i32:$RA, (int_ppc_popcntb i32:$RST))]>;

def CDTBCD : XForm_11<31, 282, (outs gprc:$RA), (ins gprc:$RST),
"cdtbcd $RA, $RST", IIC_IntGeneral, []>;
"cdtbcd $RA, $RST", IIC_IntGeneral,
[(set i32:$RA, (int_ppc_cdtbcd i32:$RST))]>;
def CBCDTD : XForm_11<31, 314, (outs gprc:$RA), (ins gprc:$RST),
"cbcdtd $RA, $RST", IIC_IntGeneral, []>;

"cbcdtd $RA, $RST", IIC_IntGeneral,
[(set i32:$RA, (int_ppc_cbcdtd i32:$RST))]>;
def ADDG6S : XOForm_1<31, 74, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
"addg6s $RT, $RA, $RB", IIC_IntGeneral, []>;
"addg6s $RT, $RA, $RB", IIC_IntGeneral,
[(set i32:$RT, (int_ppc_addg6s i32:$RA, i32:$RB))]>;

//===----------------------------------------------------------------------===//
// PPC32 Load Instructions.
Expand Down
111 changes: 111 additions & 0 deletions llvm/test/CodeGen/PowerPC/builtins-bcd-assist.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux \
; RUN: --ppc-asm-full-reg-names -mcpu=pwr7 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
; RUN: --ppc-asm-full-reg-names -mcpu=pwr7 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
; RUN: --ppc-asm-full-reg-names -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-AIX32

define dso_local i64 @cdtbcd_test(i64 noundef %ll) {
; CHECK-LABEL: cdtbcd_test:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cdtbcd r3, r3
; CHECK-NEXT: clrldi r3, r3, 32
; CHECK-NEXT: blr
; CHECK-AIX32-LABEL: cdtbcd_test:
; CHECK-AIX32: # %bb.0: # %entry
; CHECK-AIX32-NEXT: li r3, 0
; CHECK-AIX32-NEXT: cdtbcd r4, r4
; CHECK-AIX32-NEXT: blr
entry:
%conv = trunc i64 %ll to i32
%0 = tail call i32 @llvm.ppc.cdtbcd(i32 %conv)
%conv1 = zext i32 %0 to i64
ret i64 %conv1
}

define dso_local zeroext i32 @cdtbcd_test_ui(i32 noundef zeroext %ui) {
; CHECK-LABEL: cdtbcd_test_ui:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cdtbcd r3, r3
; CHECK-NEXT: clrldi r3, r3, 32
; CHECK-NEXT: blr
; CHECK-AIX32-LABEL: cdtbcd_test_ui:
; CHECK-AIX32: # %bb.0: # %entry
; CHECK-AIX32-NEXT: cdtbcd r3, r3
; CHECK-AIX32-NEXT: blr
entry:
%0 = tail call i32 @llvm.ppc.cdtbcd(i32 %ui)
ret i32 %0
}

define dso_local i64 @cbcdtd_test(i64 noundef %ll) {
; CHECK-LABEL: cbcdtd_test:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cbcdtd r3, r3
; CHECK-NEXT: clrldi r3, r3, 32
; CHECK-NEXT: blr
; CHECK-AIX32-LABEL: cbcdtd_test:
; CHECK-AIX32: # %bb.0: # %entry
; CHECK-AIX32-NEXT: li r3, 0
; CHECK-AIX32-NEXT: cbcdtd r4, r4
; CHECK-AIX32-NEXT: blr
entry:
%conv = trunc i64 %ll to i32
%0 = tail call [email protected](i32 %conv)
%conv1 = zext i32 %0 to i64
ret i64 %conv1
}

define dso_local zeroext i32 @cbcdtd_test_ui(i32 noundef zeroext %ui) {
; CHECK-LABEL: cbcdtd_test_ui:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cbcdtd r3, r3
; CHECK-NEXT: clrldi r3, r3, 32
; CHECK-NEXT: blr
; CHECK-AIX32-LABEL: cbcdtd_test_ui:
; CHECK-AIX32: # %bb.0: # %entry
; CHECK-AIX32-NEXT: cbcdtd r3, r3
; CHECK-AIX32-NEXT: blr
entry:
%0 = tail call i32 @llvm.ppc.cbcdtd(i32 %ui)
ret i32 %0
}

define dso_local i64 @addg6s_test(i64 noundef %ll, i64 noundef %ll2) {
; CHECK-LABEL: addg6s_test:
; CHECK: bb.0: # %entry
; CHECK-NEXT: addg6s r3, r3, r4
; CHECK-NEXT: clrldi r3, r3, 32
; CHECK-NEXT: blr
; CHECK-AIX32-LABEL: addg6s_test:
; CHECK-AIX32: # %bb.0: # %entry
; CHECK-AIX32-NEXT: li r3, 0
; CHECK-AIX32-NEXT: addg6s r4, r4, r6
; CHECK-AIX32-NEXT: blr
entry:
%conv = trunc i64 %ll to i32
%conv1 = trunc i64 %ll2 to i32
%0 = tail call i32 @llvm.ppc.addg6s(i32 %conv, i32 %conv1)
%conv2 = zext i32 %0 to i64
ret i64 %conv2
}

define dso_local zeroext i32 @addg6s_test_ui(i32 noundef zeroext %ui, i32 noundef zeroext %ui2) {
; CHECK-LABEL: addg6s_test_ui:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addg6s r3, r3, r4
; CHECK-NEXT: clrldi r3, r3, 32
; CHECK-NEXT: blr
; CHECK-AIX32-LABEL: addg6s_test_ui:
; CHECK-AIX32: # %bb.0: # %entry
; CHECK-AIX32-NEXT: addg6s r3, r3, r4
; CHECK-AIX32-NEXT: blr
entry:
%0 = tail call i32 @llvm.ppc.addg6s(i32 %ui, i32 %ui2)
ret i32 %0
}

declare i32 @llvm.ppc.cdtbcd(i32)
declare i32 @llvm.ppc.cbcdtd(i32)
declare i32 @llvm.ppc.addg6s(i32, i32)
Loading
Loading