https://gcc.gnu.org/g:4bcf1f72c6990970a59ca10de39c57e19230cfe0
commit r16-6255-g4bcf1f72c6990970a59ca10de39c57e19230cfe0 Author: Oleg Endo <[email protected]> Date: Tue Oct 8 12:30:42 2024 +0900 SH: Add test case from PR55212 c#298 / c#311 / att. 59185 gcc/testsuite/ChangeLog: PR target/55212 * g++.target/sh/sh.exp: New. * g++.target/sh/torture/sh-torture.exp: New. * g++.target/sh/torture/pr55212-c311.C: New Diff: --- gcc/testsuite/g++.target/sh/sh.exp | 297 ++++++++++++++++++++ gcc/testsuite/g++.target/sh/torture/pr55212-c311.C | 73 +++++ gcc/testsuite/g++.target/sh/torture/sh-torture.exp | 299 +++++++++++++++++++++ 3 files changed, 669 insertions(+) diff --git a/gcc/testsuite/g++.target/sh/sh.exp b/gcc/testsuite/g++.target/sh/sh.exp new file mode 100644 index 000000000000..45c5b3738575 --- /dev/null +++ b/gcc/testsuite/g++.target/sh/sh.exp @@ -0,0 +1,297 @@ +# Copyright (C) 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an SH target. +if ![istarget sh*-*-*] then { + return +} + +# Load support procs. +load_lib g++-dg.exp + +# Return 1 if target is SH2A +proc check_effective_target_sh2a { } { + return [check_no_compiler_messages sh2a object { + #ifndef __SH2A__ + #error "" + #endif + } ""] +} + +# Return 1 if target is SH1 +proc check_effective_target_sh1 { } { + return [check_no_compiler_messages sh1 object { + #ifndef __SH1__ + #error "" + #endif + } ""] +} + +# Return 1 if target is SH4A +proc check_effective_target_sh4a { } { + return [check_no_compiler_messages sh4a object { + #ifndef __SH4A__ + #error "" + #endif + } ""] +} + +# Return 1 if target is big endian +proc check_effective_target_big_endian { } { + return [check_no_compiler_messages big_endian object { + #if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ + #error "" + #endif + } ""] +} + +# Return 1 if target is little endian +proc check_effective_target_little_endian { } { + return [check_no_compiler_messages little_endian object { + #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + #error "" + #endif + } ""] +} + +# Return 1 if the target has any FPU (single or double precision) +proc check_effective_target_any_fpu { } { + return [check_no_compiler_messages any_fpu object { + #ifndef __SH_FPU_ANY__ + #error "" + #endif + } ""] +} + +# Return 1 if the target has a double precision FPU which is allowed to be +# used by the compiler as such. +proc check_effective_target_double_fpu { } { + return [check_no_compiler_messages double_fpu object { + #ifndef __SH_FPU_DOUBLE__ + #error "" + #endif + } ""] +} + +# Return 1 if the target has a double precision FPU but it is only being used +# in single precision mode by the compiler +proc check_effective_target_use_single_only_fpu { } { + return [check_no_compiler_messages use_single_only_fpu object { + #if !(defined (__SH2A_SINGLE_ONLY__) \ + || defined (__SH4_SINGLE_ONLY__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target has an FPU and the default mode is single +proc check_effective_target_default_single_fpu { } { + return [check_no_compiler_messages default_single_fpu object { + #if !(defined (__SH2E__) || defined (__SH3E__) \ + || defined (__SH2A_SINGLE__) \ + || defined (__SH2A_SINGLE_ONLY__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target has no FPU +proc check_effective_target_no_fpu { } { + return [check_no_compiler_messages no_fpu object { + #ifdef __SH_FPU_ANY__ + #error "" + #endif + } ""] +} + + +# Return 1 if the target has XF regs +proc check_effective_target_has_xf_regs { } { + return [check_no_compiler_messages has_xf_regs object { + #if !(defined (__SH_FPU_ANY__) \ + && (defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__))) + #error "" + #endif + } ""] +} + + +# Return 1 if the target can do the fsca insn +proc check_effective_target_has_fsca { } { + return [check_no_compiler_messages has_fsca object { + #if !(defined (__SH_FPU_ANY__) \ + && (defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__))) + #error "" + #endif + } ""] +} + +# Return 1 if the target can do the fsrra insn +proc check_effective_target_has_fsrra { } { + return [check_no_compiler_messages has_fsrra object { + #if !(defined (__SH_FPU_ANY__) \ + && (defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__))) + #error "" + #endif + } ""] +} + +# Return 1 if the target can do the fpchg insn +proc check_effective_target_has_fpchg { } { + return [check_no_compiler_messages has_fpchg object { + #if !(defined (__SH4A__) && defined (__SH_FPU_ANY__) \ + && !defined (__SH4_SINGLE_ONLY__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target can do dynamic shifts +proc check_effective_target_has_dyn_shift { } { + return [check_no_compiler_messages has_dyn_shift object { + #if !(defined (__SH3__) \ + || defined (__SH3E__) \ + || defined (__SH2A__) \ + || defined (__SH4__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if the mfmovd option is enabled +proc check_effective_target_fmovd_enabled { } { + return [check_no_compiler_messages fmovd_enabled object { + #ifndef __FMOVD_ENABLED__ + #error "" + #endif + } ""] +} + +# Return 1 if the target supports privileged mode +proc check_effective_target_has_privileged { } { + return [check_no_compiler_messages has_privileged object { + #if !(defined (__SH3__) \ + || defined (__SH3E__) \ + || defined (__SH4__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target supports the prefetch insn +proc check_effective_target_has_pref { } { + return [check_no_compiler_messages has_pref object { + #if !(defined (__SH3__) \ + || defined (__SH3E__) \ + || defined (__SH4__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if target does banked r0..r7 regs type of ISRs +proc check_effective_target_banked_r0r7_isr { } { + return [check_no_compiler_messages banked_r0r7_isr object { + #if !(defined (__SH3__) || defined (__SH3E__) \ + || defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if target does stack only type of ISRs +proc check_effective_target_stack_save_isr { } { + return [check_no_compiler_messages stack_save_isr object { + #if !(defined (__SH1__) \ + || defined (__SH2__) \ + || defined (__SH2E__) \ + || defined (__SH2A__)) + #error "" + #endif + } ""] +} + +# Return 1 if target supports atomic-model=soft-gusa +proc check_effective_target_atomic_model_soft_gusa_available { } { + return [check_no_compiler_messages atomic_model_soft_gusa_available object { + int x = 0; + } "-matomic-model=soft-gusa"] +} + +# Return 1 if target supports atomic-model=soft-tcb +proc check_effective_target_atomic_model_soft_tcb_available { } { + return [check_no_compiler_messages atomic_model_soft_tcb_available object { + int x = 0; + } "-matomic-model=soft-tcb,gbr-offset=0"] +} + +# Return 1 if target supports atomic-model=soft-imask +proc check_effective_target_atomic_model_soft_imask_available { } { + return [check_no_compiler_messages atomic_model_soft_imask_available object { + int x = 0; + } "-matomic-model=soft-imask -mno-usermode"] +} + +# Return 1 if target supports atomic-model=hard-llcs +proc check_effective_target_atomic_model_hard_llcs_available { } { + return [check_no_compiler_messages atomic_model_hard_llcs_available object { + int x = 0; + } "-matomic-model=hard-llcs"] +} + +# If a testcase doesn't have special options, use these. +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" $DEFAULT_CXXFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/g++.target/sh/torture/pr55212-c311.C b/gcc/testsuite/g++.target/sh/torture/pr55212-c311.C new file mode 100644 index 000000000000..cc31dbcc4436 --- /dev/null +++ b/gcc/testsuite/g++.target/sh/torture/pr55212-c311.C @@ -0,0 +1,73 @@ +/* { dg-additional-options "-mlra -fpic" } */ +/* { dg-do compile } */ + + +typedef signed int int32_t; +typedef signed long long int int64_t; +static constexpr int32_t SK_MaxS32 = 214748364;; +static constexpr int32_t SK_MinS32 = -SK_MaxS32; + +extern double fabs (double __x) noexcept (true) __attribute__ ((__const__)); + +namespace std __attribute__ ((__visibility__ ("default"))) +{ +using ::fabs; + +template<typename _Tp> [[__nodiscard__]] constexpr inline const _Tp& min(const _Tp& __a, const _Tp& __b) +{ + if (__b < __a) return __b; + return __a; +} + +template<typename _Tp> [[__nodiscard__]] constexpr inline const _Tp& max(const _Tp& __a, const _Tp& __b) +{ + return __a; +} + +} + + +static constexpr int32_t Sk64_pin_to_s32(int64_t x) +{ + return x < SK_MinS32 ? SK_MinS32 : (x > SK_MaxS32 ? SK_MaxS32 : (int32_t)x); +} + +static constexpr int32_t Sk32_sat_sub(int32_t a, int32_t b) +{ + return Sk64_pin_to_s32((int64_t)a - (int64_t)b); +}; + +struct SkPoint +{ + float fX; + float fY; +}; + +typedef float SkScalar; +static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance = (1.0f / (1 << 12))) +{ + return std::fabs(x-y) <= tolerance; +} + +class SkCubicMap +{ +public: + SkCubicMap(SkPoint p1, SkPoint p2); +private: + enum Type + { + kLine_Type, kCubeRoot_Type, kSolver_Type, + }; + + Type fType; +}; + +SkCubicMap::SkCubicMap(SkPoint p1, SkPoint p2) +{ + p1.fX = std::min(std::max(p1.fX, 0.0f), 1.0f); + p2.fX = std::min(std::max(p2.fX, 0.0f), 1.0f); + if (SkScalarNearlyEqual(p1.fX, p1.fY) && SkScalarNearlyEqual(p2.fX, p2.fY)) + { + fType = kLine_Type; + } +} diff --git a/gcc/testsuite/g++.target/sh/torture/sh-torture.exp b/gcc/testsuite/g++.target/sh/torture/sh-torture.exp new file mode 100644 index 000000000000..8be516ebd25a --- /dev/null +++ b/gcc/testsuite/g++.target/sh/torture/sh-torture.exp @@ -0,0 +1,299 @@ +# Copyright (C) 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `gcc-dg.exp' driver, looping over +# optimization options. + +# Exit immediately if this isn't an SH target. +if { ![istarget sh*-*-*] } then { + return +} + +# Load support procs. +load_lib g++-dg.exp + +# Return 1 if target is SH2A +proc check_effective_target_sh2a { } { + return [check_no_compiler_messages sh2a object { + #ifndef __SH2A__ + #error "" + #endif + } ""] +} + +# Return 1 if target is SH1 +proc check_effective_target_sh1 { } { + return [check_no_compiler_messages sh1 object { + #ifndef __SH1__ + #error "" + #endif + } ""] +} + +# Return 1 if target is SH4A +proc check_effective_target_sh4a { } { + return [check_no_compiler_messages sh4a object { + #ifndef __SH4A__ + #error "" + #endif + } ""] +} + +# Return 1 if target is big endian +proc check_effective_target_big_endian { } { + return [check_no_compiler_messages big_endian object { + #if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ + #error "" + #endif + } ""] +} + +# Return 1 if target is little endian +proc check_effective_target_little_endian { } { + return [check_no_compiler_messages little_endian object { + #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + #error "" + #endif + } ""] +} + +# Return 1 if the target has any FPU (single or double precision) +proc check_effective_target_any_fpu { } { + return [check_no_compiler_messages any_fpu object { + #ifndef __SH_FPU_ANY__ + #error "" + #endif + } ""] +} + +# Return 1 if the target has a double precision FPU which is allowed to be +# used by the compiler as such. +proc check_effective_target_double_fpu { } { + return [check_no_compiler_messages double_fpu object { + #ifndef __SH_FPU_DOUBLE__ + #error "" + #endif + } ""] +} + +# Return 1 if the target has a double precision FPU but it is only being used +# in single precision mode by the compiler +proc check_effective_target_use_single_only_fpu { } { + return [check_no_compiler_messages use_single_only_fpu object { + #if !(defined (__SH2A_SINGLE_ONLY__) \ + || defined (__SH4_SINGLE_ONLY__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target has an FPU and the default mode is single +proc check_effective_target_default_single_fpu { } { + return [check_no_compiler_messages default_single_fpu object { + #if !(defined (__SH2E__) || defined (__SH3E__) \ + || defined (__SH2A_SINGLE__) \ + || defined (__SH2A_SINGLE_ONLY__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target has no FPU +proc check_effective_target_no_fpu { } { + return [check_no_compiler_messages no_fpu object { + #ifdef __SH_FPU_ANY__ + #error "" + #endif + } ""] +} + + +# Return 1 if the target has XF regs +proc check_effective_target_has_xf_regs { } { + return [check_no_compiler_messages has_xf_regs object { + #if !(defined (__SH_FPU_ANY__) \ + && (defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__))) + #error "" + #endif + } ""] +} + + +# Return 1 if the target can do the fsca insn +proc check_effective_target_has_fsca { } { + return [check_no_compiler_messages has_fsca object { + #if !(defined (__SH_FPU_ANY__) \ + && (defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__))) + #error "" + #endif + } ""] +} + +# Return 1 if the target can do the fsrra insn +proc check_effective_target_has_fsrra { } { + return [check_no_compiler_messages has_fsrra object { + #if !(defined (__SH_FPU_ANY__) \ + && (defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__))) + #error "" + #endif + } ""] +} + +# Return 1 if the target can do the fpchg insn +proc check_effective_target_has_fpchg { } { + return [check_no_compiler_messages has_fpchg object { + #if !(defined (__SH4A__) && defined (__SH_FPU_ANY__) \ + && !defined (__SH4_SINGLE_ONLY__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target can do dynamic shifts +proc check_effective_target_has_dyn_shift { } { + return [check_no_compiler_messages has_dyn_shift object { + #if !(defined (__SH3__) \ + || defined (__SH3E__) \ + || defined (__SH2A__) \ + || defined (__SH4__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if the mfmovd option is enabled +proc check_effective_target_fmovd_enabled { } { + return [check_no_compiler_messages fmovd_enabled object { + #ifndef __FMOVD_ENABLED__ + #error "" + #endif + } ""] +} + +# Return 1 if the target supports privileged mode +proc check_effective_target_has_privileged { } { + return [check_no_compiler_messages has_privileged object { + #if !(defined (__SH3__) \ + || defined (__SH3E__) \ + || defined (__SH4__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if the target supports the prefetch insn +proc check_effective_target_has_pref { } { + return [check_no_compiler_messages has_pref object { + #if !(defined (__SH3__) \ + || defined (__SH3E__) \ + || defined (__SH4__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if target does banked r0..r7 regs type of ISRs +proc check_effective_target_banked_r0r7_isr { } { + return [check_no_compiler_messages banked_r0r7_isr object { + #if !(defined (__SH3__) || defined (__SH3E__) \ + || defined (__SH4__) \ + || defined (__SH4_SINGLE__) \ + || defined (__SH4_SINGLE_ONLY__) \ + || defined (__SH4_NOFPU__) \ + || defined (__SH4A__)) + #error "" + #endif + } ""] +} + +# Return 1 if target does stack only type of ISRs +proc check_effective_target_stack_save_isr { } { + return [check_no_compiler_messages stack_save_isr object { + #if !(defined (__SH1__) \ + || defined (__SH2__) \ + || defined (__SH2E__) \ + || defined (__SH2A__)) + #error "" + #endif + } ""] +} + +# Return 1 if target supports atomic-model=soft-gusa +proc check_effective_target_atomic_model_soft_gusa_available { } { + return [check_no_compiler_messages atomic_model_soft_gusa_available object { + int x = 0; + } "-matomic-model=soft-gusa"] +} + +# Return 1 if target supports atomic-model=soft-tcb +proc check_effective_target_atomic_model_soft_tcb_available { } { + return [check_no_compiler_messages atomic_model_soft_tcb_available object { + int x = 0; + } "-matomic-model=soft-tcb,gbr-offset=0"] +} + +# Return 1 if target supports atomic-model=soft-imask +proc check_effective_target_atomic_model_soft_imask_available { } { + return [check_no_compiler_messages atomic_model_soft_imask_available object { + int x = 0; + } "-matomic-model=soft-imask -mno-usermode"] +} + +# Return 1 if target supports atomic-model=hard-llcs +proc check_effective_target_atomic_model_hard_llcs_available { } { + return [check_no_compiler_messages atomic_model_hard_llcs_available object { + int x = 0; + } "-matomic-model=hard-llcs"] +} + +# If a testcase doesn't have special options, use these. +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" $DEFAULT_CXXFLAGS + + +# All done. +dg-finish
