From: Quinn Pham Date: Thu, 22 Jul 2021 13:47:57 +0000 (-0500) Subject: [PowerPC] swdiv builtins for XL compatibility X-Git-Tag: upstream/15.0.7~30143 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=67a3d1e2755152608fcb1737f7d0519121e037b7;p=platform%2Fupstream%2Fllvm.git [PowerPC] swdiv builtins for XL compatibility This patch is in a series of patches to provide builtins for compatibility with the XL compiler. This patch implements the software divide builtin as wrappers for a floating point divide. XL provided these builtins because it didn't produce software estimates by default at `-Ofast`. When compiled with `-Ofast` these builtins will produce the software estimate for divide. Reviewed By: #powerpc, nemanjai Differential Revision: https://reviews.llvm.org/D106959 --- diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 6fee978..26286c2 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -101,6 +101,8 @@ BUILTIN(__builtin_ppc_compare_exp_lt, "idd", "") BUILTIN(__builtin_ppc_compare_exp_gt, "idd", "") BUILTIN(__builtin_ppc_compare_exp_eq, "idd", "") BUILTIN(__builtin_ppc_test_data_class, "idIi", "t") +BUILTIN(__builtin_ppc_swdiv, "ddd", "") +BUILTIN(__builtin_ppc_swdivs, "fff", "") // Compare BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "") BUILTIN(__builtin_ppc_cmprb, "iCIiii", "") diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 4835f1d..21376b3 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -243,6 +243,8 @@ static void defineXLCompatMacros(MacroBuilder &Builder) { Builder.defineMacro("__compare_exp_gt", "__builtin_ppc_compare_exp_gt"); Builder.defineMacro("__compare_exp_eq", "__builtin_ppc_compare_exp_eq"); Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class"); + Builder.defineMacro("__swdiv", "__builtin_ppc_swdiv"); + Builder.defineMacro("__swdivs", "__builtin_ppc_swdivs"); } /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index fe532a7..c7dcde1 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16077,7 +16077,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, *this, E, Intrinsic::sqrt, Intrinsic::experimental_constrained_sqrt)) .getScalarVal(); - case PPC::BI__builtin_ppc_test_data_class: + case PPC::BI__builtin_ppc_test_data_class: { llvm::Type *ArgType = EmitScalarExpr(E->getArg(0))->getType(); unsigned IntrinsicID; if (ArgType->isDoubleTy()) @@ -16089,6 +16089,10 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(CGM.getIntrinsic(IntrinsicID), Ops, "test_data_class"); } + case PPC::BI__builtin_ppc_swdiv: + case PPC::BI__builtin_ppc_swdivs: + return Builder.CreateFDiv(Ops[0], Ops[1], "swdiv"); + } } namespace { diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat-swdiv.c b/clang/test/CodeGen/builtins-ppc-xlcompat-swdiv.c new file mode 100644 index 0000000..33b3f14 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat-swdiv.c @@ -0,0 +1,80 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu \ +// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-aix \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | 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-linux-gnu -ffast-math -ffp-contract=fast \ +// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefix CHECK-OFAST + +extern double a; +extern double b; +extern float c; +extern float d; + +// CHECK-LABEL: @test_swdiv( +// CHECK: [[TMP0:%.*]] = load double, double* @a +// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @b +// CHECK-NEXT: [[SWDIV:%.*]] = fdiv double [[TMP0]], [[TMP1]] +// CHECK-NEXT: ret double [[SWDIV]] +// +// CHECK-OFAST-LABEL: @test_swdiv( +// CHECK-OFAST: [[TMP0:%.*]] = load double, double* @a +// CHECK-OFAST-NEXT: [[TMP1:%.*]] = load double, double* @b +// CHECK-OFAST-NEXT: [[SWDIV:%.*]] = fdiv fast double [[TMP0]], [[TMP1]] +// CHECK-OFAST-NEXT: ret double [[SWDIV]] +// +double test_swdiv() { + return __swdiv(a, b); +} + +// CHECK-LABEL: @test_swdivs( +// CHECK: [[TMP0:%.*]] = load float, float* @c +// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d +// CHECK-NEXT: [[SWDIVS:%.*]] = fdiv float [[TMP0]], [[TMP1]] +// CHECK-NEXT: ret float [[SWDIVS]] +// +// CHECK-OFAST-LABEL: @test_swdivs( +// CHECK-OFAST: [[TMP0:%.*]] = load float, float* @c +// CHECK-OFAST-NEXT: [[TMP1:%.*]] = load float, float* @d +// CHECK-OFAST-NEXT: [[SWDIVS:%.*]] = fdiv fast float [[TMP0]], [[TMP1]] +// CHECK-OFAST-NEXT: ret float [[SWDIVS]] +// +float test_swdivs() { + return __swdivs(c, d); +} + +// CHECK-LABEL: @test_builtin_ppc_swdiv( +// CHECK: [[TMP0:%.*]] = load double, double* @a +// CHECK-NEXT: [[TMP1:%.*]] = load double, double* @b +// CHECK-NEXT: [[SWDIV:%.*]] = fdiv double [[TMP0]], [[TMP1]] +// CHECK-NEXT: ret double [[SWDIV]] +// +// CHECK-OFAST-LABEL: @test_builtin_ppc_swdiv( +// CHECK-OFAST: [[TMP0:%.*]] = load double, double* @a +// CHECK-OFAST-NEXT: [[TMP1:%.*]] = load double, double* @b +// CHECK-OFAST-NEXT: [[SWDIV:%.*]] = fdiv fast double [[TMP0]], [[TMP1]] +// CHECK-OFAST-NEXT: ret double [[SWDIV]] +// +double test_builtin_ppc_swdiv() { + return __builtin_ppc_swdiv(a, b); +} + +// CHECK-LABEL: @test_builtin_ppc_swdivs( +// CHECK: [[TMP0:%.*]] = load float, float* @c +// CHECK-NEXT: [[TMP1:%.*]] = load float, float* @d +// CHECK-NEXT: [[SWDIVS:%.*]] = fdiv float [[TMP0]], [[TMP1]] +// CHECK-NEXT: ret float [[SWDIVS]] +// +// CHECK-OFAST-LABEL: @test_builtin_ppc_swdivs( +// CHECK-OFAST: [[TMP0:%.*]] = load float, float* @c +// CHECK-OFAST-NEXT: [[TMP1:%.*]] = load float, float* @d +// CHECK-OFAST-NEXT: [[SWDIVS:%.*]] = fdiv fast float [[TMP0]], [[TMP1]] +// CHECK-OFAST-NEXT: ret float [[SWDIVS]] +// +float test_builtin_ppc_swdivs() { + return __builtin_ppc_swdivs(c, d); +} diff --git a/llvm/test/CodeGen/PowerPC/fdiv.ll b/llvm/test/CodeGen/PowerPC/fdiv.ll index f55d7a7..3ea28ec 100644 --- a/llvm/test/CodeGen/PowerPC/fdiv.ll +++ b/llvm/test/CodeGen/PowerPC/fdiv.ll @@ -23,3 +23,16 @@ define dso_local float @foo(float %0, float %1) local_unnamed_addr { %3 = fdiv contract reassoc arcp nsz ninf float %0, %1 ret float %3 } + +define dso_local float @fdiv_fast(float %0, float %1) local_unnamed_addr { +; CHECK-LABEL: fdiv_fast: +; CHECK: # %bb.0: +; CHECK-NEXT: xsresp 3, 2 +; CHECK-NEXT: xsmulsp 0, 1, 3 +; CHECK-NEXT: xsnmsubasp 1, 2, 0 +; CHECK-NEXT: xsmaddasp 0, 3, 1 +; CHECK-NEXT: fmr 1, 0 +; CHECK-NEXT: blr + %3 = fdiv fast float %0, %1 + ret float %3 +}