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 @@ -45,6 +45,18 @@ BUILTIN(__builtin_ppc_dcbtst, "vv*", "") BUILTIN(__builtin_ppc_dcbz, "vv*", "") BUILTIN(__builtin_ppc_icbt, "vv*", "") +// Compare +BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "") +BUILTIN(__builtin_ppc_cmprb, "iCiii", "") +BUILTIN(__builtin_ppc_setb, "LLiLLiLLi", "") +// Multiply +BUILTIN(__builtin_ppc_mulhd, "LLiLiLi", "") +BUILTIN(__builtin_ppc_mulhdu, "ULLiULiULi", "") +BUILTIN(__builtin_ppc_mulhw, "iii", "") +BUILTIN(__builtin_ppc_mulhwu, "UiUiUi", "") +BUILTIN(__builtin_ppc_maddhd, "LLiLLiLLiLLi", "") +BUILTIN(__builtin_ppc_maddhdu, "ULLiULLiULLiULLi", "") +BUILTIN(__builtin_ppc_maddld, "LLiLLiLLiLLi", "") BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n") diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -351,23 +351,6 @@ return RegName.equals("r1") || RegName.equals("x1"); } - void defineXLCompatMacros(MacroBuilder &Builder) const { - Builder.defineMacro("__popcntb", "__builtin_ppc_popcntb"); - Builder.defineMacro("__eieio", "__builtin_ppc_eieio"); - Builder.defineMacro("__iospace_eieio", "__builtin_ppc_iospace_eieio"); - Builder.defineMacro("__isync", "__builtin_ppc_isync"); - Builder.defineMacro("__lwsync", "__builtin_ppc_lwsync"); - Builder.defineMacro("__iospace_lwsync", "__builtin_ppc_iospace_lwsync"); - Builder.defineMacro("__sync", "__builtin_ppc_sync"); - Builder.defineMacro("__iospace_sync", "__builtin_ppc_iospace_sync"); - Builder.defineMacro("__dcbfl", "__builtin_ppc_dcbfl"); - Builder.defineMacro("__dcbflp", "__builtin_ppc_dcbflp"); - Builder.defineMacro("__dcbst", "__builtin_ppc_dcbst"); - Builder.defineMacro("__dcbt", "__builtin_ppc_dcbt"); - Builder.defineMacro("__dcbtst", "__builtin_ppc_dcbtst"); - Builder.defineMacro("__dcbz", "__builtin_ppc_dcbz"); - Builder.defineMacro("__icbt", "__builtin_ppc_icbt"); - } }; class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { 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 @@ -81,6 +81,34 @@ return true; } +static void defineXLCompatMacros(MacroBuilder &Builder) { + Builder.defineMacro("__popcntb", "__builtin_ppc_popcntb"); + Builder.defineMacro("__eieio", "__builtin_ppc_eieio"); + Builder.defineMacro("__iospace_eieio", "__builtin_ppc_iospace_eieio"); + Builder.defineMacro("__isync", "__builtin_ppc_isync"); + Builder.defineMacro("__lwsync", "__builtin_ppc_lwsync"); + Builder.defineMacro("__iospace_lwsync", "__builtin_ppc_iospace_lwsync"); + Builder.defineMacro("__sync", "__builtin_ppc_sync"); + Builder.defineMacro("__iospace_sync", "__builtin_ppc_iospace_sync"); + Builder.defineMacro("__dcbfl", "__builtin_ppc_dcbfl"); + Builder.defineMacro("__dcbflp", "__builtin_ppc_dcbflp"); + Builder.defineMacro("__dcbst", "__builtin_ppc_dcbst"); + Builder.defineMacro("__dcbt", "__builtin_ppc_dcbt"); + Builder.defineMacro("__dcbtst", "__builtin_ppc_dcbtst"); + Builder.defineMacro("__dcbz", "__builtin_ppc_dcbz"); + Builder.defineMacro("__icbt", "__builtin_ppc_icbt"); + Builder.defineMacro("__cmpeqb", "__builtin_ppc_cmpeqb"); + Builder.defineMacro("__cmprb", "__builtin_ppc_cmprb"); + Builder.defineMacro("__setb", "__builtin_ppc_setb"); + Builder.defineMacro("__mulhd", "__builtin_ppc_mulhd"); + Builder.defineMacro("__mulhdu", "__builtin_ppc_mulhdu"); + Builder.defineMacro("__mulhw", "__builtin_ppc_mulhw"); + Builder.defineMacro("__mulhwu", "__builtin_ppc_mulhwu"); + Builder.defineMacro("__maddhd", "__builtin_ppc_maddhd"); + Builder.defineMacro("__maddhdu", "__builtin_ppc_maddhdu"); + Builder.defineMacro("__maddld", "__builtin_ppc_maddld"); +} + /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific /// #defines that are not tied to a specific subtarget. void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3260,7 +3260,14 @@ unsigned i = 0, l = 0, u = 0; bool Is64BitBltin = BuiltinID == PPC::BI__builtin_divde || BuiltinID == PPC::BI__builtin_divdeu || - BuiltinID == PPC::BI__builtin_bpermd; + BuiltinID == PPC::BI__builtin_bpermd || + BuiltinID == PPC::BI__builtin_ppc_cmpeqb || + BuiltinID == PPC::BI__builtin_ppc_setb || + BuiltinID == PPC::BI__builtin_ppc_mulhd || + BuiltinID == PPC::BI__builtin_ppc_mulhdu || + BuiltinID == PPC::BI__builtin_ppc_maddhd || + BuiltinID == PPC::BI__builtin_ppc_maddhdu || + BuiltinID == PPC::BI__builtin_ppc_maddld; bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64; bool IsBltinExtDiv = BuiltinID == PPC::BI__builtin_divwe || BuiltinID == PPC::BI__builtin_divweu || @@ -3331,6 +3338,8 @@ return SemaBuiltinConstantArgRange(TheCall, 2, 0, 7); case PPC::BI__builtin_vsx_xxpermx: return SemaBuiltinConstantArgRange(TheCall, 3, 0, 7); + case PPC::BI__builtin_ppc_cmprb: + return SemaBuiltinConstantArgRange(TheCall, 0, 0, 1); #define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \ case PPC::BI__builtin_##Name: \ return SemaBuiltinPPCMMACall(TheCall, Types); diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-compare-64bit-only.c b/clang/test/CodeGen/builtins-ppc-xlcompat-compare-64bit-only.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-compare-64bit-only.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s --check-prefix=CHECK-64 +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s --check-prefix=CHECK-64 +// RUN: %clang_cc1 -triple powerpc64-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s --check-prefix=CHECK-64 +// RUN: not %clang_cc1 -triple powerpc-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 2>&1 | FileCheck %s -check-prefix=CHECK-32 + +extern signed long long sll; + +signed long long test_builtin_ppc_cmpeqb() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_cmpeqb + +// CHECK-64-LABEL: @test_builtin_ppc_cmpeqb( +// CHECK-64-NEXT: entry: + return __builtin_ppc_cmpeqb(sll, sll); +// CHECK-64: %2 = call i64 @llvm.ppc.cmpeqb(i64 %0, i64 %1) +} +long long test_builtin_ppc_setb() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_setb + +// CHECK-64-LABEL: @test_builtin_ppc_setb( +// CHECK-64-NEXT: entry: + return __builtin_ppc_setb(sll, sll); +// CHECK-64: %2 = call i64 @llvm.ppc.setb(i64 %0, i64 %1) +} + +signed long long test_cmpeqb() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __cmpeqb + +// CHECK-64-LABEL: @test_cmpeqb( +// CHECK-64-NEXT: entry: + return __cmpeqb(sll, sll); +// CHECK-64: %2 = call i64 @llvm.ppc.cmpeqb(i64 %0, i64 %1) +} +long long test_setb() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __setb + +// CHECK-64-LABEL: @test_setb( +// CHECK-64-NEXT: entry: + return __setb(sll, sll); +// CHECK-64: %2 = call i64 @llvm.ppc.setb(i64 %0, i64 %1) +} 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,26 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s + +extern unsigned int ui; + +int test_builtin_ppc_cmprb() { +// CHECK-LABEL: @test_builtin_ppc_cmprb( +// CHECK-NEXT: entry: + return __builtin_ppc_cmprb(0, ui, ui) + __builtin_ppc_cmprb(1, ui, ui); +// CHECK: %2 = call i32 @llvm.ppc.cmprb(i32 0, i32 %0, i32 %1) +// CHECK: %5 = call i32 @llvm.ppc.cmprb(i32 1, i32 %3, i32 %4) +} + +int test_cmprb() { +// CHECK-LABEL: @test_cmprb( +// CHECK-NEXT: entry: + return __cmprb(0, ui, ui) + __cmprb(1, ui, ui); +// CHECK: %2 = call i32 @llvm.ppc.cmprb(i32 0, i32 %0, i32 %1) +// CHECK: %5 = call i32 @llvm.ppc.cmprb(i32 1, i32 %3, i32 %4) +} diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-error.c b/clang/test/CodeGen/builtins-ppc-xlcompat-error.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-error.c @@ -0,0 +1,18 @@ +// REQUIRES: powerpc-registered-target + +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -fsyntax-only \ +// RUN: -Wall -Werror -verify %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -fsyntax-only \ +// RUN: -Wall -Werror -verify %s +// RUN: %clang_cc1 -triple powerpc64-unknown-aix -fsyntax-only \ +// RUN: -Wall -Werror -verify %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix -fsyntax-only \ +// RUN: -Wall -Werror -verify %s + +extern unsigned int ui; + +void test_builtin_ppc_cmprb() { + int res = __builtin_ppc_cmprb(3, ui, ui); //expected-error {{argument value 3 is outside the valid range [0, 1]}} +} + + diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-multiply-64bit-only.c b/clang/test/CodeGen/builtins-ppc-xlcompat-multiply-64bit-only.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-multiply-64bit-only.c @@ -0,0 +1,134 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s --check-prefix=CHECK-64 +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s --check-prefix=CHECK-64 +// RUN: %clang_cc1 -triple powerpc64-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s --check-prefix=CHECK-64 +// RUN: not %clang_cc1 -triple powerpc-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 2>&1 | FileCheck %s --check-prefix=CHECK-32 + + +extern long int sli; +extern unsigned long int uli; +extern signed long long sll; +extern unsigned long long ull; + +long long test_builtin_ppc_mulhd() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_mulhd + +// CHECK-64-LABEL: @test_builtin_ppc_mulhd( +// CHECK-64-NEXT: entry: + return __builtin_ppc_mulhd(sli, sli); +// CHECK-64: %2 = call i64 @llvm.ppc.mulhd(i64 %0, i64 %1) +} + +unsigned long long test_builtin_ppc_mulhdu() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_mulhdu + +// CHECK-64-LABEL: @test_builtin_ppc_mulhdu( +// CHECK-64-NEXT: entry: + return __builtin_ppc_mulhdu(uli, uli); +// CHECK-64: %2 = call i64 @llvm.ppc.mulhdu(i64 %0, i64 %1) +} + +signed long long test_builtin_ppc_maddhd() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_maddhd + +// CHECK-64-LABEL: @test_builtin_ppc_maddhd( +// CHECK-64-NEXT: entry: + return __builtin_ppc_maddhd(sll, sll, sll); +// CHECK-64: %3 = call i64 @llvm.ppc.maddhd(i64 %0, i64 %1, i64 %2) +} + +unsigned long long test_builtin_ppc_maddhdu() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_maddhdu + +// CHECK-64-LABEL: @test_builtin_ppc_maddhdu( +// CHECK-64-NEXT: entry: + return __builtin_ppc_maddhdu(ull, ull, ull); +// CHECK-64: %3 = call i64 @llvm.ppc.maddhdu(i64 %0, i64 %1, i64 %2) +} + +signed long long test_builtin_ppc_maddld() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_maddld + +// CHECK-64-LABEL: @test_builtin_ppc_maddld( +// CHECK-64-NEXT: entry: + return __builtin_ppc_maddld(sll, sll, sll); +// CHECK-64: %3 = call i64 @llvm.ppc.maddld(i64 %0, i64 %1, i64 %2) +} + +unsigned long long test_builtin_ppc_maddld_unsigned() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __builtin_ppc_maddld + +// CHECK-64-LABEL: @test_builtin_ppc_maddld_unsigned( +// CHECK-64-NEXT: entry: + return __builtin_ppc_maddld(ull, ull, ull); +// CHECK-64: %3 = call i64 @llvm.ppc.maddld(i64 %0, i64 %1, i64 %2) +} + +long long test_mulhd() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __mulhd + +// CHECK-64-LABEL: @test_mulhd( +// CHECK-64-NEXT: entry: + return __mulhd(sli, sli); +// CHECK-64: %2 = call i64 @llvm.ppc.mulhd(i64 %0, i64 %1) +} + +unsigned long long test_mulhdu() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __mulhdu + +// CHECK-64-LABEL: @test_mulhdu( +// CHECK-64-NEXT: entry: + return __mulhdu(uli, uli); +// CHECK-64: %2 = call i64 @llvm.ppc.mulhdu(i64 %0, i64 %1) +} + +signed long long test_maddhd() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __maddhd + +// CHECK-64-LABEL: @test_maddhd( +// CHECK-64-NEXT: entry: + return __maddhd(sll, sll, sll); +// CHECK-64: %3 = call i64 @llvm.ppc.maddhd(i64 %0, i64 %1, i64 %2) +} + +unsigned long long test_maddhdu() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __maddhdu + +// CHECK-64-LABEL: @test_maddhdu( +// CHECK-64-NEXT: entry: + return __maddhdu(ull, ull, ull); +// CHECK-64: %3 = call i64 @llvm.ppc.maddhdu(i64 %0, i64 %1, i64 %2) +} + +signed long long test_maddld() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __maddld + +// CHECK-64-LABEL: @test_maddld( +// CHECK-64-NEXT: entry: + return __maddld(sll, sll, sll); +// CHECK-64: %3 = call i64 @llvm.ppc.maddld(i64 %0, i64 %1, i64 %2) +} + +unsigned long long test_maddld_unsigned() { +// CHECK-32: error: this builtin is only available on 64-bit targets +// CHECK-32: __maddld + +// CHECK-64-LABEL: @test_maddld_unsigned( +// CHECK-64-NEXT: entry: + return __maddld(ull, ull, ull); +// CHECK-64: %3 = call i64 @llvm.ppc.maddld(i64 %0, i64 %1, i64 %2) +} diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-multiply.c b/clang/test/CodeGen/builtins-ppc-xlcompat-multiply.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-multiply.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr9 | FileCheck %s + +extern int si; +extern unsigned int ui; + +int test_builtin_ppc_mulhw() { +// CHECK-LABEL: @test_builtin_ppc_mulhw( +// CHECK-NEXT: entry: + return __builtin_ppc_mulhw(si, si); +// CHECK: %2 = call i32 @llvm.ppc.mulhw(i32 %0, i32 %1) +} + +unsigned int test_builtin_ppc_mulhwu() { +// CHECK-LABEL: @test_builtin_ppc_mulhwu( +// CHECK-NEXT: entry: + return __builtin_ppc_mulhwu(ui, ui); +// CHECK: %2 = call i32 @llvm.ppc.mulhwu(i32 %0, i32 %1) +} + +int test_mulhw() { +// CHECK-LABEL: @test_mulhw( +// CHECK-NEXT: entry: + return __mulhw(si, si); +// CHECK: %2 = call i32 @llvm.ppc.mulhw(i32 %0, i32 %1) +} + +unsigned int test_mulhwu() { +// CHECK-LABEL: @test_mulhwu( +// CHECK-NEXT: entry: + return __mulhwu(ui, ui); +// CHECK: %2 = call i32 @llvm.ppc.mulhwu(i32 %0, i32 %1) +} diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -1520,3 +1520,37 @@ [llvm_v512i1_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; } + +// XL compatibility intrinsics. +let TargetPrefix = "ppc" in { + def int_ppc_cmpeqb + : GCCBuiltin<"__builtin_ppc_cmpeqb">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + def int_ppc_cmprb + : GCCBuiltin<"__builtin_ppc_cmprb">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_ppc_setb + : GCCBuiltin<"__builtin_ppc_setb">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + def int_ppc_mulhd + : GCCBuiltin<"__builtin_ppc_mulhd">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + def int_ppc_mulhdu + : GCCBuiltin<"__builtin_ppc_mulhdu">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + def int_ppc_mulhw + : GCCBuiltin<"__builtin_ppc_mulhw">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_ppc_mulhwu + : GCCBuiltin<"__builtin_ppc_mulhwu">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + def int_ppc_maddhd + : GCCBuiltin<"__builtin_ppc_maddhd">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + def int_ppc_maddhdu + : GCCBuiltin<"__builtin_ppc_maddhdu">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + def int_ppc_maddld + : GCCBuiltin<"__builtin_ppc_maddld">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; +} diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -1645,6 +1645,26 @@ def : Pat<(atomic_store_64 DSForm:$ptr, i64:$val), (STD g8rc:$val, memrix:$ptr)>; def : Pat<(atomic_store_64 XForm:$ptr, i64:$val), (STDX g8rc:$val, memrr:$ptr)>; +let Predicates = [IsISA3_0, In64BitMode] in { +def : Pat<(i64 (int_ppc_cmpeqb i64:$a, i64:$b)), + (i64 (SETB8 (CMPEQB $a, $b)))>; +def : Pat<(i64 (int_ppc_setb i64:$a, i64:$b)), + (i64 (SETB8 (CMPD $a, $b)))>; +def : Pat<(i64 (int_ppc_maddhd i64:$a, i64:$b, i64:$c)), + (i64 (MADDHD $a, $b, $c))>; +def : Pat<(i64 (int_ppc_maddhdu i64:$a, i64:$b, i64:$c)), + (i64 (MADDHDU $a, $b, $c))>; +def : Pat<(i64 (int_ppc_maddld i64:$a, i64:$b, i64:$c)), + (i64 (MADDLD8 $a, $b, $c))>; +} + +let Predicates = [In64BitMode] in { +def : Pat<(i64 (int_ppc_mulhd i64:$a, i64:$b)), + (i64 (MULHD $a, $b))>; +def : Pat<(i64 (int_ppc_mulhdu i64:$a, i64:$b)), + (i64 (MULHDU $a, $b))>; +} + let Predicates = [IsISA3_0] in { // DARN (deliver random number) // L=0 for 32-bit, L=1 for conditioned random, L=2 for raw random diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -5253,6 +5253,15 @@ "setb $RT, $BFA", IIC_IntGeneral>; } // IsISA3_0 +let Predicates = [IsISA3_0] in { +def : Pat<(i32 (int_ppc_cmprb i32:$a, i32:$b, i32:$c)), + (i32 (SETB (CMPRB imm:$a, $b, $c)))>; +} +def : Pat<(i32 (int_ppc_mulhw i32:$a, i32:$b)), + (i32 (MULHW $a, $b))>; +def : Pat<(i32 (int_ppc_mulhwu i32:$a, i32:$b)), + (i32 (MULHWU $a, $b))>; + // Fast 32-bit reverse bits algorithm: // Step 1: 1-bit swap (swap odd 1-bit and even 1-bit): // n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xAAAAAAAA); diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-compare-64bit-only.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-compare-64bit-only.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-compare-64bit-only.ll @@ -0,0 +1,42 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @test_builtin_ppc_cmpeqb(i64 %a, i64 %b) #0 { +; CHECK-LABEL: test_builtin_ppc_cmpeqb: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpeqb 0, 3, 4 +; CHECK-NEXT: setb 3, 0 +; CHECK-NEXT: blr +entry: + %0 = call i64 @llvm.ppc.cmpeqb(i64 %a, i64 %b) + ret i64 %0 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.cmpeqb(i64, i64) #1 + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @test_builtin_ppc_setb(i64 %a, i64 %b) #0 { +; CHECK-LABEL: test_builtin_ppc_setb: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpd 3, 4 +; CHECK-NEXT: setb 3, 0 +; CHECK-NEXT: blr +entry: + %0 = call i64 @llvm.ppc.setb(i64 %a, i64 %b) + ret i64 %0 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.setb(i64, i64) #1 + +attributes #0 = { noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-privileged,-rop-protect,-spe" } +attributes #1 = { nounwind readnone } + + diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-compare.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-compare.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-compare.ll @@ -0,0 +1,42 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-32 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64 + +; Function Attrs: noinline nounwind optnone +define dso_local signext i32 @test_builtin_ppc_cmprb(i32 %a, i32%b, i32 %c, i32%d) #0 { +; CHECK-32-LABEL: test_builtin_ppc_cmprb: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: cmprb 0, 0, 3, 4 +; CHECK-32-NEXT: setb 3, 0 +; CHECK-32-NEXT: cmprb 0, 1, 5, 6 +; CHECK-32-NEXT: setb 4, 0 +; CHECK-32-NEXT: add 3, 3, 4 +; CHECK-32-NEXT: blr +; +; CHECK-64-LABEL: test_builtin_ppc_cmprb: +; CHECK-64: # %bb.0: # %entry +; CHECK-64-NEXT: cmprb 0, 0, 3, 4 +; CHECK-64-NEXT: setb 3, 0 +; CHECK-64-NEXT: cmprb 0, 1, 5, 6 +; CHECK-64-NEXT: setb 4, 0 +; CHECK-64-NEXT: add 3, 3, 4 +; CHECK-64-NEXT: extsw 3, 3 +; CHECK-64-NEXT: blr +entry: + %0 = call i32 @llvm.ppc.cmprb(i32 0, i32 %a, i32 %b) + %1 = call i32 @llvm.ppc.cmprb(i32 1, i32 %c, i32 %d) + %add = add nsw i32 %0, %1 + ret i32 %add +} + +; Function Attrs: nounwind readnone +declare i32 @llvm.ppc.cmprb(i32, i32, i32) #1 + +attributes #0 = { noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-privileged,-rop-protect,-spe" } +attributes #1 = { nounwind readnone } diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-multiply-64bit-only.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-multiply-64bit-only.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-multiply-64bit-only.ll @@ -0,0 +1,82 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @test_builtin_ppc_mulhd(i64 %a, i64 %b) #0 { +; CHECK-LABEL: test_builtin_ppc_mulhd: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mulhd 3, 3, 4 +; CHECK-NEXT: blr +entry: + %0 = call i64 @llvm.ppc.mulhd(i64 %a, i64 %b) + ret i64 %0 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.mulhd(i64, i64) #1 + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @test_builtin_ppc_mulhdu(i64 %a, i64 %b) #0 { +; CHECK-LABEL: test_builtin_ppc_mulhdu: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mulhdu 3, 3, 4 +; CHECK-NEXT: blr +entry: + %0 = call i64 @llvm.ppc.mulhdu(i64 %a, i64 %b) + ret i64 %0 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.mulhdu(i64, i64) #1 + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @test_builtin_ppc_maddhd(i64 %a, i64 %b, i64 %c) #0 { +; CHECK-LABEL: test_builtin_ppc_maddhd: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: maddhd 3, 3, 4, 5 +; CHECK-NEXT: blr +entry: + %0 = call i64 @llvm.ppc.maddhd(i64 %a, i64 %b, i64 %c) + ret i64 %0 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.maddhd(i64, i64, i64) #1 + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @test_builtin_ppc_maddhdu(i64 %a, i64 %b, i64 %c) #0 { +; CHECK-LABEL: test_builtin_ppc_maddhdu: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: maddhdu 3, 3, 4, 5 +; CHECK-NEXT: blr +entry: + %0 = call i64 @llvm.ppc.maddhdu(i64 %a, i64 %b, i64 %c) + ret i64 %0 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.maddhdu(i64, i64, i64) #1 + +; Function Attrs: noinline nounwind optnone +define dso_local i64 @test_builtin_ppc_maddld(i64 %a, i64 %b, i64 %c) #0 { +; CHECK-LABEL: test_builtin_ppc_maddld: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: maddld 3, 3, 4, 5 +; CHECK-NEXT: blr +entry: + %0 = call i64 @llvm.ppc.maddld(i64 %a, i64 %b, i64 %c) + ret i64 %0 +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.maddld(i64, i64, i64) #1 + +attributes #0 = { noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-privileged,-rop-protect,-spe" } +attributes #1 = { nounwind readnone } + + diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-multiply.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-multiply.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-multiply.ll @@ -0,0 +1,52 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64 +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-32 +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-64 + +; Function Attrs: noinline nounwind optnone +define dso_local signext i32 @test_builtin_ppc_mulhw(i32 %a, i32%b) #0 { +; CHECK-32-LABEL: test_builtin_ppc_mulhw: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: mulhw 3, 3, 4 +; CHECK-32-NEXT: blr +; +; CHECK-64-LABEL: test_builtin_ppc_mulhw: +; CHECK-64: # %bb.0: # %entry +; CHECK-64-NEXT: mulhw 3, 3, 4 +; CHECK-64-NEXT: extsw 3, 3 +; CHECK-64-NEXT: blr +entry: + %0 = call i32 @llvm.ppc.mulhw(i32 %a, i32 %b) + ret i32 %0 +} + +; Function Attrs: nounwind readnone +declare i32 @llvm.ppc.mulhw(i32, i32) #1 + +; Function Attrs: noinline nounwind optnone +define dso_local zeroext i32 @test_builtin_ppc_mulhwu(i32 %a, i32%b) #0 { +; CHECK-32-LABEL: test_builtin_ppc_mulhwu: +; CHECK-32: # %bb.0: # %entry +; CHECK-32-NEXT: mulhwu 3, 3, 4 +; CHECK-32-NEXT: blr +; +; CHECK-64-LABEL: test_builtin_ppc_mulhwu: +; CHECK-64: # %bb.0: # %entry +; CHECK-64-NEXT: mulhwu 3, 3, 4 +; CHECK-64-NEXT: clrldi 3, 3, 32 +; CHECK-64-NEXT: blr +entry: + %0 = call i32 @llvm.ppc.mulhwu(i32 %a, i32 %b) + ret i32 %0 +} + +; Function Attrs: nounwind readnone +declare i32 @llvm.ppc.mulhwu(i32, i32) #1 + +attributes #0 = { noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr9" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+power9-vector,+vsx,-privileged,-rop-protect,-spe" } +attributes #1 = { nounwind readnone }