Skip to content
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
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/BuiltinsPPC.def
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ TARGET_BUILTIN(__builtin_ppc_bcdsub_p, "iiV16UcV16Uc", "",
"isa-v207-instructions")

// P9 Binary-coded decimal (BCD) builtins.
TARGET_BUILTIN(__builtin_ppc_bcdcopysign, "V16UcV16UcV16Uc", "", "power9-vector")
TARGET_BUILTIN(__builtin_ppc_bcdsetsign, "V16UcV16UcUc", "t", "power9-vector")
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")
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
}

static void defineXLCompatMacros(MacroBuilder &Builder) {
Builder.defineMacro("__builtin_bcdcopysign", "__builtin_ppc_bcdcopysign");
Builder.defineMacro("__builtin_bcdsetsign", "__builtin_ppc_bcdsetsign");
Builder.defineMacro("__builtin_national2packed",
"__builtin_ppc_national2packed");
Builder.defineMacro("__builtin_packed2national",
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaPPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
switch (BuiltinID) {
default:
return false;
case PPC::BI__builtin_ppc_bcdsetsign:
case PPC::BI__builtin_ppc_national2packed:
case PPC::BI__builtin_ppc_packed2zoned:
case PPC::BI__builtin_ppc_zoned2packed:
Expand Down
29 changes: 29 additions & 0 deletions clang/test/CodeGen/PowerPC/builtins-bcd-format-conversion.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
// 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: test_bcdcopysign
// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.bcdcopysign(<16 x i8> %a, <16 x i8> %b)
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
vector unsigned char test_bcdcopysign(vector unsigned char a, vector unsigned char b) {
return __builtin_ppc_bcdcopysign(a, b);
}

// CHECK-LABEL: test_bcdsetsign_imm0
// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.bcdsetsign(<16 x i8> %a, i32 0)
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
vector unsigned char test_bcdsetsign_imm0(vector unsigned char a) {
return __builtin_ppc_bcdsetsign(a, '\0');
}

// CHECK-LABEL: test_bcdsetsign_imm1
// CHECK: [[TMP0:%.*]] = tail call <16 x i8> @llvm.ppc.bcdsetsign(<16 x i8> %a, i32 1)
// CHECK-NEXT: ret <16 x i8> [[TMP0]]
vector unsigned char test_bcdsetsign_imm1(vector unsigned char a) {
return __builtin_ppc_bcdsetsign(a, '\1');
Copy link
Contributor

Choose a reason for hiding this comment

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

it's strange that the 2nd arg need to be a const of 1 or 0 and we are making the users specify it as a char via \1 or \0. Seems like this should just be 1 or 0.

Copy link
Member Author

@AditiRM AditiRM Aug 14, 2025

Choose a reason for hiding this comment

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

While it works with 0 and 1, we use '\0' and '\1' as that’s the conventional way to pass an unsigned character, and it ensures the value is treated as a character literal. At runtime, these literals are converted to their corresponding ASCII values.

}
7 changes: 7 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsPowerPC.td
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,13 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_addg6s: ClangBuiltin<"__builtin_addg6s">,
DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;

// BCD Format conversion intrinsics
def int_ppc_bcdcopysign : ClangBuiltin<"__builtin_ppc_bcdcopysign">,
DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_ppc_bcdsetsign : ClangBuiltin<"__builtin_ppc_bcdsetsign">,
DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty],
[IntrNoMem, ImmArg<ArgIndex<1>>]>;

def int_ppc_bcdadd : ClangBuiltin<"__builtin_ppc_bcdadd">,
DefaultAttrsIntrinsic<
[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Target/PowerPC/PPCInstrAltivec.td
Original file line number Diff line number Diff line change
Expand Up @@ -1630,9 +1630,11 @@ def BCDCTSQ_rec : VX_VT5_EO5_VB5_XO9_o <0, 385, "bcdctsq.", []>;

// Decimal Copy-Sign/Set-Sign
let Defs = [CR6] in
def BCDCPSGN_rec : VX1_VT5_VA5_VB5<833, "bcdcpsgn.", []>;
def BCDCPSGN_rec : VX1_VT5_VA5_VB5<833, "bcdcpsgn.",
[(set v16i8:$VD, (int_ppc_bcdcopysign v16i8:$VA, v16i8:$VB))]>;

def BCDSETSGN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<31, 385, "bcdsetsgn.", []>;
def BCDSETSGN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<31, 385, "bcdsetsgn.",
[(set v16i8:$VD, (int_ppc_bcdsetsign v16i8:$VB, i32:$PS))]>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think i32 should be uimm1

Copy link
Member Author

Choose a reason for hiding this comment

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

Keeping it as i32 since the backend expects and handles it correctly


// Decimal Shift/Unsigned-Shift/Shift-and-Round
def BCDS_rec : VX_VT5_VA5_VB5_PS1_XO9_o<193, "bcds." , []>;
Expand Down
40 changes: 40 additions & 0 deletions llvm/test/CodeGen/PowerPC/builtins-bcd-format-conversion.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-unknown -mcpu=pwr9 \
; RUN: --ppc-asm-full-reg-names < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-unknown -mcpu=pwr9 \
; 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

define dso_local <16 x i8> @test_bcdcopysign(<16 x i8> noundef %a, <16 x i8> noundef %b) {
; CHECK-LABEL: test_bcdcopysign:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: bcdcpsgn. v2, v2, v3
; CHECK-NEXT: blr
entry:
%0 = tail call <16 x i8> @llvm.ppc.bcdcopysign(<16 x i8> %a, <16 x i8> %b)
ret <16 x i8> %0
}

define dso_local <16 x i8> @test_bcdsetsign_imm0(<16 x i8> noundef %a) {
; CHECK-LABEL: test_bcdsetsign_imm0:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: bcdsetsgn. v2, v2, 0
; CHECK-NEXT: blr
entry:
%0 = tail call <16 x i8> @llvm.ppc.bcdsetsign(<16 x i8> %a, i32 0)
ret <16 x i8> %0
}

define dso_local <16 x i8> @test_bcdsetsign_imm1(<16 x i8> noundef %a) {
; CHECK-LABEL: test_bcdsetsign_imm1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: bcdsetsgn. v2, v2, 1
; CHECK-NEXT: blr
entry:
%0 = tail call <16 x i8> @llvm.ppc.bcdsetsign(<16 x i8> %a, i32 1)
ret <16 x i8> %0
}

declare <16 x i8> @llvm.ppc.bcdcopysign(<16 x i8>, <16 x i8>)
declare <16 x i8> @llvm.ppc.bcdsetsign(<16 x i8>, i32)