public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-8070] rs6000: Consider inline asm as safe if no assembler complains [PR111828]
@ 2023-11-15  9:27 Kewen Lin
  0 siblings, 0 replies; only message in thread
From: Kewen Lin @ 2023-11-15  9:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:63690ce8174c8b8d13e8d1a1f01b19e4f6d93e9e

commit r13-8070-g63690ce8174c8b8d13e8d1a1f01b19e4f6d93e9e
Author: Kewen Lin <linkw@linux.ibm.com>
Date:   Mon Nov 6 00:14:43 2023 -0600

    rs6000: Consider inline asm as safe if no assembler complains [PR111828]
    
    As discussed in PR111828, rs6000_update_ipa_fn_target_info
    is much conservative, currently for any non-empty inline
    asm, without any parsing, it would take inline asm could
    have HTM insns.  It means for one function attributed with
    power8 having inline asm, even if it has no HTM insns, we
    don't make a function attributed with power10 inline it.
    
    Peter pointed out an inline asm parser can be a slippery
    slope, and noticed that the current gnu assembler still
    allows HTM insns even with power10 machine type, so he
    suggested that we can aggressively ignore the handling on
    inline asm, this patch goes for this suggestion.
    
    Considering that there are a few assembler alternatives
    and assembler can update its behaviors (complaining HTM
    insns at power10 and later cpus sounds reasonable from a
    certain point of view), this patch also checks assembler
    complains on HTM insns at power10 or not.  For a case that
    a caller attributed power10 calls a callee attributed
    power8 having inline asm with HTM insn, without inlining
    at least the compilation succeeds, but if assembler
    complains HTM insns at power10, after inlining the
    compilation would fail.
    
    The two associated test cases are fine without and with
    this patch (effective target takes effect or not).
    
            PR target/111828
    
    gcc/ChangeLog:
    
            * config.in: Regenerate.
            * config/rs6000/rs6000.cc (rs6000_update_ipa_fn_target_info): Guard
            inline asm handling under !HAVE_AS_POWER10_HTM.
            * configure: Regenerate.
            * configure.ac: Detect assembler support for HTM insns at power10.
    
    gcc/testsuite/ChangeLog:
    
            * lib/target-supports.exp
            (check_effective_target_powerpc_as_p10_htm): New proc.
            * g++.target/powerpc/pr111828-1.C: New test.
            * g++.target/powerpc/pr111828-2.C: New test.
    
    (cherry picked from commit b2075291af8810794c7184fd125b991c2341cb1e)

Diff:
---
 gcc/config.in                                 |  6 ++++
 gcc/config/rs6000/rs6000.cc                   |  5 ++-
 gcc/configure                                 | 43 ++++++++++++++++++++++
 gcc/configure.ac                              | 17 +++++++++
 gcc/testsuite/g++.target/powerpc/pr111828-1.C | 49 +++++++++++++++++++++++++
 gcc/testsuite/g++.target/powerpc/pr111828-2.C | 52 +++++++++++++++++++++++++++
 gcc/testsuite/lib/target-supports.exp         | 40 +++++++++++++++++++++
 7 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/gcc/config.in b/gcc/config.in
index 4cad077bfbe..ef35af16f2f 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -678,6 +678,12 @@
 #endif
 
 
+/* Define if your assembler supports htm insns on power10. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_POWER10_HTM
+#endif
+
+
 /* Define if your assembler supports .ref */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_REF
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 063bb0242bf..e5ceff3a61b 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -25412,6 +25412,7 @@ rs6000_need_ipa_fn_target_info (const_tree decl,
 static bool
 rs6000_update_ipa_fn_target_info (unsigned int &info, const gimple *stmt)
 {
+#ifndef HAVE_AS_POWER10_HTM
   /* Assume inline asm can use any instruction features.  */
   if (gimple_code (stmt) == GIMPLE_ASM)
     {
@@ -25423,7 +25424,9 @@ rs6000_update_ipa_fn_target_info (unsigned int &info, const gimple *stmt)
 	info |= RS6000_FN_TARGET_INFO_HTM;
       return false;
     }
-  else if (gimple_code (stmt) == GIMPLE_CALL)
+#endif
+
+  if (gimple_code (stmt) == GIMPLE_CALL)
     {
       tree fndecl = gimple_call_fndecl (stmt);
       if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD))
diff --git a/gcc/configure b/gcc/configure
index c7b26d1927d..0ab71aa3bcd 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -28077,6 +28077,49 @@ if test $gcc_cv_as_powerpc_mfcrf = yes; then
 
 $as_echo "#define HAVE_AS_MFCRF 1" >>confdefs.h
 
+fi
+
+
+    case $target in
+      *-*-aix*) conftest_s='	.machine "pwr10"
+	.csect .text[PR]
+	tend. 0';;
+      *-*-darwin*) conftest_s='	.text
+	tend. 0';;
+      *) conftest_s='	.machine power10
+	.text
+	tend. 0';;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for htm support on Power10" >&5
+$as_echo_n "checking assembler for htm support on Power10... " >&6; }
+if ${gcc_cv_as_power10_htm+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_power10_htm=no
+  if test x$gcc_cv_as != x; then
+    $as_echo "$conftest_s" > conftest.s
+    if { ac_try='$gcc_cv_as $gcc_cv_as_flags  -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+	gcc_cv_as_power10_htm=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_power10_htm" >&5
+$as_echo "$gcc_cv_as_power10_htm" >&6; }
+if test $gcc_cv_as_power10_htm = yes; then
+
+$as_echo "#define HAVE_AS_POWER10_HTM 1" >>confdefs.h
+
 fi
 
 
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 09082e8ccae..fcd45f54c7d 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -5032,6 +5032,23 @@ gd:
       [AC_DEFINE(HAVE_AS_MFCRF, 1,
 	  [Define if your assembler supports mfcr field.])])
 
+    case $target in
+      *-*-aix*) conftest_s='	.machine "pwr10"
+	.csect .text[[PR]]
+	tend. 0';;
+      *-*-darwin*) conftest_s='	.text
+	tend. 0';;
+      *) conftest_s='	.machine power10
+	.text
+	tend. 0';;
+    esac
+
+    gcc_GAS_CHECK_FEATURE([htm support on Power10],
+      gcc_cv_as_power10_htm,,
+      [$conftest_s],,
+      [AC_DEFINE(HAVE_AS_POWER10_HTM, 1,
+	  [Define if your assembler supports htm insns on power10.])])
+
     case $target in
       *-*-aix*) conftest_s='	.csect .text[[PR]]
 LCF..0:
diff --git a/gcc/testsuite/g++.target/powerpc/pr111828-1.C b/gcc/testsuite/g++.target/powerpc/pr111828-1.C
new file mode 100644
index 00000000000..d76a084bdcf
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/pr111828-1.C
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_as_p10_htm } */
+/* Use -Wno-attributes to suppress the possible warning on always_inline.  */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -Wno-attributes" } */
+
+/* Verify it doesn't emit any error messages.  */
+
+#include <stddef.h>
+#define HWY_PRAGMA(tokens) _Pragma (#tokens)
+#define HWY_PUSH_ATTRIBUTES(targets_str) HWY_PRAGMA (GCC target targets_str)
+__attribute__ ((always_inline)) void
+PreventElision (int output)
+{
+  asm("nop" : "+r"(output) : : "memory");
+}
+#define HWY_BEFORE_NAMESPACE() HWY_PUSH_ATTRIBUTES (",cpu=power10")
+HWY_BEFORE_NAMESPACE () namespace detail
+{
+  template <typename, size_t, int> struct CappedTagChecker
+  {
+  };
+}
+template <typename T, size_t kLimit, int kPow2 = 0>
+using CappedTag = detail::CappedTagChecker<T, kLimit, kPow2>;
+template <typename, size_t, size_t kMinArg, class Test> struct ForeachCappedR
+{
+  static void Do (size_t, size_t)
+  {
+    CappedTag<int, kMinArg> d;
+    Test () (int(), d);
+  }
+};
+template <class Test> struct ForPartialVectors
+{
+  template <typename T> void operator() (T)
+  {
+    ForeachCappedR<T, 1, 1, Test>::Do (1, 1);
+  }
+};
+struct TestFloorLog2
+{
+  template <class T, class DF> void operator() (T, DF) { PreventElision (0x10); }
+};
+void
+TestAllFloorLog2 ()
+{
+  ForPartialVectors<TestFloorLog2> () (float());
+}
+
diff --git a/gcc/testsuite/g++.target/powerpc/pr111828-2.C b/gcc/testsuite/g++.target/powerpc/pr111828-2.C
new file mode 100644
index 00000000000..0b7331675f7
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/pr111828-2.C
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-skip-if "HTM inline asm supported" { powerpc_as_p10_htm } } */
+/* Use -Wno-attributes to suppress the possible warning on always_inline.  */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -Wno-attributes" } */
+
+/* Verify it emits error messages on non-empty inline asm.  */
+
+#include <stddef.h>
+#define HWY_PRAGMA(tokens) _Pragma (#tokens)
+#define HWY_PUSH_ATTRIBUTES(targets_str) HWY_PRAGMA (GCC target targets_str)
+__attribute__ ((always_inline)) void
+PreventElision (int output) /* { dg-error "inlining failed in call to .* target specific option mismatch" } */
+{
+  asm("nop" : "+r"(output) : : "memory");
+}
+#define HWY_BEFORE_NAMESPACE() HWY_PUSH_ATTRIBUTES (",cpu=power10")
+HWY_BEFORE_NAMESPACE () namespace detail
+{
+  template <typename, size_t, int> struct CappedTagChecker
+  {
+  };
+}
+template <typename T, size_t kLimit, int kPow2 = 0>
+using CappedTag = detail::CappedTagChecker<T, kLimit, kPow2>;
+template <typename, size_t, size_t kMinArg, class Test> struct ForeachCappedR
+{
+  static void Do (size_t, size_t)
+  {
+    CappedTag<int, kMinArg> d;
+    Test () (int(), d);
+  }
+};
+template <class Test> struct ForPartialVectors
+{
+  template <typename T> void operator() (T)
+  {
+    ForeachCappedR<T, 1, 1, Test>::Do (1, 1);
+  }
+};
+struct TestFloorLog2
+{
+  template <class T, class DF> void operator() (T, DF)
+  {
+    PreventElision (0x10); /* { dg-message "called from here" } */
+  }
+};
+void
+TestAllFloorLog2 ()
+{
+  ForPartialVectors<TestFloorLog2> () (float());
+}
+
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 40f71e9ed8b..4d6bf2eb8d3 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12263,6 +12263,46 @@ proc check_effective_target_o_flag_in_section { } {
     }]
 }
 
+# Return 1 if the given assembler supports hardware transactional memory
+# instructions with machine type Power10, 0 otherwise.  Cache the result.
+
+proc check_effective_target_powerpc_as_p10_htm { } {
+    global tool
+    global GCC_UNDER_TEST
+
+    # Need auto-host.h to check linker support.
+    if { ![file exists ../../auto-host.h ] } {
+	return 0
+    }
+
+    return [check_cached_effective_target powerpc_as_p10_htm {
+
+	set src pie[pid].c
+	set obj pie[pid].o
+
+	set f [open $src "w"]
+	puts $f "#include \"../../auto-host.h\""
+	puts $f "#if HAVE_AS_POWER10_HTM == 0"
+	puts $f "# error Assembler does not support htm insns with power10."
+	puts $f "#endif"
+	close $f
+
+	verbose "check_effective_target_powerpc_as_p10_htm compiling testfile $src" 2
+	set lines [${tool}_target_compile $src $obj object ""]
+
+	file delete $src
+	file delete $obj
+
+	if [string match "" $lines] then {
+	    verbose "check_effective_target_powerpc_as_p10_htm testfile compilation passed" 2
+	    return 1
+	} else {
+	    verbose "check_effective_target_powerpc_as_p10_htm testfile compilation failed" 2
+	    return 0
+	}
+    }]
+}
+
 # return 1 if LRA is supported.
 
 proc check_effective_target_lra { } {

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-15  9:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-15  9:27 [gcc r13-8070] rs6000: Consider inline asm as safe if no assembler complains [PR111828] Kewen Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).