diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -49,6 +49,7 @@ BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "") BUILTIN(__builtin_ppc_cmprb, "iCiii", "") BUILTIN(__builtin_ppc_setb, "LLiLLiLLi", "") +BUILTIN(__builtin_ppc_cmpb, "LLiLLiLLi", "") // Multiply BUILTIN(__builtin_ppc_mulhd, "LLiLiLi", "") BUILTIN(__builtin_ppc_mulhdu, "ULLiULiULi", "") diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -100,6 +100,7 @@ Builder.defineMacro("__cmpeqb", "__builtin_ppc_cmpeqb"); Builder.defineMacro("__cmprb", "__builtin_ppc_cmprb"); Builder.defineMacro("__setb", "__builtin_ppc_setb"); + Builder.defineMacro("__cmpb", "__builtin_ppc_cmpb"); Builder.defineMacro("__mulhd", "__builtin_ppc_mulhd"); Builder.defineMacro("__mulhdu", "__builtin_ppc_mulhdu"); Builder.defineMacro("__mulhw", "__builtin_ppc_mulhw"); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -15078,6 +15078,21 @@ Value *shift = Builder.CreateCall(F, {Ops[0], Ops[0], Ops[1]}); return Builder.CreateAnd(shift, Ops[2]); } + case PPC::BI__builtin_ppc_cmpb: { + llvm::Type *Ty = Ops[0]->getType(); + Value *Zero = Constant::getNullValue(Ty); + Value *Res = Constant::getNullValue(Ty); + Value *X = Builder.CreateXor(Ops[0], Ops[1]); + for (int i = 0; i < 8; i++) { + int64_t Mask = (int64_t)0xff << i * 8; + Value *Cmp = Builder.CreateICmpEQ( + Builder.CreateAnd(X, ConstantInt::getSigned(Ty, Mask)), Zero); + Value *Select = + Builder.CreateSelect(Cmp, ConstantInt::getSigned(Ty, Mask), Zero); + Res = Builder.CreateOr(Res, Select); + } + return Res; + } // Copy sign case PPC::BI__builtin_vsx_xvcpsgnsp: case PPC::BI__builtin_vsx_xvcpsgndp: { diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-compare.c b/clang/test/CodeGen/builtins-ppc-xlcompat-compare.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-compare.c @@ -0,0 +1,56 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s + +// CHECK-LABEL: @test_builtin_ppc_cmpb( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[LLA_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[LLB_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store i64 [[LLA:%.*]], i64* [[LLA_ADDR]], align 8 +// CHECK-NEXT: store i64 [[LLB:%.*]], i64* [[LLB_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[LLA_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[LLB_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP0]], [[TMP1]] +// CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], 255 +// CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[TMP3]], 0 +// CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP4]], i64 255, i64 0 +// CHECK-NEXT: [[TMP6:%.*]] = or i64 0, [[TMP5]] +// CHECK-NEXT: [[TMP7:%.*]] = and i64 [[TMP2]], 65280 +// CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 0 +// CHECK-NEXT: [[TMP9:%.*]] = select i1 [[TMP8]], i64 65280, i64 0 +// CHECK-NEXT: [[TMP10:%.*]] = or i64 [[TMP6]], [[TMP9]] +// CHECK-NEXT: [[TMP11:%.*]] = and i64 [[TMP2]], 16711680 +// CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[TMP11]], 0 +// CHECK-NEXT: [[TMP13:%.*]] = select i1 [[TMP12]], i64 16711680, i64 0 +// CHECK-NEXT: [[TMP14:%.*]] = or i64 [[TMP10]], [[TMP13]] +// CHECK-NEXT: [[TMP15:%.*]] = and i64 [[TMP2]], 4278190080 +// CHECK-NEXT: [[TMP16:%.*]] = icmp eq i64 [[TMP15]], 0 +// CHECK-NEXT: [[TMP17:%.*]] = select i1 [[TMP16]], i64 4278190080, i64 0 +// CHECK-NEXT: [[TMP18:%.*]] = or i64 [[TMP14]], [[TMP17]] +// CHECK-NEXT: [[TMP19:%.*]] = and i64 [[TMP2]], 1095216660480 +// CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[TMP19]], 0 +// CHECK-NEXT: [[TMP21:%.*]] = select i1 [[TMP20]], i64 1095216660480, i64 0 +// CHECK-NEXT: [[TMP22:%.*]] = or i64 [[TMP18]], [[TMP21]] +// CHECK-NEXT: [[TMP23:%.*]] = and i64 [[TMP2]], 280375465082880 +// CHECK-NEXT: [[TMP24:%.*]] = icmp eq i64 [[TMP23]], 0 +// CHECK-NEXT: [[TMP25:%.*]] = select i1 [[TMP24]], i64 280375465082880, i64 0 +// CHECK-NEXT: [[TMP26:%.*]] = or i64 [[TMP22]], [[TMP25]] +// CHECK-NEXT: [[TMP27:%.*]] = and i64 [[TMP2]], 71776119061217280 +// CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[TMP27]], 0 +// CHECK-NEXT: [[TMP29:%.*]] = select i1 [[TMP28]], i64 71776119061217280, i64 0 +// CHECK-NEXT: [[TMP30:%.*]] = or i64 [[TMP26]], [[TMP29]] +// CHECK-NEXT: [[TMP31:%.*]] = and i64 [[TMP2]], -72057594037927936 +// CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[TMP31]], 0 +// CHECK-NEXT: [[TMP33:%.*]] = select i1 [[TMP32]], i64 -72057594037927936, i64 0 +// CHECK-NEXT: [[TMP34:%.*]] = or i64 [[TMP30]], [[TMP33]] +// CHECK-NEXT: ret i64 [[TMP34]] +// +long long test_builtin_ppc_cmpb(long long lla, long long llb) { + return __builtin_ppc_cmpb(lla, llb); +}