[clang] c35ca3a - [PowerPC] Implement XL compat __fnabs and __fnabss builtins.

Amy Kwan via cfe-commits cfe-commits at lists.llvm.org
Thu May 19 09:29:30 PDT 2022


Author: Amy Kwan
Date: 2022-05-19T11:28:40-05:00
New Revision: c35ca3a1c78f693b749ad11742350b7fc6c5cd89

URL: https://github.com/llvm/llvm-project/commit/c35ca3a1c78f693b749ad11742350b7fc6c5cd89
DIFF: https://github.com/llvm/llvm-project/commit/c35ca3a1c78f693b749ad11742350b7fc6c5cd89.diff

LOG: [PowerPC] Implement XL compat __fnabs and __fnabss builtins.

This patch implements the following floating point negative absolute value
builtins that required for compatibility with the XL compiler:
```
double __fnabs(double);
float __fnabss(float);
```

These builtins will emit :
- fnabs on PWR6 and below, or if VSX is disabled.
- xsnabsdp on PWR7 and above, if VSX is enabled.

Differential Revision: https://reviews.llvm.org/D125506

Added: 
    clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.c
    llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.ll

Modified: 
    clang/include/clang/Basic/BuiltinsPPC.def
    clang/lib/Basic/Targets/PPC.cpp
    llvm/include/llvm/IR/IntrinsicsPowerPC.td
    llvm/lib/Target/PowerPC/P10InstrResources.td
    llvm/lib/Target/PowerPC/P9InstrResources.td
    llvm/lib/Target/PowerPC/PPCBack2BackFusion.def
    llvm/lib/Target/PowerPC/PPCInstrInfo.td
    llvm/lib/Target/PowerPC/PPCInstrVSX.td

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index 8a4c5b4eead27..923215cc3e5d0 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -159,6 +159,9 @@ BUILTIN(__builtin_ppc_maxfs, "ffff.", "t")
 BUILTIN(__builtin_ppc_minfe, "LdLdLdLd.", "t")
 BUILTIN(__builtin_ppc_minfl, "dddd.", "t")
 BUILTIN(__builtin_ppc_minfs, "ffff.", "t")
+// Floating Negative Absolute Value
+BUILTIN(__builtin_ppc_fnabs, "dd", "")
+BUILTIN(__builtin_ppc_fnabss, "ff", "")
 
 BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
 

diff  --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index dacb7eeea12a8..7de40b5db04a3 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -252,6 +252,8 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class");
   Builder.defineMacro("__swdiv", "__builtin_ppc_swdiv");
   Builder.defineMacro("__swdivs", "__builtin_ppc_swdivs");
+  Builder.defineMacro("__fnabs", "__builtin_ppc_fnabs");
+  Builder.defineMacro("__fnabss", "__builtin_ppc_fnabss");
   Builder.defineMacro("__builtin_maxfe", "__builtin_ppc_maxfe");
   Builder.defineMacro("__builtin_maxfl", "__builtin_ppc_maxfl");
   Builder.defineMacro("__builtin_maxfs", "__builtin_ppc_maxfs");

diff  --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.c
new file mode 100644
index 0000000000000..2889f38f01068
--- /dev/null
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.c
@@ -0,0 +1,36 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -target-cpu pwr8 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm %s -target-cpu pwr8 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -target-cpu pwr7 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm %s -target-cpu pwr7 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -target-cpu pwr6 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -target-cpu pwr6 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix \
+// RUN:   -emit-llvm %s -target-cpu pwr6 -o - | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-unknown-aix \
+// RUN:   -emit-llvm %s -target-cpu pwr6 -o - | FileCheck %s
+
+extern float f;
+extern double d;
+
+// CHECK-LABEL: @test_fnabs(
+// CHECK:       [[TMP0:%.*]] = load double, ptr @d
+// CHECK-NEXT:  [[TMP1:%.*]] = call double @llvm.ppc.fnabs(double [[TMP0]])
+// CHECK-NEXT:  ret double [[TMP1]]
+double test_fnabs() {
+  return __fnabs (d);
+}
+
+// CHECK-LABEL: @test_fnabss(
+// CHECK:       [[TMP0:%.*]] = load float, ptr @f
+// CHECK-NEXT:  [[TMP1:%.*]] = call float @llvm.ppc.fnabss(float [[TMP0]])
+// CHECK-NEXT:  ret float [[TMP1]]
+float test_fnabss() {
+  return __fnabss (f);
+}

diff  --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 8082b457242de..963f4c2dc475c 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -1801,6 +1801,12 @@ let TargetPrefix = "ppc" in {
   def int_ppc_test_data_class_f : Intrinsic<[llvm_i32_ty],
                                             [llvm_float_ty, llvm_i32_ty],
                                             [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+  def int_ppc_fnabs
+      : GCCBuiltin<"__builtin_ppc_fnabs">,
+        Intrinsic <[llvm_double_ty], [llvm_double_ty], [IntrNoMem]>;
+  def int_ppc_fnabss
+      : GCCBuiltin<"__builtin_ppc_fnabss">,
+        Intrinsic <[llvm_float_ty], [llvm_float_ty], [IntrNoMem]>;
 
   def int_ppc_convert_f128_to_ppcf128
       : Intrinsic<[llvm_ppcf128_ty], [llvm_f128_ty], [IntrNoMem]>;

diff  --git a/llvm/lib/Target/PowerPC/P10InstrResources.td b/llvm/lib/Target/PowerPC/P10InstrResources.td
index b3a91df2e8a0f..a6ba5adda8394 100644
--- a/llvm/lib/Target/PowerPC/P10InstrResources.td
+++ b/llvm/lib/Target/PowerPC/P10InstrResources.td
@@ -956,7 +956,7 @@ def : InstRW<[P10W_FX_3C, P10W_DISP_ANY, P10FX_Read],
     WAIT,
     XSABSDP,
     XSABSQP,
-    XSNABSDP,
+    XSNABSDP, XSNABSDPs,
     XSNABSQP,
     XSNEGDP,
     XSNEGQP,

diff  --git a/llvm/lib/Target/PowerPC/P9InstrResources.td b/llvm/lib/Target/PowerPC/P9InstrResources.td
index acb3585156ed7..2bbab64ce0da4 100644
--- a/llvm/lib/Target/PowerPC/P9InstrResources.td
+++ b/llvm/lib/Target/PowerPC/P9InstrResources.td
@@ -156,6 +156,7 @@ def : InstRW<[P9_ALU_2C, IP_EXEC_1C, DISP_1C],
     MCRF,
     MCRXRX,
     XSNABSDP,
+    XSNABSDPs,
     XSXEXPDP,
     XSABSDP,
     XSNEGDP,

diff  --git a/llvm/lib/Target/PowerPC/PPCBack2BackFusion.def b/llvm/lib/Target/PowerPC/PPCBack2BackFusion.def
index 38ed5f2e78e3a..f1eecfea5a5e9 100644
--- a/llvm/lib/Target/PowerPC/PPCBack2BackFusion.def
+++ b/llvm/lib/Target/PowerPC/PPCBack2BackFusion.def
@@ -434,6 +434,7 @@ FUSION_FEATURE(GeneralBack2Back, hasBack2BackFusion, -1,
     XSMINDP,
     XSMINJDP,
     XSNABSDP,
+    XSNABSDPs,
     XSNABSQP,
     XSNEGDP,
     XSNEGQP,
@@ -978,6 +979,7 @@ FUSION_FEATURE(GeneralBack2Back, hasBack2BackFusion, -1,
     XSMINDP,
     XSMINJDP,
     XSNABSDP,
+    XSNABSDPs,
     XSNABSQP,
     XSNEGDP,
     XSNEGQP,

diff  --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 11b70000cd6f6..399c9567cd2d2 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -3240,6 +3240,8 @@ def : Pat<(int_ppc_fnmadd f64:$A, f64:$B, f64:$C), (FNMADD $A, $B, $C)>;
 def : Pat<(int_ppc_fnmadds f32:$A, f32:$B, f32:$C), (FNMADDS $A, $B, $C)>;
 def : Pat<(int_ppc_fre f64:$A), (FRE $A)>;
 def : Pat<(int_ppc_fres f32:$A), (FRES $A)>;
+def : Pat<(int_ppc_fnabs f64:$A), (FNABSD $A)>;
+def : Pat<(int_ppc_fnabss f32:$A), (FNABSS $A)>;
 
 include "PPCInstrAltivec.td"
 include "PPCInstrSPE.td"

diff  --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
index 417a2cc3e679d..1e87af516e52b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
@@ -703,6 +703,11 @@ let hasSideEffects = 0 in {
                       (outs vsfrc:$XT), (ins vsfrc:$XB),
                       "xsnabsdp $XT, $XB", IIC_VecFP,
                       [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
+  let isCodeGenOnly = 1 in
+  def XSNABSDPs : XX2Form<60, 361,
+                      (outs vssrc:$XT), (ins vssrc:$XB),
+                      "xsnabsdp $XT, $XB", IIC_VecFP,
+                      [(set f32:$XT, (fneg (fabs f32:$XB)))]>;
   def XSNEGDP : XX2Form<60, 377,
                       (outs vsfrc:$XT), (ins vsfrc:$XB),
                       "xsnegdp $XT, $XB", IIC_VecFP,
@@ -2871,6 +2876,8 @@ def : Pat<(int_ppc_fmsub f64:$A, f64:$B, f64:$C), (XSMSUBMDP $A, $B, $C)>;
 def : Pat<(int_ppc_fnmadd f64:$A, f64:$B, f64:$C), (XSNMADDMDP $A, $B, $C)>;
 def : Pat<(int_ppc_fre f64:$A), (XSREDP $A)>;
 def : Pat<(int_ppc_frsqrte vsfrc:$XB), (XSRSQRTEDP $XB)>;
+def : Pat<(int_ppc_fnabs f64:$A), (XSNABSDP $A)>;
+def : Pat<(int_ppc_fnabss f32:$A), (XSNABSDPs $A)>;
 
 // XXMRG[LH]W is a direct replacement for VMRG[LH]W respectively.
 // Prefer the VSX form for greater register range.

diff  --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.ll
new file mode 100644
index 0000000000000..f4bf063066a54
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-xlcompat-fnabs.ll
@@ -0,0 +1,63 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -mcpu=pwr8 < %s | \
+; RUN: FileCheck %s --check-prefix=CHECK-DEFAULT
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -mcpu=pwr8 \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s \
+; RUN:   --check-prefix=CHECK-DEFAULT
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -mcpu=pwr7 \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s \
+; RUN:   --check-prefix=CHECK-DEFAULT
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix -mcpu=pwr7 \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s \
+; RUN:   --check-prefix=CHECK-DEFAULT
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -mcpu=pwr6 \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -mattr=+vsx < %s | \
+; RUN: FileCheck %s --check-prefix=CHECK-DEFAULT
+
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -mcpu=pwr6 < %s | \
+; RUN: FileCheck %s --check-prefix=CHECK-NOVSX
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -mcpu=pwr6 < %s | \
+; RUN: FileCheck %s --check-prefix=CHECK-NOVSX
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -mcpu=pwr8 \
+; RUN:   -mattr=-vsx < %s | FileCheck %s --check-prefix=CHECK-NOVSX
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-aix \
+; RUN:   -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names -mcpu=pwr8 \
+; RUN:   -mattr=-vsx < %s | FileCheck %s --check-prefix=CHECK-NOVSX
+
+declare double @llvm.ppc.fnabs(double)
+declare float @llvm.ppc.fnabss(float)
+
+define double @test_fnabs2(double %d) {
+; CHECK-DEFAULT-LABEL: test_fnabs2:
+; CHECK-DEFAULT:       # %bb.0: # %entry
+; CHECK-DEFAULT-NEXT:    xsnabsdp f1, f1
+; CHECK-DEFAULT-NEXT:    blr
+;
+; CHECK-NOVSX-LABEL: test_fnabs2:
+; CHECK-NOVSX:       # %bb.0: # %entry
+; CHECK-NOVSX-NEXT:    fnabs f1, f1
+; CHECK-NOVSX-NEXT:    blr
+entry:
+  %0 = tail call double @llvm.ppc.fnabs(double %d)
+  ret double %0
+}
+
+define float @test_fnabss(float %f) {
+; CHECK-DEFAULT-LABEL: test_fnabss:
+; CHECK-DEFAULT:       # %bb.0: # %entry
+; CHECK-DEFAULT-NEXT:    xsnabsdp f1, f1
+; CHECK-DEFAULT-NEXT:    blr
+;
+; CHECK-NOVSX-LABEL: test_fnabss:
+; CHECK-NOVSX:       # %bb.0: # %entry
+; CHECK-NOVSX-NEXT:    fnabs f1, f1
+; CHECK-NOVSX-NEXT:    blr
+entry:
+  %0 = tail call float @llvm.ppc.fnabss(float %f)
+  ret float %0
+}
+


        


More information about the cfe-commits mailing list