Skip to content

Commit b20e796

Browse files
committed
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 b207529)
1 parent 7d0f1c7 commit b20e796

File tree

7 files changed

+211
-1
lines changed

7 files changed

+211
-1
lines changed

gcc/config.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,12 @@
672672
#endif
673673

674674

675+
/* Define if your assembler supports htm insns on power10. */
676+
#ifndef USED_FOR_TARGET
677+
#undef HAVE_AS_POWER10_HTM
678+
#endif
679+
680+
675681
/* Define if your assembler supports .ref */
676682
#ifndef USED_FOR_TARGET
677683
#undef HAVE_AS_REF

gcc/config/rs6000/rs6000.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25253,6 +25253,7 @@ rs6000_need_ipa_fn_target_info (const_tree decl,
2525325253
static bool
2525425254
rs6000_update_ipa_fn_target_info (unsigned int &info, const gimple *stmt)
2525525255
{
25256+
#ifndef HAVE_AS_POWER10_HTM
2525625257
/* Assume inline asm can use any instruction features. */
2525725258
if (gimple_code (stmt) == GIMPLE_ASM)
2525825259
{
@@ -25264,7 +25265,9 @@ rs6000_update_ipa_fn_target_info (unsigned int &info, const gimple *stmt)
2526425265
info |= RS6000_FN_TARGET_INFO_HTM;
2526525266
return false;
2526625267
}
25267-
else if (gimple_code (stmt) == GIMPLE_CALL)
25268+
#endif
25269+
25270+
if (gimple_code (stmt) == GIMPLE_CALL)
2526825271
{
2526925272
tree fndecl = gimple_call_fndecl (stmt);
2527025273
if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD))

gcc/configure

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27959,6 +27959,49 @@ if test $gcc_cv_as_powerpc_mfcrf = yes; then
2795927959

2796027960
$as_echo "#define HAVE_AS_MFCRF 1" >>confdefs.h
2796127961

27962+
fi
27963+
27964+
27965+
case $target in
27966+
*-*-aix*) conftest_s=' .machine "pwr10"
27967+
.csect .text[PR]
27968+
tend. 0';;
27969+
*-*-darwin*) conftest_s=' .text
27970+
tend. 0';;
27971+
*) conftest_s=' .machine power10
27972+
.text
27973+
tend. 0';;
27974+
esac
27975+
27976+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for htm support on Power10" >&5
27977+
$as_echo_n "checking assembler for htm support on Power10... " >&6; }
27978+
if ${gcc_cv_as_power10_htm+:} false; then :
27979+
$as_echo_n "(cached) " >&6
27980+
else
27981+
gcc_cv_as_power10_htm=no
27982+
if test x$gcc_cv_as != x; then
27983+
$as_echo "$conftest_s" > conftest.s
27984+
if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
27985+
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
27986+
(eval $ac_try) 2>&5
27987+
ac_status=$?
27988+
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
27989+
test $ac_status = 0; }; }
27990+
then
27991+
gcc_cv_as_power10_htm=yes
27992+
else
27993+
echo "configure: failed program was" >&5
27994+
cat conftest.s >&5
27995+
fi
27996+
rm -f conftest.o conftest.s
27997+
fi
27998+
fi
27999+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_power10_htm" >&5
28000+
$as_echo "$gcc_cv_as_power10_htm" >&6; }
28001+
if test $gcc_cv_as_power10_htm = yes; then
28002+
28003+
$as_echo "#define HAVE_AS_POWER10_HTM 1" >>confdefs.h
28004+
2796228005
fi
2796328006

2796428007

gcc/configure.ac

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5032,6 +5032,23 @@ gd:
50325032
[AC_DEFINE(HAVE_AS_MFCRF, 1,
50335033
[Define if your assembler supports mfcr field.])])
50345034

5035+
case $target in
5036+
*-*-aix*) conftest_s=' .machine "pwr10"
5037+
.csect .text[[PR]]
5038+
tend. 0';;
5039+
*-*-darwin*) conftest_s=' .text
5040+
tend. 0';;
5041+
*) conftest_s=' .machine power10
5042+
.text
5043+
tend. 0';;
5044+
esac
5045+
5046+
gcc_GAS_CHECK_FEATURE([htm support on Power10],
5047+
gcc_cv_as_power10_htm,,
5048+
[$conftest_s],,
5049+
[AC_DEFINE(HAVE_AS_POWER10_HTM, 1,
5050+
[Define if your assembler supports htm insns on power10.])])
5051+
50355052
case $target in
50365053
*-*-aix*) conftest_s=' .csect .text[[PR]]
50375054
LCF..0:
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* { dg-do compile } */
2+
/* { dg-require-effective-target powerpc_as_p10_htm } */
3+
/* Use -Wno-attributes to suppress the possible warning on always_inline. */
4+
/* { dg-options "-O2 -mdejagnu-cpu=power9 -Wno-attributes" } */
5+
6+
/* Verify it doesn't emit any error messages. */
7+
8+
#include <stddef.h>
9+
#define HWY_PRAGMA(tokens) _Pragma (#tokens)
10+
#define HWY_PUSH_ATTRIBUTES(targets_str) HWY_PRAGMA (GCC target targets_str)
11+
__attribute__ ((always_inline)) void
12+
PreventElision (int output)
13+
{
14+
asm("nop" : "+r"(output) : : "memory");
15+
}
16+
#define HWY_BEFORE_NAMESPACE() HWY_PUSH_ATTRIBUTES (",cpu=power10")
17+
HWY_BEFORE_NAMESPACE () namespace detail
18+
{
19+
template <typename, size_t, int> struct CappedTagChecker
20+
{
21+
};
22+
}
23+
template <typename T, size_t kLimit, int kPow2 = 0>
24+
using CappedTag = detail::CappedTagChecker<T, kLimit, kPow2>;
25+
template <typename, size_t, size_t kMinArg, class Test> struct ForeachCappedR
26+
{
27+
static void Do (size_t, size_t)
28+
{
29+
CappedTag<int, kMinArg> d;
30+
Test () (int(), d);
31+
}
32+
};
33+
template <class Test> struct ForPartialVectors
34+
{
35+
template <typename T> void operator() (T)
36+
{
37+
ForeachCappedR<T, 1, 1, Test>::Do (1, 1);
38+
}
39+
};
40+
struct TestFloorLog2
41+
{
42+
template <class T, class DF> void operator() (T, DF) { PreventElision (0x10); }
43+
};
44+
void
45+
TestAllFloorLog2 ()
46+
{
47+
ForPartialVectors<TestFloorLog2> () (float());
48+
}
49+
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/* { dg-do compile } */
2+
/* { dg-skip-if "HTM inline asm supported" { powerpc_as_p10_htm } } */
3+
/* Use -Wno-attributes to suppress the possible warning on always_inline. */
4+
/* { dg-options "-O2 -mdejagnu-cpu=power9 -Wno-attributes" } */
5+
6+
/* Verify it emits error messages on non-empty inline asm. */
7+
8+
#include <stddef.h>
9+
#define HWY_PRAGMA(tokens) _Pragma (#tokens)
10+
#define HWY_PUSH_ATTRIBUTES(targets_str) HWY_PRAGMA (GCC target targets_str)
11+
__attribute__ ((always_inline)) void
12+
PreventElision (int output) /* { dg-error "inlining failed in call to .* target specific option mismatch" } */
13+
{
14+
asm("nop" : "+r"(output) : : "memory");
15+
}
16+
#define HWY_BEFORE_NAMESPACE() HWY_PUSH_ATTRIBUTES (",cpu=power10")
17+
HWY_BEFORE_NAMESPACE () namespace detail
18+
{
19+
template <typename, size_t, int> struct CappedTagChecker
20+
{
21+
};
22+
}
23+
template <typename T, size_t kLimit, int kPow2 = 0>
24+
using CappedTag = detail::CappedTagChecker<T, kLimit, kPow2>;
25+
template <typename, size_t, size_t kMinArg, class Test> struct ForeachCappedR
26+
{
27+
static void Do (size_t, size_t)
28+
{
29+
CappedTag<int, kMinArg> d;
30+
Test () (int(), d);
31+
}
32+
};
33+
template <class Test> struct ForPartialVectors
34+
{
35+
template <typename T> void operator() (T)
36+
{
37+
ForeachCappedR<T, 1, 1, Test>::Do (1, 1);
38+
}
39+
};
40+
struct TestFloorLog2
41+
{
42+
template <class T, class DF> void operator() (T, DF)
43+
{
44+
PreventElision (0x10); /* { dg-message "called from here" } */
45+
}
46+
};
47+
void
48+
TestAllFloorLog2 ()
49+
{
50+
ForPartialVectors<TestFloorLog2> () (float());
51+
}
52+

gcc/testsuite/lib/target-supports.exp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11819,6 +11819,46 @@ proc check_effective_target_o_flag_in_section { } {
1181911819
}]
1182011820
}
1182111821

11822+
# Return 1 if the given assembler supports hardware transactional memory
11823+
# instructions with machine type Power10, 0 otherwise. Cache the result.
11824+
11825+
proc check_effective_target_powerpc_as_p10_htm { } {
11826+
global tool
11827+
global GCC_UNDER_TEST
11828+
11829+
# Need auto-host.h to check linker support.
11830+
if { ![file exists ../../auto-host.h ] } {
11831+
return 0
11832+
}
11833+
11834+
return [check_cached_effective_target powerpc_as_p10_htm {
11835+
11836+
set src pie[pid].c
11837+
set obj pie[pid].o
11838+
11839+
set f [open $src "w"]
11840+
puts $f "#include \"../../auto-host.h\""
11841+
puts $f "#if HAVE_AS_POWER10_HTM == 0"
11842+
puts $f "# error Assembler does not support htm insns with power10."
11843+
puts $f "#endif"
11844+
close $f
11845+
11846+
verbose "check_effective_target_powerpc_as_p10_htm compiling testfile $src" 2
11847+
set lines [${tool}_target_compile $src $obj object ""]
11848+
11849+
file delete $src
11850+
file delete $obj
11851+
11852+
if [string match "" $lines] then {
11853+
verbose "check_effective_target_powerpc_as_p10_htm testfile compilation passed" 2
11854+
return 1
11855+
} else {
11856+
verbose "check_effective_target_powerpc_as_p10_htm testfile compilation failed" 2
11857+
return 0
11858+
}
11859+
}]
11860+
}
11861+
1182211862
# return 1 if LRA is supported.
1182311863

1182411864
proc check_effective_target_lra { } {

0 commit comments

Comments
 (0)