-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are only providing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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 Also, to be clear, we are only redirecting users of
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
My comment above is for case when a user wants to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this patch doesn't reject 64-bit input for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It does not do so though. It accepts (and converts) 32-bit arguments (in the C/C++ code) for |
||
} | ||
|
||
// 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); | ||
} |
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For |
||
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); | ||
} |
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) |
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.
It's surprising that
__builtin_xxx
and__builtin_ppc_xxx
has difference in signature. Does XL have these?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.
Yes, XL currently have these builtins and
__buitin_ppc_xxx
are implemented to be compat with XL.