diff --git a/suite2cases/gcc.json b/suite2cases/gcc.json index 659726e90f13ae75518e0a49fea57a0dbb9407e0..1591c262d461e76ddf2639665e349fde8b6354c4 100644 --- a/suite2cases/gcc.json +++ b/suite2cases/gcc.json @@ -6,6 +6,9 @@ }, { "name": "oe_test_liblsan" + }, + { + "name": "oe_test_dejagnu" } ] -} \ No newline at end of file +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/oe_test_dejagnu.sh b/testcases/cli-test/gcc/oe_test_dejagnu/oe_test_dejagnu.sh new file mode 100644 index 0000000000000000000000000000000000000000..cc377651914d97a64f94af2e21080f93d07094e3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/oe_test_dejagnu.sh @@ -0,0 +1,65 @@ +#!/usr/bin/bash + +# Copyright (c) 2024. Huawei Technologies Co.,Ltd.ALL rights reserved. +# This program is licensed under Mulan PSL v2. +# You can use it according to the terms and conditions of the Mulan PSL v2. +# http://license.coscl.org.cn/MulanPSL2 +# THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +# See the Mulan PSL v2 for more detaitest -f. + +# ############################################################################# +# @Author : xiongzhou +# @Contact : xiongzhou4@huawei.com +# @Date : 2024/07/27 +# @License : Mulan PSL v2 +# @Desc : DejaGnu test of all self-developed features in openEuler GCC +# ############################################################################# + +source "${OET_PATH}"/libs/locallibs/common_lib.sh + +exec_dir="gcc-test" + +function pre_test() { + LOG_INFO "Start to prepare the test environment." + DNF_INSTALL "gcc gcc-c++ gcc-gfortran dejagnu" + rm -rf "${exec_dir}" + mkdir "${exec_dir}" + LOG_INFO "End to prepare the test environment." +} + +function run_test() { + LOG_INFO "Start to run test." + cd "${exec_dir}" || exit + + LOG_INFO "Running tests..." + gcc_version=$(gcc -dumpversion) + if [[ "${gcc_version}" == "10.3.1" ]]; then + runtest --tool gcc --srcdir "${OET_PATH}"/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10 + runtest --tool g++ --srcdir "${OET_PATH}"/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10 + runtest --tool gfortran --srcdir "${OET_PATH}"/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10 + elif [[ "${gcc_version}" == "12.3.1" ]]; then + runtest --tool gcc --srcdir "${OET_PATH}"/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12 + runtest --tool g++ --srcdir "${OET_PATH}"/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12 + runtest --tool gfortran --srcdir "${OET_PATH}"/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12 + else + LOG_WARN "GCC version doesn't match, please use openEuler GCC 10.3.1 or 12.3.1 ." + return + fi + + LOG_INFO "Checking results..." + grep -E '# of (unexpected|unresolved|unsupported)' ./*.sum > /dev/null + CHECK_RESULT $? 1 0 "Some tests failed, please check." + + cd - || exit + LOG_INFO "End to run test." +} + +function post_test() { + LOG_INFO "Start to restore the test environment." + rm -rf "${exec_dir}" + LOG_INFO "End to restore the test environment." +} + +main "$@" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/config/default.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/config/default.exp new file mode 100644 index 0000000000000000000000000000000000000000..7f1241a91552abb588d3602f3661874a617a566f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/config/default.exp @@ -0,0 +1,17 @@ +# Copyright (C) 1997-2020 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 +# . + +load_lib "standard.exp" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..fce7c6c6a10ad0fadc872260b7f3854004a170bc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/dg.exp @@ -0,0 +1,57 @@ +# Copyright (C) 2000-2020 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 +# . + +# G++ testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib g++-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors -Wno-long-long" +} + +# Initialize `dg'. +dg-init + +# Recursively find files in $dir and subdirs, do not walk into subdirs +# that contain their own .exp file. +proc find-cxx-tests { dir suffix } { + set tests [lsort [glob -nocomplain -directory $dir "*.$suffix" ]] + foreach subdir [lsort [glob -nocomplain -type d -directory $dir *]] { + if { [glob -nocomplain -directory $subdir *.exp] eq "" } { + eval lappend tests [find-cxx-tests $subdir $suffix] + } + } + return $tests +} + +set tests [find-cxx-tests $srcdir/$subdir {C}] + +# Main loop. +g++-dg-runtest $tests "" $DEFAULT_CXXFLAGS + +# C/C++ common tests. +g++-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/*.\[cSi\]]] \ + "" "" + +g++-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cpp/*.\[cS\]]] \ + "" "" + + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/llc-allocate.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/llc-allocate.exp new file mode 100644 index 0000000000000000000000000000000000000000..ae6daa1b6559d28376222d1a0ba22a893f527805 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/llc-allocate.exp @@ -0,0 +1,27 @@ +# Copyright (C) 2022-2023 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 +# . + +load_lib g++-dg.exp +load_lib target-supports.exp + +# Initialize `dg'. +dg-init + +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \ + "" "-fllc-allocate" + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/llc-relion-expand-kernels.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/llc-relion-expand-kernels.C new file mode 100644 index 0000000000000000000000000000000000000000..44a9d7c66f9f242fcb7a8b8d30f1546dc66e74d3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/llc-relion-expand-kernels.C @@ -0,0 +1,53 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param branch-prob-threshold=50 --param filter-kernels=0 --param mem-access-num=2 --param issue-topn=1 --param force-issue=1" } */ +#include "multidim_array.h" + +class Input +{ + public: + int metadata_offset = 13; + int exp_nr_images = 1; + MultidimArray exp_Mweight; + void convertAllSquaredDifferencesToWeights(); +}; + +int main() +{ + clock_t start = clock(); + Input input; + int testIter = 2; + + for (int i = 0; i < testIter; ++i) + { + input.convertAllSquaredDifferencesToWeights(); + } + return 0; +} + +void Input::convertAllSquaredDifferencesToWeights() +{ + for (int img_id = 0; img_id < exp_nr_images; img_id++) + { + int my_metadata_offset = metadata_offset + img_id; + MultidimArray sorted_weight; + + exp_Mweight.getRow(img_id, sorted_weight); + long int np = 0; + FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(sorted_weight) + { + if (DIRECT_MULTIDIM_ELEM(sorted_weight, n) > 0.) + { + DIRECT_MULTIDIM_ELEM(sorted_weight, np) = DIRECT_MULTIDIM_ELEM( \ + sorted_weight, n); + np++; + } + } + } +} + + + +/* { dg-final { scan-tree-dump-times "dense memory access" 1 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_prefetch" 1 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "static issue" 1 "llc_allocate" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/multidim_array.h b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/multidim_array.h new file mode 100644 index 0000000000000000000000000000000000000000..d65066ebfb157b2e382cf5f0d0edfc8122087060 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/llc-allocate/multidim_array.h @@ -0,0 +1,186 @@ +#ifndef MULTIDIM_ARRAY_H +#define MULTIDIM_ARRAY_H + +#include + +#define RELION_ALIGNED_MALLOC malloc +#define RELION_ALIGNED_FREE free + +#define STARTINGX(v) ((v).xinit) +#define STARTINGY(v) ((v).yinit) +#define NZYXSIZE(v) ((v).nzyxdim) + +#define DIRECT_MULTIDIM_ELEM(v,n) ((v).data[(n)]) +#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v) \ + for (long int n=0; n +class MultidimArray +{ +public: + T* data; + bool destroyData; + long int ndim; + long int zdim; + long int ydim; + long int xdim; + long int yxdim; + long int zyxdim; + long int nzyxdim; + long int zinit; + long int yinit; + long int xinit; + long int nzyxdimAlloc; + +public: + void clear() + { + coreDeallocate(); + coreInit(); + } + + void coreInit() + { + xdim=0; + yxdim=0; + zyxdim=0; + nzyxdim=0; + ydim=1; + zdim=1; + ndim=1; + zinit=0; + yinit=0; + xinit=0; + data=NULL; + nzyxdimAlloc = 0; + destroyData=true; + } + + void coreAllocate(long int _ndim, long int _zdim, long int _ydim, long int _xdim) + { + if (_ndim <= 0 || _zdim <= 0 || _ydim<=0 || _xdim<=0) + { + clear(); + return; + } + + ndim=_ndim; + zdim=_zdim; + ydim=_ydim; + xdim=_xdim; + yxdim=ydim*xdim; + zyxdim=zdim*yxdim; + nzyxdim=ndim*zyxdim; + + coreAllocate(); + } + + void coreAllocate() + { + data = (T*)RELION_ALIGNED_MALLOC(sizeof(T) * nzyxdim); + nzyxdimAlloc = nzyxdim; + } + + void coreDeallocate() + { + if (data != NULL && destroyData) + { + RELION_ALIGNED_FREE(data); + } + data=NULL; + nzyxdimAlloc = 0; + } + + void resize(long int Ndim, long int Zdim, long int Ydim, long int Xdim) + { + if (Ndim*Zdim*Ydim*Xdim == nzyxdimAlloc && data != NULL) + { + ndim = Ndim; + xdim = Xdim; + ydim = Ydim; + zdim = Zdim; + yxdim = Ydim * Xdim; + zyxdim = Zdim * yxdim; + nzyxdim = Ndim * zyxdim; + nzyxdimAlloc = nzyxdim; + return; + } + + if (Xdim <= 0 || Ydim <= 0 || Zdim <= 0 || Ndim <= 0) + { + clear(); + return; + } + + if (NZYXSIZE(*this) > 0 && data == NULL) + { + coreAllocate(); + return; + } + + size_t YXdim=Ydim*Xdim; + size_t ZYXdim=Zdim*YXdim; + size_t NZYXdim=Ndim*ZYXdim; + + T * new_data = (T*)RELION_ALIGNED_MALLOC(sizeof(T) * NZYXdim); + for (long int l = 0; l < Ndim; l++) + for (long int k = 0; k < Zdim; k++) + for (long int i = 0; i < Ydim; i++) + for (long int j = 0; j < Xdim; j++) + { + T val; + new_data[l*ZYXdim + k*YXdim+i*Xdim+j] = val; + } + coreDeallocate(); + + data = new_data; + ndim = Ndim; + xdim = Xdim; + ydim = Ydim; + zdim = Zdim; + yxdim = Ydim * Xdim; + zyxdim = Zdim * yxdim; + nzyxdim = Ndim * zyxdim; + nzyxdimAlloc = nzyxdim; + } + + void resize(long int Xdim) + { + resize(1, 1, 1, Xdim); + } + + inline T& operator()(long int i, long int j) const + { + return A2D_ELEM(*this, i, j); + } + + inline T& operator()(long int i) const + { + return A1D_ELEM(*this, i); + } + + void getRow(long int i, MultidimArray& v) const + { + if (xdim == 0 || ydim == 0) + { + v.clear(); + return; + } + + v.resize(xdim); + for (long int j = 0; j < xdim; j++) + v(j) = (*this)(i, j); + } +}; + +#endif /* MULTIDIM_ARRAY_H */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-1.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-1.C new file mode 100644 index 0000000000000000000000000000000000000000..d1cc5050c2546b80a977f566856d2574d898bd6a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-1.C @@ -0,0 +1,33 @@ +// PR tree-optimization/94589 +// { dg-do compile { target c++20 } } +// { dg-options "-O2 -g0 -fdump-tree-optimized" } +// { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 12 "optimized" } } +// { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[45]" 12 "optimized" } } + +#include + +#define A __attribute__((noipa)) +A bool f1 (int i, int j) { auto c = i <=> j; return c == 0; } +A bool f2 (int i, int j) { auto c = i <=> j; return c != 0; } +A bool f3 (int i, int j) { auto c = i <=> j; return c > 0; } +A bool f4 (int i, int j) { auto c = i <=> j; return c < 0; } +A bool f5 (int i, int j) { auto c = i <=> j; return c >= 0; } +A bool f6 (int i, int j) { auto c = i <=> j; return c <= 0; } +A bool f7 (int i, int j) { auto c = i <=> j; return c == std::strong_ordering::less; } +A bool f8 (int i, int j) { auto c = i <=> j; return c != std::strong_ordering::less; } +A bool f9 (int i, int j) { auto c = i <=> j; return c == std::strong_ordering::equal; } +A bool f10 (int i, int j) { auto c = i <=> j; return c != std::strong_ordering::equal; } +A bool f11 (int i, int j) { auto c = i <=> j; return c == std::strong_ordering::greater; } +A bool f12 (int i, int j) { auto c = i <=> j; return c != std::strong_ordering::greater; } +A bool f13 (int i) { auto c = i <=> 5; return c == 0; } +A bool f14 (int i) { auto c = i <=> 5; return c != 0; } +A bool f15 (int i) { auto c = i <=> 5; return c > 0; } +A bool f16 (int i) { auto c = i <=> 5; return c < 0; } +A bool f17 (int i) { auto c = i <=> 5; return c >= 0; } +A bool f18 (int i) { auto c = i <=> 5; return c <= 0; } +A bool f19 (int i) { auto c = i <=> 5; return c == std::strong_ordering::less; } +A bool f20 (int i) { auto c = i <=> 5; return c != std::strong_ordering::less; } +A bool f21 (int i) { auto c = i <=> 5; return c == std::strong_ordering::equal; } +A bool f22 (int i) { auto c = i <=> 5; return c != std::strong_ordering::equal; } +A bool f23 (int i) { auto c = i <=> 5; return c == std::strong_ordering::greater; } +A bool f24 (int i) { auto c = i <=> 5; return c != std::strong_ordering::greater; } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-2.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-2.C new file mode 100644 index 0000000000000000000000000000000000000000..dda947e22b11db744f8a6ecde275b45006c2d985 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-2.C @@ -0,0 +1,33 @@ +// PR tree-optimization/94589 +// { dg-do compile { target c++20 } } +// { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } +// { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } +// { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 5\\.0" 14 "optimized" } } + +#include + +#define A __attribute__((noipa)) +A bool f1 (double i, double j) { auto c = i <=> j; return c == 0; } +A bool f2 (double i, double j) { auto c = i <=> j; return c != 0; } +A bool f3 (double i, double j) { auto c = i <=> j; return c > 0; } +A bool f4 (double i, double j) { auto c = i <=> j; return c < 0; } +A bool f5 (double i, double j) { auto c = i <=> j; return c >= 0; } +A bool f6 (double i, double j) { auto c = i <=> j; return c <= 0; } +A bool f7 (double i, double j) { auto c = i <=> j; return c == std::partial_ordering::less; } +A bool f8 (double i, double j) { auto c = i <=> j; return c != std::partial_ordering::less; } +A bool f9 (double i, double j) { auto c = i <=> j; return c == std::partial_ordering::equivalent; } +A bool f10 (double i, double j) { auto c = i <=> j; return c != std::partial_ordering::equivalent; } +A bool f11 (double i, double j) { auto c = i <=> j; return c == std::partial_ordering::greater; } +A bool f12 (double i, double j) { auto c = i <=> j; return c != std::partial_ordering::greater; } +A bool f13 (double i) { auto c = i <=> 5.0; return c == 0; } +A bool f14 (double i) { auto c = i <=> 5.0; return c != 0; } +A bool f15 (double i) { auto c = i <=> 5.0; return c > 0; } +A bool f16 (double i) { auto c = i <=> 5.0; return c < 0; } +A bool f17 (double i) { auto c = i <=> 5.0; return c >= 0; } +A bool f18 (double i) { auto c = i <=> 5.0; return c <= 0; } +A bool f19 (double i) { auto c = i <=> 5.0; return c == std::partial_ordering::less; } +A bool f20 (double i) { auto c = i <=> 5.0; return c != std::partial_ordering::less; } +A bool f21 (double i) { auto c = i <=> 5.0; return c == std::partial_ordering::equivalent; } +A bool f22 (double i) { auto c = i <=> 5.0; return c != std::partial_ordering::equivalent; } +A bool f23 (double i) { auto c = i <=> 5.0; return c == std::partial_ordering::greater; } +A bool f24 (double i) { auto c = i <=> 5.0; return c != std::partial_ordering::greater; } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-3.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-3.C new file mode 100644 index 0000000000000000000000000000000000000000..725b81f56b97cedfd7f67e150a8c700c3c7b216a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-3.C @@ -0,0 +1,84 @@ +// { dg-do run { target c++20 } } +// { dg-options "-O2 -g" } + +#include "pr94589-1.C" + +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () + +int +main () +{ + C (f1, 7, 8, false); + C (f1, 8, 8, true); + C (f1, 9, 8, false); + C (f2, 7, 8, true); + C (f2, 8, 8, false); + C (f2, 9, 8, true); + C (f3, 7, 8, false); + C (f3, 8, 8, false); + C (f3, 9, 8, true); + C (f4, 7, 8, true); + C (f4, 8, 8, false); + C (f4, 9, 8, false); + C (f5, 7, 8, false); + C (f5, 8, 8, true); + C (f5, 9, 8, true); + C (f6, 7, 8, true); + C (f6, 8, 8, true); + C (f6, 9, 8, false); + C (f7, 7, 8, true); + C (f7, 8, 8, false); + C (f7, 9, 8, false); + C (f8, 7, 8, false); + C (f8, 8, 8, true); + C (f8, 9, 8, true); + C (f9, 7, 8, false); + C (f9, 8, 8, true); + C (f9, 9, 8, false); + C (f10, 7, 8, true); + C (f10, 8, 8, false); + C (f10, 9, 8, true); + C (f11, 7, 8, false); + C (f11, 8, 8, false); + C (f11, 9, 8, true); + C (f12, 7, 8, true); + C (f12, 8, 8, true); + C (f12, 9, 8, false); + D (f13, 4, false); + D (f13, 5, true); + D (f13, 6, false); + D (f14, 4, true); + D (f14, 5, false); + D (f14, 6, true); + D (f15, 4, false); + D (f15, 5, false); + D (f15, 6, true); + D (f16, 4, true); + D (f16, 5, false); + D (f16, 6, false); + D (f17, 4, false); + D (f17, 5, true); + D (f17, 6, true); + D (f18, 4, true); + D (f18, 5, true); + D (f18, 6, false); + D (f19, 4, true); + D (f19, 5, false); + D (f19, 6, false); + D (f20, 4, false); + D (f20, 5, true); + D (f20, 6, true); + D (f21, 4, false); + D (f21, 5, true); + D (f21, 6, false); + D (f22, 4, true); + D (f22, 5, false); + D (f22, 6, true); + D (f23, 4, false); + D (f23, 5, false); + D (f23, 6, true); + D (f24, 4, true); + D (f24, 5, true); + D (f24, 6, false); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-4.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-4.C new file mode 100644 index 0000000000000000000000000000000000000000..256a455804ea8d218039a85572eea28e3c67d715 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr94589-4.C @@ -0,0 +1,84 @@ +// { dg-do run { target c++20 } } +// { dg-options "-O2 -g -ffast-math" } + +#include "pr94589-2.C" + +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () + +int +main () +{ + C (f1, 7.0, 8.0, false); + C (f1, 8.0, 8.0, true); + C (f1, 9.0, 8.0, false); + C (f2, 7.0, 8.0, true); + C (f2, 8.0, 8.0, false); + C (f2, 9.0, 8.0, true); + C (f3, 7.0, 8.0, false); + C (f3, 8.0, 8.0, false); + C (f3, 9.0, 8.0, true); + C (f4, 7.0, 8.0, true); + C (f4, 8.0, 8.0, false); + C (f4, 9.0, 8.0, false); + C (f5, 7.0, 8.0, false); + C (f5, 8.0, 8.0, true); + C (f5, 9.0, 8.0, true); + C (f6, 7.0, 8.0, true); + C (f6, 8.0, 8.0, true); + C (f6, 9.0, 8.0, false); + C (f7, 7.0, 8.0, true); + C (f7, 8.0, 8.0, false); + C (f7, 9.0, 8.0, false); + C (f8, 7.0, 8.0, false); + C (f8, 8.0, 8.0, true); + C (f8, 9.0, 8.0, true); + C (f9, 7.0, 8.0, false); + C (f9, 8.0, 8.0, true); + C (f9, 9.0, 8.0, false); + C (f10, 7.0, 8.0, true); + C (f10, 8.0, 8.0, false); + C (f10, 9.0, 8.0, true); + C (f11, 7.0, 8.0, false); + C (f11, 8.0, 8.0, false); + C (f11, 9.0, 8.0, true); + C (f12, 7.0, 8.0, true); + C (f12, 8.0, 8.0, true); + C (f12, 9.0, 8.0, false); + D (f13, 4.0, false); + D (f13, 5.0, true); + D (f13, 6.0, false); + D (f14, 4.0, true); + D (f14, 5.0, false); + D (f14, 6.0, true); + D (f15, 4.0, false); + D (f15, 5.0, false); + D (f15, 6.0, true); + D (f16, 4.0, true); + D (f16, 5.0, false); + D (f16, 6.0, false); + D (f17, 4.0, false); + D (f17, 5.0, true); + D (f17, 6.0, true); + D (f18, 4.0, true); + D (f18, 5.0, true); + D (f18, 6.0, false); + D (f19, 4.0, true); + D (f19, 5.0, false); + D (f19, 6.0, false); + D (f20, 4.0, false); + D (f20, 5.0, true); + D (f20, 6.0, true); + D (f21, 4.0, false); + D (f21, 5.0, true); + D (f21, 6.0, false); + D (f22, 4.0, true); + D (f22, 5.0, false); + D (f22, 6.0, true); + D (f23, 4.0, false); + D (f23, 5.0, false); + D (f23, 6.0, true); + D (f24, 4.0, true); + D (f24, 5.0, true); + D (f24, 6.0, false); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr99305.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr99305.C new file mode 100644 index 0000000000000000000000000000000000000000..06295116fe411dc3bf2f3346496dba45abe49170 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/opt/pr99305.C @@ -0,0 +1,26 @@ +// PR tree-optimization/99305 +// { dg-do compile } +// { dg-options "-O3 -ftree-fold-phiopt -fno-ipa-icf -fdump-tree-optimized" } +// { dg-final { scan-tree-dump-times " = \\\(unsigned char\\\) c_\[0-9]*\\\(D\\\);" 3 "optimized" { target { ! unsigned_char } } } } +// { dg-final { scan-tree-dump-times " = \[^\n\r]* \\+ \[0-9]*;" 3 "optimized" } } +// { dg-final { scan-tree-dump-times " = \[^\n\r]* <= 9;" 3 "optimized" } } +// { dg-final { scan-tree-dump-not "if \\\(c_\[0-9]*\\\(D\\\) \[!=]= 0\\\)" "optimized" } } +// { dg-final { scan-tree-dump-not " = PHI <" "optimized" } } + +bool +foo (char c) +{ + return c >= 48 && c <= 57; +} + +bool +bar (char c) +{ + return c != 0 && foo (c); +} + +bool +baz (char c) +{ + return c != 0 && c >= 48 && c <= 57; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/no-body-function.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/no-body-function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e56e73fcaedea15e944313cff4b6a009a0dcbb4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/no-body-function.cpp @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu++17 -Wno-builtin-declaration-mismatch -O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -S" } */ + +struct S { + int x; + double y; +}; +S f(); + +const auto [x0, y0] = f(); +const auto [x1, y1] = f(); + +static union { +int a; +double b; +}; + +const auto [x2, y2] = f(); diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-1.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ab71abe140f981e4b663a92df41742e8125bba9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-1.cpp @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -fdump-ipa-struct_reorg-details -S" } */ + +struct Foo { int foo; int a; }; +Foo& ignoreSetMutex = *(new Foo); + +struct Goo { int goo; int a; }; + +int main () +{ + Goo* a; + return a->goo = 90; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-2.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72b7db8a9cea780675adea2628cb6101adbd7c69 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-2.cpp @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -fdump-ipa-struct_reorg-details" } */ + +#include + +struct testg { + int b; + float c; +}; + +testg *testgvar; +int main () +{ + testgvar = (testg*) calloc(10, sizeof(testg)); + int b = testgvar->b; + return b; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-3.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..771164a96e7091622d21e06e32e5f40c015fbdcc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg-3.cpp @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -fdump-ipa-struct_reorg-details" } */ + +#include + +struct testg { + int b; + float c; + double d; + double e; + double f; + double h; + double i; + double j; + int k; +}; + +testg *testgvar; +int main () +{ + testgvar = (testg*) calloc(10, sizeof(testg)); + int b = testgvar->b; + return b; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg.exp new file mode 100644 index 0000000000000000000000000000000000000000..4307f69e2cd0e37142458291284bbebc15662d81 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/struct/struct-reorg.exp @@ -0,0 +1,26 @@ +# Copyright (C) 2021-2021 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 +# . + +load_lib g++-dg.exp + +# Initialize `dg'. +dg-init + +g++-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cpp]] \ + "" "" + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/torture/dg-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/torture/dg-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..f42a6d21a39e7b3648ea79ab6b2951829bbc82e9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/torture/dg-torture.exp @@ -0,0 +1,7 @@ +# This harness is for tests that should be run at all optimisation levels. + +load_lib g++-dg.exp + +dg-init +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C $srcdir/c-c++-common/torture/*.c]] "" "" +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/torture/pr100925.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/torture/pr100925.C new file mode 100644 index 0000000000000000000000000000000000000000..de13950dca0a9c05328c149a10571f921cc7b8b5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/torture/pr100925.C @@ -0,0 +1,24 @@ +// { dg-do compile } + +struct QScopedPointerDeleter { + static void cleanup(int *); +}; +class QScopedPointer { + typedef int *QScopedPointer::*RestrictedBool; + +public: + operator RestrictedBool() { return d ? nullptr : &QScopedPointer::d; } + void reset() { + if (d) + QScopedPointerDeleter::cleanup(d); + } + int *d; +}; +class DOpenGLPaintDevicePrivate { +public: + QScopedPointer fbo; +} DOpenGLPaintDeviceresize_d; +void DOpenGLPaintDeviceresize() { + if (DOpenGLPaintDeviceresize_d.fbo) + DOpenGLPaintDeviceresize_d.fbo.reset(); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/tree-ssa/mull64.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/tree-ssa/mull64.C new file mode 100644 index 0000000000000000000000000000000000000000..ec359f2bae45ee8e402401c082e9f387d4bb03ea --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.dg/tree-ssa/mull64.C @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-fold-phiopt -fmerge-mull -Wno-psabi -fdump-tree-forwprop1-details -fdump-tree-forwprop4-details" } */ + +# define BN_BITS4 32 +# define BN_MASK2 (0xffffffffffffffffL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000L) +# define BN_MASK2h1 (0xffffffff80000000L) +# define LBITS(a) ((a)&BN_MASK2l) +# define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l) +# define L2HBITS(a) (((a)<. + +# GCC testsuite that uses the 'dg.exp' driver. + +# There's a bunch of headers we need. +if [is_remote host] { + foreach header [glob -nocomplain $srcdir/$subdir/*.{h,def} ] { + remote_download host $header + } +} + +# Load support procs. +load_lib g++-dg.exp +load_lib target-supports.exp + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +# Set up flags used for tests that don't specify options. +global DEFAULT_VECTCFLAGS +set DEFAULT_VECTCFLAGS "" + +# Set up a list of effective targets to run vector tests for all supported +# targets. +global EFFECTIVE_TARGETS +set EFFECTIVE_TARGETS "" + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fno-vect-cost-model" + +# Skip these tests for targets that do not support generating vector +# code. Set additional target-dependent vector flags, which can be +# overridden by using dg-options in individual tests. +if ![check_vect_support_and_set_flags] { + return +} + +set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" +lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" + +# Initialize `dg'. +dg-init + +# Main loop. +et-dg-runtest g++-dg-runtest [lsort [glob -nocomplain \ + $srcdir/$subdir/{pr,simd}*.{c,cc,S} ]] "" $DEFAULT_VECTCFLAGS +et-dg-runtest g++-dg-runtest [lsort [glob -nocomplain \ + $srcdir/$subdir/slp-pr*.{c,cc,S} ]] "" $VECT_SLP_CFLAGS + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS + +# --param max-aliased-vops=0 +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "--param max-aliased-vops=0" +et-dg-runtest g++-dg-runtest [lsort [glob -nocomplain \ + $srcdir/$subdir/param-max-aliased*.\[cS\]]] "" $DEFAULT_VECTCFLAGS + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512bw-pr98537-1.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512bw-pr98537-1.C new file mode 100644 index 0000000000000000000000000000000000000000..969684a222b35ecf8d52d9ed398e3b2e6ecf5eab --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512bw-pr98537-1.C @@ -0,0 +1,11 @@ +/* PR target/98537 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -std=c++11" } */ + +#define TYPEV char +#define TYPEW short + +#define T_ARR \ + __attribute__ ((target ("avx512vl,avx512bw"))) + +#include "avx512vl-pr98537-1.C" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512vl-pr98537-1.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512vl-pr98537-1.C new file mode 100644 index 0000000000000000000000000000000000000000..b2ba91111da55f99745a978471830f7abe90f844 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512vl-pr98537-1.C @@ -0,0 +1,40 @@ +/* PR target/98537 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -std=c++11" } */ + +#ifndef TYPEV +#define TYPEV int +#endif + +#ifndef TYPEW +#define TYPEW long long +#endif + +#ifndef T_ARR +#define T_ARR \ + __attribute__ ((target ("avx512vl"))) +#endif + +typedef TYPEV V __attribute__((__vector_size__(32))); +typedef TYPEW W __attribute__((__vector_size__(32))); + +W c, d; +struct B {}; +B e; +struct C { W i; }; +void foo (C); + +C +operator== (B, B) +{ + W r = (V)c == (V)d; + return {r}; +} + +void +T_ARR +bar () +{ + B a; + foo (a == e); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512vl-pr98537-2.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512vl-pr98537-2.C new file mode 100644 index 0000000000000000000000000000000000000000..42c9682746d6cea1abb23db8ee9abd9385eb78e3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/avx512vl-pr98537-2.C @@ -0,0 +1,8 @@ +/* PR target/98537 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=x86-64 -std=c++11" } */ + +#define TYPEV float +#define TYPEW double + +#include "avx512vl-pr98537-1.C" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/i386.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/i386.exp new file mode 100644 index 0000000000000000000000000000000000000000..276093dad071b7e19f1da45434b356f8584284f1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/g++.target/i386/i386.exp @@ -0,0 +1,43 @@ +# Copyright (C) 2018-2020 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 +# . + +# GCC testsuite that uses the `g++.exp' driver. + +# Exit immediately if this isn't a x86 target. +if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { + return +} + +# Load support procs. +load_lib g++-dg.exp +load_lib clearcap.exp + +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init +clearcap-init + +# Main loop. +g++-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \ + "" $DEFAULT_CXXFLAGS + +# All done. +clearcap-finish +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/bitfld-10.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/bitfld-10.c new file mode 100644 index 0000000000000000000000000000000000000000..bdbf5733ce7fba23f8ab4d33622d98fd5520ba86 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/bitfld-10.c @@ -0,0 +1,24 @@ +/* PR tree-optimization/102622 */ +/* Wrong code introduced due to phi-opt + introducing undefined signed interger overflow + with one bit signed integer negation. */ + +struct f{signed t:1;}; +int g(struct f *a, int t) __attribute__((noipa)); +int g(struct f *a, int t) +{ + if (t) + a->t = -1; + else + a->t = 0; + int t1 = a->t; + if (t1) return 1; + return t1; +} + +int main(void) +{ + struct f a; + if (!g(&a, 1)) __builtin_abort(); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/execute.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/execute.exp new file mode 100644 index 0000000000000000000000000000000000000000..cb44ced96a07aa801a5eb65516bbd8c44827f304 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/execute.exp @@ -0,0 +1,38 @@ +# Copyright (C) 1991-2020 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 +# . + +# This file was written by Rob Savoye. (rob@cygnus.com) +# Modified and maintained by Jeffrey Wheat (cassidy@cygnus.com) + +# +# These tests come from Torbjorn Granlund (tege@cygnus.com) +# C torture test suite. +# + +# Load support procs. +load_lib gcc-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +set saved-dg-do-what-default ${dg-do-what-default} +set dg-do-what-default "run" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" "-w" +set dg-do-what-default ${saved-dg-do-what-default} + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/ifcvt-renaming-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/ifcvt-renaming-1.c new file mode 100644 index 0000000000000000000000000000000000000000..761c8ab7ebce66ea58b6b3cb5363db041ba95e4e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/ifcvt-renaming-1.c @@ -0,0 +1,38 @@ + +extern void abort(void); + +__attribute__ ((noinline)) +int foo (int x, int y, int z, int a, int b) +{ + if (a < 2) + { + if (a == 0) + { + if (x - y < 0) + x = x - y + z; + else + x = x - y; + } + else + { + if (x + y >= z) + x = x + y - z; + else + x = x + y; + } + } + return x; +} + +int main(void) +{ + if (foo (5,10,7,0,1) != 2) // x - y + z = -5 + 7 = 2 + abort (); + if (foo (50,10,7,0,1) != 40) // x - y = 40 + abort (); + if (foo (5,10,7,1,1) != 8) // x + y - z = 5 + 10 - 7 = 8 + abort (); + if (foo (5,10,70,1,1) != 15) // x + y = 15 + abort (); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/pr10352-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/pr10352-1.c new file mode 100644 index 0000000000000000000000000000000000000000..babb9d45a2813a4fffdde7f8480317f7001dd2bc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.c-torture/execute/pr10352-1.c @@ -0,0 +1,12 @@ +/* this is another case where phiopt + would create -signed1bit which is undefined. */ +struct { + int a:1; +} b; +int *c = (int *)&b, d; +int main() { + d = c && (b.a = (d < 0) ^ 3); + if (d != 1) + __builtin_abort(); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/Wstringop-overflow-67.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/Wstringop-overflow-67.c new file mode 100644 index 0000000000000000000000000000000000000000..7b8f3f014c63b359ebf6ebbfca6735b41dd3bb14 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/Wstringop-overflow-67.c @@ -0,0 +1,92 @@ +/* PR middle-end/100571 - bogus -Wstringop-overflow with VLA of elements + larger than byte + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +__attribute__ ((access (read_only, 1, 2))) void fro (int *, int); +__attribute__ ((access (write_only, 1, 2))) void fwo (int *, int); +__attribute__ ((access (read_write, 1, 2))) void frw (int *, int); + +extern __SIZE_TYPE__ n; + +void alloca_ro (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + a[0] = 0; + fro (a, n); +} + +void alloca_wo (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + fwo (a, n); +} + +void alloca_rw (void) +{ + int *a = __builtin_alloca (n * sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void calloc_ro (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + fro (a, n); +} + +void calloc_wo (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + fwo (a, n); +} + +void calloc_rw (void) +{ + int *a = __builtin_calloc (n, sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void malloc_ro (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + a[0] = 0; + fro (a, n); +} + +void malloc_wo (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + fwo (a, n); +} + +void malloc_rw (void) +{ + int *a = __builtin_malloc (n * sizeof *a); + a[0] = 0; + frw (a, n); +} + + +void vla_ro (void) +{ + int a[n]; + a[0] = 0; + fro (a, n); +} + +void vla_wo (void) +{ + int a[n]; + fwo (a, n); +} + +void vla_rw (void) +{ + int a[n]; + a[0] = 0; + frw (a, n); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/autoprefetch.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/autoprefetch.exp new file mode 100644 index 0000000000000000000000000000000000000000..7cae630a20610fb92feb6cd75f9dab9fd3ac3af5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/autoprefetch.exp @@ -0,0 +1,27 @@ +# Copyright (C) 1997-2022 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 +# . + +load_lib gcc-dg.exp +load_lib target-supports.exp + +# Initialize `dg'. +dg-init + +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] \ + "" "-fprefetch-loop-arrays" + +# All done. +dg-finish \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/branch-weighted-prefetch.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/branch-weighted-prefetch.c new file mode 100644 index 0000000000000000000000000000000000000000..ab537cb29873df7edbc85485382a46b21aefb052 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/branch-weighted-prefetch.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O2 -fprefetch-loop-arrays=2 --param min-insn-to-prefetch-ratio=5 --param simultaneous-prefetches=100 --param l1-cache-size=64 --param l1-cache-line-size=32 -fdump-tree-aprefetch-details -fdump-tree-optimized" } */ +#define N 10000000 + +long long a[N]; + +long long func () +{ + long long i; + long long sum = 0; + + for (i = 0; i < N; i+=1) { + if (i < 100000) + sum += a[i]; + else + continue; + } + + return sum; +} +/* { dg-final { scan-tree-dump "Calculating prefetch distance using bb branch weighting method" "aprefetch" } } */ +/* { dg-final { scan-tree-dump "builtin_prefetch" "optimized" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/get-edge-prob-non-init.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/get-edge-prob-non-init.c new file mode 100644 index 0000000000000000000000000000000000000000..f55481008df075f85949e859af19246cc1a92104 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/autoprefetch/get-edge-prob-non-init.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fprefetch-loop-arrays=2 -fdump-tree-aprefetch-details" } */ + +int a, c, f; +static int *b = &a; +int *d; +int e[0]; +void g() { + int h; + for (;;) { + h = 1; + for (; h >= 0; h--) { + c = 2; + for (; c; c--) + if (e[0]) + if (e[c]) + *b = 0; + f || (*d = 0); + } + } +} +int main() {} + +/* { dg-final } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-cmlt.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-cmlt.c new file mode 100755 index 0000000000000000000000000000000000000000..b4c9a37ffe7795bba115f7e78e4d9a4e4f06f681 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-cmlt.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -mcmlt-arith" } */ + +/* The test checks usage of cmlt insns for arithmetic/logic calculations + * in foo (). It's inspired by sources of x264 codec. */ + +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; + +void foo( uint32_t *a, uint32_t *b) +{ + for (unsigned i = 0; i < 4; i++) + { + uint32_t s = ((a[i]>>((8 * sizeof(uint16_t))-1)) + &(((uint32_t)1<<(8 * sizeof(uint16_t)))+1))*((uint16_t)-1); + b[i] = (a[i]+s)^s; + } +} + +/* { dg-final { scan-assembler-times {cmlt\t} 1 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin-1.c new file mode 100644 index 0000000000000000000000000000000000000000..859ff7df8cb64bd4bfa635894325712797399472 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -fconvert-minmax" } */ + +#include + +__attribute__((noinline)) +void test (int32_t *restrict a, int32_t *restrict x) +{ + for (int i = 0; i < 4; i++) + a[i] = ((((-x[i]) >> 31) ^ x[i]) + & (-((int32_t)((x[i] & (~((1 << 8)-1))) == 0)))) ^ ((-x[i]) >> 31); +} + +/* { dg-final { scan-assembler-not {smax\t} } } */ +/* { dg-final { scan-assembler-not {smin\t} } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin-2.c new file mode 100644 index 0000000000000000000000000000000000000000..63d4d85b3f3983ab20741b5e9abe98f5c0dee0b4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -fconvert-minmax" } */ + +#include + +__attribute__((noinline)) +void test (int8_t *restrict a, int32_t *restrict x) +{ + for (int i = 0; i < 8; i++) + a[i] = ((x[i] & ~((1 << 9)-1)) ? (-x[i])>>31 & ((1 << 9)-1) : x[i]); +} + +/* { dg-final { scan-assembler-times {smax\t} 4 } } */ +/* { dg-final { scan-assembler-times {smin\t} 4 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin.c new file mode 100755 index 0000000000000000000000000000000000000000..a984fa56068c67ed143a9382e5c9cb608eece586 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/combine-maxmin.c @@ -0,0 +1,55 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -fconvert-minmax" } */ + +/* The test checks usage of smax/smin insns for clip evaluation and + * uzp1/uzp2 insns for vector element narrowing. It's inspired by + * sources of x264 codec. */ + +typedef unsigned char uint8_t; +typedef long int intptr_t; +typedef signed short int int16_t; + +static __attribute__((always_inline)) inline uint8_t clip (int x ) +{ + return ( (x & ~((1 << 8)-1)) ? (-x)>>31 & ((1 << 8)-1) : x ); +} + +void hf (uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, uint8_t *src, + intptr_t stride, int width, int height, int16_t *buf) +{ + const int pad = (8 > 9) ? (-10 * ((1 << 8)-1)) : 0; + for( int y = 0; y < height; y++ ) { + /* This loop is not being vectorized now. */ + for( int x = -2; x < width+3; x++ ) { + int v = ((src)[x-2*stride] + (src)[x+3*stride] - 5*((src)[x-stride] + + (src)[x+2*stride]) + 20*((src)[x] + (src)[x+stride])); + dstv[x] = clip ( (v + 16) >> 5 ); + buf[x+2] = v + pad; + } + + /* Produces two versions of the code: 3xUZP1/2xMAX/2xMIN + 1xUZP1/1xMAX/1xMIN. */ + for( int x = 0; x < width; x++ ) + dstc[x] = clip ((((buf+2)[x-2*1] + (buf+2)[x+3*1] - 5*((buf+2)[x-1] + + (buf+2)[x+2*1]) + 20*((buf+2)[x] + (buf+2)[x+1])) + - 32*pad + 512) >> 10); + + /* Priduces two versions of the code: 1xUZP1/2xMAX/2xMIN + 0xUZP1/1xMAX/1xMIN. */ + for( int x = 0; x < width; x++ ) + dsth[x] = clip ((((src)[x-2*1] + (src)[x+3*1] - 5*((src)[x-1] + + (src)[x+2*1]) + 20*((src)[x] + (src)[x+1])) + + 16) >> 5); + + dsth += stride; + dstv += stride; + dstc += stride; + src += stride; + } +} + +/* Max is performed on 0 from signed values, match smax exactly. */ +/* { dg-final { scan-assembler-times {smax\t} 6 } } */ +/* Min is performed on signed val>0 and a mask, min sign doesn't matter. */ +/* { dg-final { scan-assembler-times {[us]min\t} 6 } } */ +/* All of the vectorized patterns are expected to be matched. */ +/* { dg-final { scan-assembler-not {cmtst\t} } } */ +/* { dg-final { scan-assembler-times {uzp1\t} 5 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..8cda6a3b9c72040f3a3bc4bfb5e02aa09bf86cc4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/dg.exp @@ -0,0 +1,40 @@ +# Copyright (C) 1997-2020 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cSi\]]] \ + "" $DEFAULT_CFLAGS + +# C/C++ common tests. +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/*.\[cSi\]]] \ + " -Wc++-compat " "" + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/double_sized_mul-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/double_sized_mul-1.c new file mode 100644 index 0000000000000000000000000000000000000000..bdb503bc4b2553b1b3f5ddc29f9290e513f8cde6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/double_sized_mul-1.c @@ -0,0 +1,141 @@ +/* { dg-do compile } */ +/* fif-conversion-gimple and fuaddsub-overflow-match-all are required for + proper overflow detection in some cases. */ +/* { dg-options "-O2 -fif-conversion-gimple -fuaddsub-overflow-match-all -ftree-fold-phiopt -fdump-tree-widening_mul-stats" } */ +#include + +typedef unsigned __int128 uint128_t; + +uint16_t mul16 (uint8_t a, uint8_t b) +{ + uint8_t a_lo = a & 0xF; + uint8_t b_lo = b & 0xF; + uint8_t a_hi = a >> 4; + uint8_t b_hi = b >> 4; + uint8_t lolo = a_lo * b_lo; + uint8_t lohi = a_lo * b_hi; + uint8_t hilo = a_hi * b_lo; + uint8_t hihi = a_hi * b_hi; + uint8_t middle = hilo + lohi; + uint8_t middle_hi = middle >> 4; + uint8_t middle_lo = middle << 4; + uint8_t res_lo = lolo + middle_lo; + uint8_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x10 : 0); + uint16_t res = ((uint16_t) res_hi) << 8; + res += res_lo; + return res; +} + +uint32_t mul32 (uint16_t a, uint16_t b) +{ + uint16_t a_lo = a & 0xFF; + uint16_t b_lo = b & 0xFF; + uint16_t a_hi = a >> 8; + uint16_t b_hi = b >> 8; + uint16_t lolo = a_lo * b_lo; + uint16_t lohi = a_lo * b_hi; + uint16_t hilo = a_hi * b_lo; + uint16_t hihi = a_hi * b_hi; + uint16_t middle = hilo + lohi; + uint16_t middle_hi = middle >> 8; + uint16_t middle_lo = middle << 8; + uint16_t res_lo = lolo + middle_lo; + uint16_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x100 : 0); + uint32_t res = ((uint32_t) res_hi) << 16; + res += res_lo; + return res; +} + +uint64_t mul64 (uint32_t a, uint32_t b) +{ + uint32_t a_lo = a & 0xFFFF; + uint32_t b_lo = b & 0xFFFF; + uint32_t a_hi = a >> 16; + uint32_t b_hi = b >> 16; + uint32_t lolo = a_lo * b_lo; + uint32_t lohi = a_lo * b_hi; + uint32_t hilo = a_hi * b_lo; + uint32_t hihi = a_hi * b_hi; + uint32_t middle = hilo + lohi; + uint32_t middle_hi = middle >> 16; + uint32_t middle_lo = middle << 16; + uint32_t res_lo = lolo + middle_lo; + uint32_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x10000 : 0); + uint64_t res = ((uint64_t) res_hi) << 32; + res += res_lo; + return res; +} + +uint128_t mul128 (uint64_t a, uint64_t b) +{ + uint64_t a_lo = a & 0xFFFFFFFF; + uint64_t b_lo = b & 0xFFFFFFFF; + uint64_t a_hi = a >> 32; + uint64_t b_hi = b >> 32; + uint64_t lolo = a_lo * b_lo; + uint64_t lohi = a_lo * b_hi; + uint64_t hilo = a_hi * b_lo; + uint64_t hihi = a_hi * b_hi; + uint64_t middle = hilo + lohi; + uint64_t middle_hi = middle >> 32; + uint64_t middle_lo = middle << 32; + uint64_t res_lo = lolo + middle_lo; + uint64_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x100000000 : 0); + uint128_t res = ((uint128_t) res_hi) << 64; + res += res_lo; + return res; +} + +uint64_t mul64_perm (uint32_t a, uint32_t b) +{ + uint32_t a_lo = a & 0xFFFF; + uint32_t b_lo = b & 0xFFFF; + uint32_t a_hi = a >> 16; + uint32_t b_hi = b >> 16; + uint32_t lolo = a_lo * b_lo; + uint32_t lohi = a_lo * b_hi; + uint32_t hilo = a_hi * b_lo; + uint32_t hihi = a_hi * b_hi; + uint32_t middle = hilo + lohi; + uint32_t middle_hi = middle >> 16; + uint32_t middle_lo = middle << 16; + uint32_t res_lo = lolo + middle_lo; + uint32_t res_hi = hihi + middle_hi; + res_hi = res_lo < middle_lo ? res_hi + 1 : res_hi; + res_hi = middle < hilo ? res_hi + 0x10000 : res_hi; + uint64_t res = ((uint64_t) res_hi) << 32; + res += res_lo; + return res; +} + +uint128_t mul128_perm (uint64_t a, uint64_t b) +{ + uint64_t a_lo = a & 0xFFFFFFFF; + uint64_t b_lo = b & 0xFFFFFFFF; + uint64_t a_hi = a >> 32; + uint64_t b_hi = b >> 32; + uint64_t lolo = a_lo * b_lo; + uint64_t lohi = a_lo * b_hi; + uint64_t hilo = a_hi * b_lo; + uint64_t hihi = a_hi * b_hi; + uint64_t middle = hilo + lohi; + uint64_t middle_hi = middle >> 32; + uint64_t middle_lo = middle << 32; + uint64_t res_lo = lolo + middle_lo; + uint64_t res_hi = hihi + middle_hi; + res_hi = res_lo < middle_lo ? res_hi + 1 : res_hi; + res_hi = middle < hilo ? res_hi + 0x100000000 : res_hi; + uint128_t res = ((uint128_t) res_hi) << 64; + res += res_lo; + return res; +} + +/* { dg-final { scan-tree-dump-times "double sized mul optimized: 1" 6 "widening_mul" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/double_sized_mul-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/double_sized_mul-2.c new file mode 100644 index 0000000000000000000000000000000000000000..f9d58a2f6443807c4f8415dcf4904a2fdcdedbd1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/double_sized_mul-2.c @@ -0,0 +1,62 @@ +/* { dg-do compile } */ +/* fif-conversion-gimple is required for proper overflow detection + in some cases. */ +/* { dg-options "-O2 -fif-conversion-gimple -fuaddsub-overflow-match-all -ftree-fold-phiopt -fdump-tree-widening_mul-stats" } */ +#include + +typedef unsigned __int128 uint128_t; +typedef struct uint256_t +{ + uint128_t lo; + uint128_t hi; +} uint256_t; + +uint64_t mul64_double_use (uint32_t a, uint32_t b) +{ + uint32_t a_lo = a & 0xFFFF; + uint32_t b_lo = b & 0xFFFF; + uint32_t a_hi = a >> 16; + uint32_t b_hi = b >> 16; + uint32_t lolo = a_lo * b_lo; + uint32_t lohi = a_lo * b_hi; + uint32_t hilo = a_hi * b_lo; + uint32_t hihi = a_hi * b_hi; + uint32_t middle = hilo + lohi; + uint32_t middle_hi = middle >> 16; + uint32_t middle_lo = middle << 16; + uint32_t res_lo = lolo + middle_lo; + uint32_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x10000 : 0); + uint64_t res = ((uint64_t) res_hi) << 32; + res += res_lo; + return res + lolo; +} + +uint256_t mul256 (uint128_t a, uint128_t b) +{ + uint128_t a_lo = a & 0xFFFFFFFFFFFFFFFF; + uint128_t b_lo = b & 0xFFFFFFFFFFFFFFFF; + uint128_t a_hi = a >> 64; + uint128_t b_hi = b >> 64; + uint128_t lolo = a_lo * b_lo; + uint128_t lohi = a_lo * b_hi; + uint128_t hilo = a_hi * b_lo; + uint128_t hihi = a_hi * b_hi; + uint128_t middle = hilo + lohi; + uint128_t middle_hi = middle >> 64; + uint128_t middle_lo = middle << 64; + uint128_t res_lo = lolo + middle_lo; + uint128_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + /* Constant is to big warning WA */ + uint128_t overflow_tmp = (middle < hilo ? 1 : 0); + overflow_tmp <<= 64; + res_hi += overflow_tmp; + uint256_t res; + res.lo = res_lo; + res.hi = res_hi; + return res; +} + +/* { dg-final { scan-tree-dump-not "double sized mul optimized" "widening_mul" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp1.c new file mode 100644 index 0000000000000000000000000000000000000000..c2117f7385b322ae19226475205f6e813e68eeee --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp1.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp1.c.077i.icp" } */ + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; +} my_str; + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + my_str.myf2 = &bar; + func1 = &foo; + return foo(a); +} + +int main() { + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(4\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(2\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by: bar \\(3\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 3 candidates for indirect call promotion, 3 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp2.c new file mode 100644 index 0000000000000000000000000000000000000000..03d31d407767682f5e8c6515a6e1edadcd683c2f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp2.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp2.c.077i.icp" } */ + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; +} my_str; + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + my_str.myf2 = dummy ? (ftype2) &foo : &bar; + func1 = (ftype1) &bar; + return foo(a); +} + +int main() { + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump-not "The call is substituted by.*" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 3 candidates for indirect call promotion, 0 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp3.c new file mode 100644 index 0000000000000000000000000000000000000000..2a7d1e6f5f807459f99393f53ef3e2dca27d377a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp3.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp3.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef ftype1 (*ftype3) (ftype2); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} my_str; + +ftype1 boo(ftype2 a) { + printf ("Call boo\n"); + return (ftype1) a; +} + +int foo(int a) { + printf ("Call foo\n"); + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + printf("Call bar\n"); + my_str.myf2 = (ftype2) my_str.myf3((ftype2) foo); + func1 = &foo; + return foo(a); +} + +int main() { + my_str.myf3 = &boo; + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(4\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(2\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by: foo \\(3\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 4 candidates for indirect call promotion, 3 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp4.c new file mode 100644 index 0000000000000000000000000000000000000000..e3e1d5116b44a26419abfb5f94eb21abdee87ebf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp4.c @@ -0,0 +1,55 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp4.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef ftype1 (*ftype3) (ftype2); + +ftype1 func1; +ftype1 boo(ftype2 a); +int foo(int a); +float bar(int a); + +typedef struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} T; + +T my_str = {0, (int*) &dummy, (ftype1) &boo, (ftype2) &foo, (ftype3) &bar}; + +ftype1 boo(ftype2 a) { + printf ("Call boo\n"); + return (ftype1) a; +} + +int foo(int a) { + printf ("Call foo\n"); + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + printf("Call bar\n"); + my_str.myf2 = (ftype2) my_str.myf3((ftype2) foo); + func1 = &foo; + return foo(a); +} + +int main() { + my_str.myf3 = &boo; + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump-not "The call is substituted by.*" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 4 candidates for indirect call promotion, 0 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp5.c new file mode 100644 index 0000000000000000000000000000000000000000..c7709243cceab51f3c01f93a2a84a2f36cc6723f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp5.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp5.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef ftype1 (*ftype3) (ftype2); + +ftype1 func1; +ftype1 boo(ftype2 a); +int foo(int a); +float bar(int a); + +typedef struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} T; + +T my_str; + +typedef struct { + int a; + int* b; + ftype3 myf1; + ftype2 myf2; + ftype1 myf3; +} T1; + +T1 my1 = {0, &dummy, boo, &bar, &foo}; + +ftype1 boo(ftype2 a) { + printf("Call boo\n"); + return (ftype1) a; +} + +int foo(int a) { + printf("Call foo\n"); + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + printf("Call bar\n"); + my_str.myf2 = (ftype2) my_str.myf3((ftype2) foo); + func1 = &foo; + return foo(a); +} + +int main() { + my_str = *(T*)&my1; + my_str.myf3 = &boo; + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump-not "The call is substituted by.*" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 4 candidates for indirect call promotion, 0 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp6.c new file mode 100644 index 0000000000000000000000000000000000000000..5a9f15045935313bcf3d3ef77afac45dc1b72313 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp6.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp6.c.077i.icp -Wno-int-conversion -Wno-incompatible-pointer-types" } */ +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef int (*ftype3)(); +typedef int (*ftype4)(int a, int b); + +ftype1 func1; +ftype4 func2; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} my_str; + +int foo3(float a) { + return dummy; +} + +int foo4(int a, int b) { + return a*b; +} + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +int foo2(float a) { + func1 = (ftype1) &foo; + func2 = &foo4; + return dummy + foo3 (a); +} + +float bar2(int a) { + my_str.myf2 = (ftype2)(0x864213); + func2 = 0x65378; + return foo(a); +} + +float bar(int a) { + my_str.myf3 = &foo2; + my_str.myf2 = &bar; + func1 = (ftype1) &dummy; + func2 = (ftype4) &bar2; + return foo(a); +} + +int main() { + bar(1); + bar2(1); + bar(0); + my_str.myf2(3); + ((ftype1) my_str.myf3)(0.0); + int sum = func1(4); + return (sum + my_str.myf1(2) + func2(5, 6)) != 38; +} +/* { dg-final { scan-ipa-dump "The call is substituted by.*foo2 \\(0\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 5 candidates for indirect call promotion, 1 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp7.c new file mode 100644 index 0000000000000000000000000000000000000000..fa52197f48fa782a3a519d3038dd16f232e6ad5c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/icp7.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp7.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; +} my_str; + +int boo(int a, ...) { + va_list ap; + va_start(ap, a); + if (a == 0) + dummy += va_arg(ap, int); + va_end(ap); + return dummy; +} + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + my_str.myf2 = &bar; + func1 = (ftype1) &boo; + return foo(a); +} + +int main() { + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)); +} + +/* { dg-final { scan-ipa-dump "Address taken function with varargs is found. Skip the optimization." "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-6.c new file mode 100644 index 0000000000000000000000000000000000000000..7d2a8d58bfab6cabb52a0c2b89aaf2a91692a765 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-6.c @@ -0,0 +1,29 @@ +/* { dg-do compile { target { aarch64*-*-* } } } */ +/* { dg-options "-fdump-rtl-ce1 -O2 -fifcvt-allow-complicated-cmps --param max-rtl-if-conversion-unpredictable-cost=100 --param max-rtl-if-conversion-predictable-cost=100 --param=ifcvt-allow-register-renaming=2 " } */ + +typedef unsigned int uint16_t; + +uint16_t +foo (uint16_t x, uint16_t y, uint16_t z, uint16_t a, + uint16_t b, uint16_t c, uint16_t d) +{ + int i = 1; + int j = 1; + if (a > b) + { + j = x; + if (b > c) + i = y; + else + i = z; + } + else + { + j = y; + if (c > d) + i = z; + } + return i * j; +} + +/* { dg-final { scan-rtl-dump "7 true changes made" "ce1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-gimple-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-gimple-1.c new file mode 100644 index 0000000000000000000000000000000000000000..381a4ad51b51e531cddba61908f6f7534c4fe556 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-gimple-1.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-inline -fif-conversion-gimple" } */ + +#include + +void foo(int a, int *p) { + *p = a; +} + +void verify (int a) { + if (a != 3) + abort (); +} + +int main() { + int a = 0; + foo (3, &a); + int tmp = (a > 7) ? a & 1 : a; + verify (tmp); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-gimple.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-gimple.c new file mode 100644 index 0000000000000000000000000000000000000000..4dc0f92061afa1cb1091499cc060e73ba91792fd --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ifcvt-gimple.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fif-conversion-gimple -fdump-tree-optimized -ftree-fold-phiopt" } */ + +int test_int (int optimizable_int) { + if (optimizable_int > 5) + ++optimizable_int; + return optimizable_int; +} + +int test_int_pow2 (int optimizable_int_pow2) { + if (optimizable_int_pow2 <= 4) + optimizable_int_pow2 += 1024; + return optimizable_int_pow2; +} + +int test_int_non_pow2 (int not_optimizable_int_non_pow2) { + if (not_optimizable_int_non_pow2 == 1) + not_optimizable_int_non_pow2 += 513; + return not_optimizable_int_non_pow2; +} + +float test_float (float not_optimizable_float) { + if (not_optimizable_float > 5) + not_optimizable_float += 1; + return not_optimizable_float; +} + +/* Expecting if-else block in test_float and test_int_non_pow2 only. */ +/* { dg-final { scan-tree-dump-not "if \\(optimizable" "optimized" } } */ +/* { dg-final { scan-tree-dump "if \\(not_optimizable_int_non_pow2" "optimized" } } */ +/* { dg-final { scan-tree-dump "if \\(not_optimizable_float" "optimized" } } */ +/* { dg-final { scan-tree-dump-times "if " 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "else" 2 "optimized" } } */ + +/* Expecting shifted result only for optimizable_int_pow2. */ +/* { dg-final { scan-tree-dump-times " << " 1 "optimized" } } */ +/* { dg-final { scan-tree-dump " << 10;" "optimized" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/ipa-prefetch-xz.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/ipa-prefetch-xz.c new file mode 100644 index 0000000000000000000000000000000000000000..bd4fb2bdc37924ab7b645a5c7ff361ae970b3955 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/ipa-prefetch-xz.c @@ -0,0 +1,1843 @@ +/* { dg-do link } */ +/* { dg-options "-O3 -fipa-ic -fipa-prefetch -flto -flto-partition=one -fdump-ipa-ipa_prefetch -fdump-ipa-icp" } */ +/* { dg-require-effective-target lto } */ + +/* Based on opensource xz code. */ + +#include +#include + +typedef long int ptrdiff_t; +typedef long unsigned int size_t; +typedef unsigned int wchar_t; + +typedef unsigned char __u_char; +typedef unsigned short int __u_short; +typedef unsigned int __u_int; +typedef unsigned long int __u_long; + +typedef signed char __int8_t; +typedef unsigned char __uint8_t; +typedef signed short int __int16_t; +typedef unsigned short int __uint16_t; +typedef signed int __int32_t; +typedef unsigned int __uint32_t; + +typedef signed long int __int64_t; +typedef unsigned long int __uint64_t; + +typedef __int8_t __int_least8_t; +typedef __uint8_t __uint_least8_t; +typedef __int16_t __int_least16_t; +typedef __uint16_t __uint_least16_t; +typedef __int32_t __int_least32_t; +typedef __uint32_t __uint_least32_t; +typedef __int64_t __int_least64_t; +typedef __uint64_t __uint_least64_t; + +typedef __int8_t int8_t; +typedef __int16_t int16_t; +typedef __int32_t int32_t; +typedef __int64_t int64_t; + +typedef __uint8_t uint8_t; +typedef __uint16_t uint16_t; +typedef __uint32_t uint32_t; +typedef __uint64_t uint64_t; + +typedef long int intptr_t; +typedef unsigned long int uintptr_t; + +static inline uint16_t +read16ne(const uint8_t *buf) +{ + uint16_t num; + memcpy(&num, buf, sizeof(num)); + return num; +} + +static inline uint32_t +read32ne(const uint8_t *buf) +{ + uint32_t num; + memcpy(&num, buf, sizeof(num)); + return num; +} + +static inline uint16_t +aligned_read16ne(const uint8_t *buf) +{ + uint16_t num; + memcpy(&num, __builtin_assume_aligned(buf, sizeof(num)), sizeof(num)); + return num; +} + + +static inline uint32_t +aligned_read32ne(const uint8_t *buf) +{ + uint32_t num; + memcpy(&num, __builtin_assume_aligned(buf, sizeof(num)), sizeof(num)); + return num; +} + +static inline uint64_t +aligned_read64ne(const uint8_t *buf) +{ + uint64_t num; + memcpy(&num, __builtin_assume_aligned(buf, sizeof(num)), sizeof(num)); + return num; +} + +typedef unsigned char lzma_bool; + +typedef enum { + LZMA_RESERVED_ENUM = 0 +} lzma_reserved_enum; + +typedef enum { + LZMA_OK = 0, + LZMA_STREAM_END = 1, + LZMA_NO_CHECK = 2, + LZMA_UNSUPPORTED_CHECK = 3, + LZMA_GET_CHECK = 4, + LZMA_MEM_ERROR = 5, + LZMA_MEMLIMIT_ERROR = 6, + LZMA_FORMAT_ERROR = 7, + LZMA_OPTIONS_ERROR = 8, + LZMA_DATA_ERROR = 9, + LZMA_BUF_ERROR = 10, + LZMA_PROG_ERROR = 11, +} lzma_ret; + +typedef enum { + LZMA_RUN = 0, + LZMA_SYNC_FLUSH = 1, + LZMA_FULL_FLUSH = 2, + LZMA_FULL_BARRIER = 4, + LZMA_FINISH = 3 +} lzma_action; + +typedef struct { + void *( *alloc)(void *opaque, size_t nmemb, size_t size); + + void ( *free)(void *opaque, void *ptr); + + void *opaque; +} lzma_allocator; + +typedef uint64_t lzma_vli; + +typedef enum { + LZMA_CHECK_NONE = 0, + LZMA_CHECK_CRC32 = 1, + LZMA_CHECK_CRC64 = 4, + LZMA_CHECK_SHA256 = 10 +} lzma_check; + +typedef struct { + lzma_vli id; + void *options; +} lzma_filter; + +typedef enum { + LZMA_MF_HC3 = 0x03, + LZMA_MF_HC4 = 0x04, + LZMA_MF_BT2 = 0x12, + LZMA_MF_BT3 = 0x13, + LZMA_MF_BT4 = 0x14 +} lzma_match_finder; + +typedef struct lzma_next_coder_s lzma_next_coder; + +typedef struct lzma_filter_info_s lzma_filter_info; + +typedef lzma_ret (*lzma_init_function)( + lzma_next_coder *next, const lzma_allocator *allocator, + const lzma_filter_info *filters); + +typedef lzma_ret (*lzma_code_function)( + void *coder, const lzma_allocator *allocator, + const uint8_t *restrict in, size_t *restrict in_pos, + size_t in_size, uint8_t *restrict out, + size_t *restrict out_pos, size_t out_size, + lzma_action action); + +typedef void (*lzma_end_function)( + void *coder, const lzma_allocator *allocator); + +struct lzma_filter_info_s { + lzma_vli id; + lzma_init_function init; + void *options; +}; + +struct lzma_next_coder_s { + void *coder; + lzma_vli id; + uintptr_t init; + + lzma_code_function code; + lzma_end_function end; + void (*get_progress)(void *coder, + uint64_t *progress_in, uint64_t *progress_out); + + lzma_check (*get_check)(const void *coder); + lzma_ret (*memconfig)(void *coder, uint64_t *memusage, + uint64_t *old_memlimit, uint64_t new_memlimit); + lzma_ret (*update)(void *coder, const lzma_allocator *allocator, + const lzma_filter *filters, const lzma_filter *reversed_filters); +}; + +typedef struct { + uint32_t len; + uint32_t dist; +} lzma_match; + +typedef struct lzma_mf_s lzma_mf; +struct lzma_mf_s { + uint8_t *buffer; + uint32_t size; + uint32_t keep_size_before; + uint32_t keep_size_after; + uint32_t offset; + uint32_t read_pos; + uint32_t read_ahead; + uint32_t read_limit; + uint32_t write_pos; + uint32_t pending; + uint32_t (*find)(lzma_mf *mf, lzma_match *matches); + void (*skip)(lzma_mf *mf, uint32_t num); + uint32_t *hash; + uint32_t *son; + uint32_t cyclic_pos; + uint32_t cyclic_size; + uint32_t hash_mask; + uint32_t depth; + uint32_t nice_len; + uint32_t match_len_max; + lzma_action action; + uint32_t hash_count; + uint32_t sons_count; +}; + +typedef struct { + size_t before_size; + size_t dict_size; + size_t after_size; + size_t match_len_max; + size_t nice_len; + lzma_match_finder match_finder; + uint32_t depth; + const uint8_t *preset_dict; + uint32_t preset_dict_size; +} lzma_lz_options; + +typedef struct { + void *coder; + lzma_ret (*code)(void *coder, + lzma_mf *restrict mf, uint8_t *restrict out, + size_t *restrict out_pos, size_t out_size); + void (*end)(void *coder, const lzma_allocator *allocator); + lzma_ret (*options_update)(void *coder, const lzma_filter *filter); +} lzma_lz_encoder; + +static inline const uint8_t * +mf_ptr(const lzma_mf *mf) +{ + return mf->buffer + mf->read_pos; +} + +static inline uint32_t +mf_avail(const lzma_mf *mf) +{ + return mf->write_pos - mf->read_pos; +} + +typedef struct { + uint32_t state[8]; + uint64_t size; +} lzma_sha256_state; + +typedef struct { + union { + uint8_t u8[64]; + uint32_t u32[16]; + uint64_t u64[8]; + } buffer; + union { + uint32_t crc32; + uint64_t crc64; + lzma_sha256_state sha256; + } state; +} lzma_check_state; + +// The table is constantly initialized in the original code. +// Skip it in the test. +const uint32_t lzma_crc32_table[8][256]; + +static inline uint32_t __attribute__((__always_inline__)) +lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, + uint32_t len, uint32_t limit) +{ + while (len < limit) { + uint32_t x = read32ne(buf1 + len) - read32ne(buf2 + len); + if (x != 0) { + if ((x & 0xFFFF) == 0) { + len += 2; + x >>= 16; + } + + if ((x & 0xFF) == 0) + ++len; + + return ((len) < (limit) ? (len) : (limit)); + } + + len += 4; + } + + return limit; +} + +extern uint32_t +lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches) +{ + const uint32_t count = mf->find(mf, matches); + uint32_t len_best = 0; + + if (count > 0) { + len_best = matches[count - 1].len; + if (len_best == mf->nice_len) { + uint32_t limit = mf_avail(mf) + 1; + if (limit > mf->match_len_max) + limit = mf->match_len_max; + const uint8_t *p1 = mf_ptr(mf) - 1; + const uint8_t *p2 = p1 - matches[count - 1].dist - 1; + len_best = lzma_memcmplen(p1, p2, len_best, limit); + } + } + + *count_ptr = count; + ++mf->read_ahead; + + return len_best; +} + +static void +normalize(lzma_mf *mf) +{ + const uint32_t subvalue = ((4294967295U) - mf->cyclic_size); + + for (uint32_t i = 0; i < mf->hash_count; ++i) { + if (mf->hash[i] <= subvalue) + mf->hash[i] = 0; + else + mf->hash[i] -= subvalue; + } + + for (uint32_t i = 0; i < mf->sons_count; ++i) { + if (mf->son[i] <= subvalue) + mf->son[i] = 0; + else + mf->son[i] -= subvalue; + } + + mf->offset -= subvalue; + return; +} + +static void +move_pos(lzma_mf *mf) +{ + if (++mf->cyclic_pos == mf->cyclic_size) + mf->cyclic_pos = 0; + ++mf->read_pos; + if (__builtin_expect(mf->read_pos + mf->offset == (4294967295U), 0 )) + normalize(mf); +} + +static void +move_pending(lzma_mf *mf) +{ + ++mf->read_pos; + ++mf->pending; +} + +static lzma_match * +hc_find_func( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size, + lzma_match *matches, + uint32_t len_best) +{ + son[cyclic_pos] = cur_match; + + while (1) { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) + return matches; + + const uint8_t *const pb = cur - delta; + cur_match = son[cyclic_pos - delta + + (delta > cyclic_pos ? cyclic_size : 0)]; + + if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) { + uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit); + + if (len_best < len) { + len_best = len; + matches->len = len; + matches->dist = delta - 1; + ++matches; + + if (len == len_limit) + return matches; + } + } + } +} + +extern uint32_t +lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (3)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t cur_match = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + uint32_t len_best = 2; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = lzma_memcmplen(cur - delta2, cur, len_best, len_limit); + + matches[0].len = len_best; + matches[0].dist = delta2 - 1; + matches_count = 1; + + if (len_best == len_limit) { + mf->son[mf->cyclic_pos] = cur_match; + move_pos(mf); + return 1; + } + } + + matches_count = hc_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount) +{ + do { + if (mf_avail(mf) < 3) { + move_pending(mf); + continue; + } + + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t cur_match + = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + do { mf->son[mf->cyclic_pos] = cur_match; move_pos(mf); } while (0); + + } while (--amount != 0); +} + +extern uint32_t +lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (4)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) + & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t delta3 + = pos - mf->hash[((1U << 10)) + hash_3_value]; + const uint32_t cur_match = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value ] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + uint32_t len_best = 1; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = 2; + matches[0].len = 2; + matches[0].dist = delta2 - 1; + matches_count = 1; + } + + if (delta2 != delta3 && delta3 < mf->cyclic_size + && *(cur - delta3) == *cur) { + len_best = 3; + matches[matches_count++].dist = delta3 - 1; + delta2 = delta3; + } + + if (matches_count != 0) { + len_best = lzma_memcmplen(cur - delta2, cur, + len_best, len_limit); + + matches[matches_count - 1].len = len_best; + + if (len_best == len_limit) { + mf->son[mf->cyclic_pos] = cur_match; move_pos(mf); + return matches_count; + } + } + + if (len_best < 3) + len_best = 3; + + matches_count = hc_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount) +{ + do { + if (mf_avail(mf) < 4) { + move_pending(mf); + continue; + } + + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + + const uint32_t cur_match + = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + mf->son[mf->cyclic_pos] = cur_match; + move_pos(mf); + } while (--amount != 0); +} + +static lzma_match * +bt_find_func( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size, + lzma_match *matches, + uint32_t len_best) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (1) { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) { + *ptr0 = 0; + *ptr1 = 0; + return matches; + } + + uint32_t *const pair = son + ((cyclic_pos - delta + + (delta > cyclic_pos ? cyclic_size : 0)) + << 1); + + const uint8_t *const pb = cur - delta; + uint32_t len = ((len0) < (len1) ? (len0) : (len1)); + + if (pb[len] == cur[len]) { + len = lzma_memcmplen(pb, cur, len + 1, len_limit); + + if (len_best < len) { + len_best = len; + matches->len = len; + matches->dist = delta - 1; + ++matches; + + if (len == len_limit) { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return matches; + } + } + } + + if (pb[len] < cur[len]) { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } else { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} + + +static void +bt_skip_func( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (1) { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) { + *ptr0 = 0; + *ptr1 = 0; + return; + } + + uint32_t *pair = son + ((cyclic_pos - delta + + (delta > cyclic_pos ? cyclic_size : 0)) + << 1); + const uint8_t *pb = cur - delta; + uint32_t len = ((len0) < (len1) ? (len0) : (len1)); + + if (pb[len] == cur[len]) { + len = lzma_memcmplen(pb, cur, len + 1, len_limit); + + if (len == len_limit) { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + + if (pb[len] < cur[len]) { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } else { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} + +extern uint32_t +lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (2) || (mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + const uint32_t hash_value = read16ne(cur); + const uint32_t cur_match = mf->hash[hash_value]; + mf->hash[hash_value] = pos; + + matches_count = bt_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, 1) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount) +{ + do { + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (2) || (mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + continue; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t hash_value = read16ne(cur); + const uint32_t cur_match = mf->hash[hash_value]; + mf->hash[hash_value] = pos; + + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + } while (--amount != 0); +} + +extern uint32_t +lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (3) || (1 && mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t cur_match = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + uint32_t len_best = 2; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = lzma_memcmplen( + cur, cur - delta2, len_best, len_limit); + + matches[0].len = len_best; + matches[0].dist = delta2 - 1; + matches_count = 1; + + if (len_best == len_limit) { + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + return 1; + } + } + + matches_count = bt_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + + +extern void +lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount) +{ + do { + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; } + else if (len_limit < (3) || (1 && mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + continue; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t cur_match = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + } while (--amount != 0); +} + +extern uint32_t +lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf->write_pos - mf->read_pos; + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (4) || (mf->action == LZMA_SYNC_FLUSH)) { + ++mf->read_pos; + ++mf->pending; + return 0; + } + + const uint8_t *cur = mf->buffer + mf->read_pos; + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + + uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t delta3 = pos - mf->hash[((1U << 10)) + hash_3_value]; + const uint32_t cur_match = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + uint32_t len_best = 1; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = 2; + matches[0].len = 2; + matches[0].dist = delta2 - 1; + matches_count = 1; + } + + if (delta2 != delta3 && delta3 < mf->cyclic_size && *(cur - delta3) == *cur) { + len_best = 3; + matches[matches_count++].dist = delta3 - 1; + delta2 = delta3; + } + + if (matches_count != 0) { + len_best = lzma_memcmplen(cur, cur - delta2, len_best, len_limit); + + matches[matches_count - 1].len = len_best; + + if (len_best == len_limit) { + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + return matches_count; + } + } + + if (len_best < 3) + len_best = 3; + + matches_count = bt_find_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount) +{ + do { + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (4) || (mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + continue; + } + + const uint8_t *cur = mf->buffer + mf->read_pos; + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) + & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + + const uint32_t cur_match = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + } while (--amount != 0); +} + +static inline void +mf_skip(lzma_mf *mf, uint32_t amount) +{ + if (amount != 0) { + mf->skip(mf, amount); + mf->read_ahead += amount; + } +} + +typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder; +typedef uint16_t probability; + +typedef struct { + probability choice; + probability choice2; + probability low[(1 << 4)][(1 << 3)]; + probability mid[(1 << 4)][(1 << 3)]; + probability high[(1 << 8)]; + uint32_t prices[(1 << 4)][((1 << 3) + (1 << 3) + (1 << 8))]; + uint32_t table_size; + uint32_t counters[(1 << 4)]; +} lzma_length_encoder; + +typedef struct { + uint64_t low; + uint64_t cache_size; + uint32_t range; + uint8_t cache; + size_t count; + size_t pos; + + enum { + RC_BIT_0, + RC_BIT_1, + RC_DIRECT_0, + RC_DIRECT_1, + RC_FLUSH, + } symbols[58]; + + probability *probs[58]; +} lzma_range_encoder; + + +typedef enum { + STATE_LIT_LIT, + STATE_MATCH_LIT_LIT, + STATE_REP_LIT_LIT, + STATE_SHORTREP_LIT_LIT, + STATE_MATCH_LIT, + STATE_REP_LIT, + STATE_SHORTREP_LIT, + STATE_LIT_MATCH, + STATE_LIT_LONGREP, + STATE_LIT_SHORTREP, + STATE_NONLIT_MATCH, + STATE_NONLIT_REP, +} lzma_lzma_state; + +typedef struct { + lzma_lzma_state state; + _Bool prev_1_is_literal; + _Bool prev_2; + + uint32_t pos_prev_2; + uint32_t back_prev_2; + + uint32_t price; + uint32_t pos_prev; + uint32_t back_prev; + + uint32_t backs[4]; +} lzma_optimal; + +struct lzma_lzma1_encoder_s { + lzma_range_encoder rc; + lzma_lzma_state state; + uint32_t reps[4]; + lzma_match matches[(2 + ((1 << 3) + (1 << 3) + (1 << 8)) - 1) + 1]; + uint32_t matches_count; + uint32_t longest_match_length; + _Bool fast_mode; + _Bool is_initialized; + _Bool is_flushed; + uint32_t pos_mask; + uint32_t literal_context_bits; + uint32_t literal_pos_mask; + + probability literal[(1 << 4)][0x300]; + probability is_match[12][(1 << 4)]; + probability is_rep[12]; + probability is_rep0[12]; + probability is_rep1[12]; + probability is_rep2[12]; + probability is_rep0_long[12][(1 << 4)]; + probability dist_slot[4][(1 << 6)]; + probability dist_special[(1 << (14 / 2)) - 14]; + probability dist_align[(1 << 4)]; + + lzma_length_encoder match_len_encoder; + lzma_length_encoder rep_len_encoder; + + uint32_t dist_slot_prices[4][(1 << 6)]; + uint32_t dist_prices[4][(1 << (14 / 2))]; + uint32_t dist_table_size; + uint32_t match_price_count; + + uint32_t align_prices[(1 << 4)]; + uint32_t align_price_count; + uint32_t opts_end_index; + uint32_t opts_current_index; + lzma_optimal opts[(1 << 12)]; +}; + +extern void +lzma_lzma_optimum_fast(lzma_lzma1_encoder *restrict coder, + lzma_mf *restrict mf, + uint32_t *restrict back_res, uint32_t *restrict len_res) +{ + const uint32_t nice_len = mf->nice_len; + + uint32_t len_main; + uint32_t matches_count; + if (mf->read_ahead == 0) { + len_main = lzma_mf_find(mf, &matches_count, coder->matches); + } else { + len_main = coder->longest_match_length; + matches_count = coder->matches_count; + } + + const uint8_t *buf = mf_ptr(mf) - 1; + const uint32_t buf_avail + = ((mf_avail(mf) + 1) < ((2 + ((1 << 3) + (1 << 3) + (1 << 8)) - 1)) + ? (mf_avail(mf) + 1) : ((2 + ((1 << 3) + (1 << 3) + (1 << 8)) - 1))); + + if (buf_avail < 2) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + + uint32_t rep_len = 0; + uint32_t rep_index = 0; + + for (uint32_t i = 0; i < 4; ++i) { + const uint8_t *const buf_back = buf - coder->reps[i] - 1; + if ((read16ne(buf) != read16ne(buf_back))) + continue; + const uint32_t len = lzma_memcmplen(buf, buf_back, 2, buf_avail); + if (len >= nice_len) { + *back_res = i; + *len_res = len; + mf_skip(mf, len - 1); + return; + } + if (len > rep_len) { + rep_index = i; + rep_len = len; + } + } + if (len_main >= nice_len) { + *back_res = coder->matches[matches_count - 1].dist + 4; + *len_res = len_main; + mf_skip(mf, len_main - 1); + return; + } + + uint32_t back_main = 0; + if (len_main >= 2) { + back_main = coder->matches[matches_count - 1].dist; + while (matches_count > 1 && len_main == + coder->matches[matches_count - 2].len + 1) { + if (!(((back_main) >> 7) > (coder->matches[ matches_count - 2].dist))) + break; + --matches_count; + len_main = coder->matches[matches_count - 1].len; + back_main = coder->matches[matches_count - 1].dist; + } + if (len_main == 2 && back_main >= 0x80) + len_main = 1; + } + + if (rep_len >= 2) { + if (rep_len + 1 >= len_main + || (rep_len + 2 >= len_main + && back_main > (1U << 9)) + || (rep_len + 3 >= len_main + && back_main > (1U << 15))) { + *back_res = rep_index; + *len_res = rep_len; + mf_skip(mf, rep_len - 1); + return; + } + } + + if (len_main < 2 || buf_avail <= 2) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + + coder->longest_match_length = lzma_mf_find(mf, + &coder->matches_count, coder->matches); + + if (coder->longest_match_length >= 2) { + const uint32_t new_dist = coder->matches[ + coder->matches_count - 1].dist; + + if ((coder->longest_match_length >= len_main + && new_dist < back_main) + || (coder->longest_match_length == len_main + 1 + && !(((new_dist) >> 7) > (back_main))) + || (coder->longest_match_length > len_main + 1) + || (coder->longest_match_length + 1 >= len_main + && len_main >= 3 + && (((back_main) >> 7) > (new_dist)))) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + } + ++buf; + const uint32_t limit = ((2) > (len_main - 1) ? (2) : (len_main - 1)); + for (uint32_t i = 0; i < 4; ++i) { + if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + } + + *back_res = back_main + 4; + *len_res = len_main; + mf_skip(mf, len_main - 2); + return; +} + +static inline void +rc_bit(lzma_range_encoder *rc, probability *prob, uint32_t bit) +{ + rc->symbols[rc->count] = bit; + rc->probs[rc->count] = prob; + ++rc->count; +} + +static inline void +rc_bittree(lzma_range_encoder *rc, probability *probs, + uint32_t bit_count, uint32_t symbol) +{ + uint32_t model_index = 1; + + do { + const uint32_t bit = (symbol >> --bit_count) & 1; + rc_bit(rc, &probs[model_index], bit); + model_index = (model_index << 1) + bit; + } while (bit_count != 0); +} + +static _Bool +encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf) +{ + if (mf->read_pos == mf->read_limit) { + if (mf->action == LZMA_RUN) + return 0; + } else { + mf_skip(mf, 1); + mf->read_ahead = 0; + rc_bit(&coder->rc, &coder->is_match[0][0], 0); + rc_bittree(&coder->rc, coder->literal[0], 8, mf->buffer[0]); + } + + coder->is_initialized = 1; + + return 1; +} + +static inline uint32_t +mf_position(const lzma_mf *mf) +{ + return mf->read_pos - mf->read_ahead; +} + +static inline _Bool +rc_shift_low(lzma_range_encoder *rc, + uint8_t *out, size_t *out_pos, size_t out_size) +{ + if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000) + || (uint32_t)(rc->low >> 32) != 0) { + do { + if (*out_pos == out_size) + return 1; + + out[*out_pos] = rc->cache + (uint8_t)(rc->low >> 32); + ++*out_pos; + rc->cache = 0xFF; + } while (--rc->cache_size != 0); + rc->cache = (rc->low >> 24) & 0xFF; + } + + ++rc->cache_size; + rc->low = (rc->low & 0x00FFFFFF) << 8; + return 0; +} + +static inline void +rc_reset(lzma_range_encoder *rc) +{ + rc->low = 0; + rc->cache_size = 1; + rc->range = (4294967295U); + rc->cache = 0; + rc->count = 0; + rc->pos = 0; +} + +static inline _Bool +rc_encode(lzma_range_encoder *rc, + uint8_t *out, size_t *out_pos, size_t out_size) +{ + while (rc->pos < rc->count) { + if (rc->range < (1U << 24)) { + if (rc_shift_low(rc, out, out_pos, out_size)) + return 1; + rc->range <<= 8; + } + + switch (rc->symbols[rc->pos]) { + case RC_BIT_0: { + probability prob = *rc->probs[rc->pos]; + rc->range = (rc->range >> 11) + * prob; + prob += ((1U << 11) - prob) >> 5; + *rc->probs[rc->pos] = prob; + break; + } + + case RC_BIT_1: { + probability prob = *rc->probs[rc->pos]; + const uint32_t bound = prob * (rc->range + >> 11); + rc->low += bound; + rc->range -= bound; + prob -= prob >> 5; + *rc->probs[rc->pos] = prob; + break; + } + + case RC_DIRECT_0: + rc->range >>= 1; + break; + + case RC_DIRECT_1: + rc->range >>= 1; + rc->low += rc->range; + break; + + case RC_FLUSH: + rc->range = (4294967295U); + do { + if (rc_shift_low(rc, out, out_pos, out_size)) + return 1; + } while (++rc->pos < rc->count); + + rc_reset(rc); + return 0; + + default: + break; + } + ++rc->pos; + } + + rc->count = 0; + rc->pos = 0; + return 0; +} + +static inline uint64_t +rc_pending(const lzma_range_encoder *rc) +{ + return rc->cache_size + 5 - 1; +} + +static inline void +literal_matched(lzma_range_encoder *rc, probability *subcoder, + uint32_t match_byte, uint32_t symbol) +{ + uint32_t offset = 0x100; + symbol += 1U << 8; + + do { + match_byte <<= 1; + const uint32_t match_bit = match_byte & offset; + const uint32_t subcoder_index + = offset + match_bit + (symbol >> 8); + const uint32_t bit = (symbol >> 7) & 1; + rc_bit(rc, &subcoder[subcoder_index], bit); + + symbol <<= 1; + offset &= ~(match_byte ^ symbol); + + } while (symbol < (1U << 16)); +} + +static inline void +literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position) +{ + const uint8_t cur_byte = mf->buffer[mf->read_pos - mf->read_ahead]; + probability *subcoder = ((coder->literal)[ + (((position) & (coder->literal_pos_mask)) + << (coder->literal_context_bits)) + + ((uint32_t)(mf->buffer[mf->read_pos - mf->read_ahead - 1]) + >> (8U - (coder->literal_context_bits)))]); + + if (((coder->state) < 7)) { + rc_bittree(&coder->rc, subcoder, 8, cur_byte); + } else { + const uint8_t match_byte + = mf->buffer[mf->read_pos - coder->reps[0] - 1 - mf->read_ahead]; + literal_matched(&coder->rc, subcoder, match_byte, cur_byte); + } + coder->state + = ((coder->state) <= STATE_SHORTREP_LIT_LIT + ? STATE_LIT_LIT : ((coder->state) <= STATE_LIT_SHORTREP + ? (coder->state) - 3 : (coder->state) - 6)); +} + +const uint8_t lzma_rc_prices[] = { + 128, 103, 91, 84, 78, 73, 69, 66, + 63, 61, 58, 56, 54, 52, 51, 49, + 48, 46, 45, 44, 43, 42, 41, 40, + 39, 38, 37, 36, 35, 34, 34, 33, + 32, 31, 31, 30, 29, 29, 28, 28, + 27, 26, 26, 25, 25, 24, 24, 23, + 23, 22, 22, 22, 21, 21, 20, 20, + 19, 19, 19, 18, 18, 17, 17, 17, + 16, 16, 16, 15, 15, 15, 14, 14, + 14, 13, 13, 13, 12, 12, 12, 11, + 11, 11, 11, 10, 10, 10, 10, 9, + 9, 9, 9, 8, 8, 8, 8, 7, + 7, 7, 7, 6, 6, 6, 6, 5, + 5, 5, 5, 5, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1 +}; + +static inline uint32_t +rc_bit_price(const probability prob, const uint32_t bit) +{ + return lzma_rc_prices[(prob ^ ((0U - bit) + & ((1U << 11) - 1))) >> 4]; +} + +static inline uint32_t +rc_bit_0_price(const probability prob) +{ + return lzma_rc_prices[prob >> 4]; +} + +static inline uint32_t +rc_bit_1_price(const probability prob) +{ + return lzma_rc_prices[(prob ^ ((1U << 11) - 1)) + >> 4]; +} + +static inline uint32_t +rc_bittree_price(const probability *const probs, + const uint32_t bit_levels, uint32_t symbol) +{ + uint32_t price = 0; + symbol += 1U << bit_levels; + + do { + const uint32_t bit = symbol & 1; + symbol >>= 1; + price += rc_bit_price(probs[symbol], bit); + } while (symbol != 1); + + return price; +} + +static void +length_update_prices(lzma_length_encoder *lc, const uint32_t pos_state) +{ + const uint32_t table_size = lc->table_size; + lc->counters[pos_state] = table_size; + + const uint32_t a0 = rc_bit_0_price(lc->choice); + const uint32_t a1 = rc_bit_1_price(lc->choice); + const uint32_t b0 = a1 + rc_bit_0_price(lc->choice2); + const uint32_t b1 = a1 + rc_bit_1_price(lc->choice2); + uint32_t *const prices = lc->prices[pos_state]; + + uint32_t i; + for (i = 0; i < table_size && i < (1 << 3); ++i) + prices[i] = a0 + rc_bittree_price(lc->low[pos_state], + 3, i); + + for (; i < table_size && i < (1 << 3) + (1 << 3); ++i) + prices[i] = b0 + rc_bittree_price(lc->mid[pos_state], + 3, i - (1 << 3)); + + for (; i < table_size; ++i) + prices[i] = b1 + rc_bittree_price(lc->high, 8, + i - (1 << 3) - (1 << 3)); + + return; +} + +static inline void +length(lzma_range_encoder *rc, lzma_length_encoder *lc, + const uint32_t pos_state, uint32_t len, const _Bool fast_mode) +{ + len -= 2; + + if (len < (1 << 3)) { + rc_bit(rc, &lc->choice, 0); + rc_bittree(rc, lc->low[pos_state], 3, len); + } else { + rc_bit(rc, &lc->choice, 1); + len -= (1 << 3); + + if (len < (1 << 3)) { + rc_bit(rc, &lc->choice2, 0); + rc_bittree(rc, lc->mid[pos_state], 3, len); + } else { + rc_bit(rc, &lc->choice2, 1); + len -= (1 << 3); + rc_bittree(rc, lc->high, 8, len); + } + } + + if (!fast_mode) + if (--lc->counters[pos_state] == 0) + length_update_prices(lc, pos_state); +} + +static inline void +rep_match(lzma_lzma1_encoder *coder, const uint32_t pos_state, + const uint32_t rep, const uint32_t len) +{ + if (rep == 0) { + rc_bit(&coder->rc, &coder->is_rep0[coder->state], 0); + rc_bit(&coder->rc, + &coder->is_rep0_long[coder->state][pos_state], + len != 1); + } else { + const uint32_t distance = coder->reps[rep]; + rc_bit(&coder->rc, &coder->is_rep0[coder->state], 1); + + if (rep == 1) { + rc_bit(&coder->rc, &coder->is_rep1[coder->state], 0); + } else { + rc_bit(&coder->rc, &coder->is_rep1[coder->state], 1); + rc_bit(&coder->rc, &coder->is_rep2[coder->state], + rep - 2); + + if (rep == 3) + coder->reps[3] = coder->reps[2]; + + coder->reps[2] = coder->reps[1]; + } + + coder->reps[1] = coder->reps[0]; + coder->reps[0] = distance; + } + + if (len == 1) { + coder->state = ((coder->state) < 7 ? STATE_LIT_SHORTREP : STATE_NONLIT_REP); + } else { + length(&coder->rc, &coder->rep_len_encoder, pos_state, len, + coder->fast_mode); + coder->state = ((coder->state) < 7 ? STATE_LIT_LONGREP : STATE_NONLIT_REP); + } +} + +// This array is constantly initialized in the original code. It's quite big +// so we skip it. +const uint8_t lzma_fastpos[1 << 13]; + +static inline uint32_t +get_dist_slot(uint32_t dist) +{ + if (dist < (1U << (13 + ((0) + (0) * (13 - 1))))) + return lzma_fastpos[dist]; + + if (dist < (1U << (13 + ((0) + (1) * (13 - 1))))) + return (uint32_t)(lzma_fastpos[(dist) >> ((0) + (1) * (13 - 1))]) + 2 * ((0) + (1) * (13 - 1)); + + return (uint32_t)(lzma_fastpos[(dist) >> ((0) + (2) * (13 - 1))]) + 2 * ((0) + (2) * (13 - 1)); +} + +static inline void +rc_bittree_reverse(lzma_range_encoder *rc, probability *probs, + uint32_t bit_count, uint32_t symbol) +{ + uint32_t model_index = 1; + do { + const uint32_t bit = symbol & 1; + symbol >>= 1; + rc_bit(rc, &probs[model_index], bit); + model_index = (model_index << 1) + bit; + } while (--bit_count != 0); +} + +static inline void +rc_direct(lzma_range_encoder *rc, uint32_t value, uint32_t bit_count) +{ + do { + rc->symbols[rc->count++] + = RC_DIRECT_0 + ((value >> --bit_count) & 1); + } while (bit_count != 0); +} + +static inline void +match(lzma_lzma1_encoder *coder, const uint32_t pos_state, + const uint32_t distance, const uint32_t len) +{ + coder->state = ((coder->state) < 7 ? STATE_LIT_MATCH : STATE_NONLIT_MATCH); + + length(&coder->rc, &coder->match_len_encoder, pos_state, len, + coder->fast_mode); + + const uint32_t dist_slot = get_dist_slot(distance); + const uint32_t dist_state = ((len) < 4 + 2 ? (len) - 2 : 4 - 1); + rc_bittree(&coder->rc, coder->dist_slot[dist_state], 6, dist_slot); + + if (dist_slot >= 4) { + const uint32_t footer_bits = (dist_slot >> 1) - 1; + const uint32_t base = (2 | (dist_slot & 1)) << footer_bits; + const uint32_t dist_reduced = distance - base; + + if (dist_slot < 14) { + rc_bittree_reverse(&coder->rc, coder->dist_special + base - dist_slot - 1, + footer_bits, dist_reduced); + } else { + rc_direct(&coder->rc, dist_reduced >> 4, + footer_bits - 4); + rc_bittree_reverse( + &coder->rc, coder->dist_align, + 4, dist_reduced & ((1 << 4) - 1)); + ++coder->align_price_count; + } + } + + coder->reps[3] = coder->reps[2]; + coder->reps[2] = coder->reps[1]; + coder->reps[1] = coder->reps[0]; + coder->reps[0] = distance; + ++coder->match_price_count; +} + +static void +encode_symbol(lzma_lzma1_encoder *coder, lzma_mf *mf, + uint32_t back, uint32_t len, uint32_t position) +{ + const uint32_t pos_state = position & coder->pos_mask; + + if (back == (4294967295U)) { + rc_bit(&coder->rc, + &coder->is_match[coder->state][pos_state], 0); + literal(coder, mf, position); + } else { + rc_bit(&coder->rc, + &coder->is_match[coder->state][pos_state], 1); + + if (back < 4) { + rc_bit(&coder->rc, &coder->is_rep[coder->state], 1); + rep_match(coder, pos_state, back, len); + } else { + rc_bit(&coder->rc, &coder->is_rep[coder->state], 0); + match(coder, pos_state, back - 4, len); + } + } + mf->read_ahead -= len; +} + +static void +encode_eopm(lzma_lzma1_encoder *coder, uint32_t position) +{ + const uint32_t pos_state = position & coder->pos_mask; + rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1); + rc_bit(&coder->rc, &coder->is_rep[coder->state], 0); + match(coder, pos_state, (4294967295U), 2); +} + +static inline void +rc_flush(lzma_range_encoder *rc) +{ + for (size_t i = 0; i < 5; ++i) + rc->symbols[rc->count++] = RC_FLUSH; +} + +extern void exit (int __status) + __attribute__ ((__nothrow__ , __leaf__ , __noreturn__)); + +extern lzma_ret +lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, + uint8_t *restrict out, size_t *restrict out_pos, + size_t out_size, uint32_t limit) +{ + + if (!coder->is_initialized && !encode_init(coder, mf)) + return LZMA_OK; + + uint32_t position = mf_position(mf); + + while (1) { + if (rc_encode(&coder->rc, out, out_pos, out_size)) { + return LZMA_OK; + } + + if (limit != (4294967295U) + && (mf->read_pos - mf->read_ahead >= limit + || *out_pos + rc_pending(&coder->rc) + >= (1U << 16) - ((1 << 12) + 1))) + break; + + if (mf->read_pos >= mf->read_limit) { + if (mf->action == LZMA_RUN) + return LZMA_OK; + + + if (mf->read_ahead == 0) + break; + } + uint32_t len; + uint32_t back; + + if (coder->fast_mode) + lzma_lzma_optimum_fast(coder, mf, &back, &len); + else + // The original code contains the call to + // lzma_lzma_optimum_normal(coder, mf, &back, &len, position); + exit (-1); + + encode_symbol(coder, mf, back, len, position); + + position += len; + } + + if (!coder->is_flushed) { + coder->is_flushed = 1; + if (limit == (4294967295U)) + encode_eopm(coder, position); + + rc_flush(&coder->rc); + + if (rc_encode(&coder->rc, out, out_pos, out_size)) { + return LZMA_OK; + } + } + + coder->is_flushed = 0; + return LZMA_STREAM_END; +} + +extern void +lzma_free(void *ptr, const lzma_allocator *allocator) +{ + if (allocator != ((void *)0) && allocator->free != ((void *)0)) + allocator->free(allocator->opaque, ptr); + else + free(ptr); + return; +} + +static _Bool +lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator, + const lzma_lz_options *lz_options) +{ + if (lz_options->dict_size < 4096U + || lz_options->dict_size + > (1U << 30) + (1U << 29) + || lz_options->nice_len > lz_options->match_len_max) + return 1; + + mf->keep_size_before = lz_options->before_size + lz_options->dict_size; + mf->keep_size_after = lz_options->after_size + + lz_options->match_len_max; + uint32_t reserve = lz_options->dict_size / 2; + if (reserve > (1U << 30)) + reserve /= 2; + + reserve += (lz_options->before_size + lz_options->match_len_max + + lz_options->after_size) / 2 + (1U << 19); + + const uint32_t old_size = mf->size; + mf->size = mf->keep_size_before + reserve + mf->keep_size_after; + + if ((mf->buffer != ((void *)0)) && old_size != mf->size) { + lzma_free(mf->buffer, allocator); + mf->buffer = ((void *)0); + } + + mf->match_len_max = lz_options->match_len_max; + mf->nice_len = lz_options->nice_len; + mf->cyclic_size = lz_options->dict_size + 1; + + switch (lz_options->match_finder) { + case LZMA_MF_HC3: + mf->find = &lzma_mf_hc3_find; + mf->skip = &lzma_mf_hc3_skip; + break; + + case LZMA_MF_HC4: + mf->find = &lzma_mf_hc4_find; + mf->skip = &lzma_mf_hc4_skip; + break; + + case LZMA_MF_BT2: + mf->find = &lzma_mf_bt2_find; + mf->skip = &lzma_mf_bt2_skip; + break; + + case LZMA_MF_BT3: + mf->find = &lzma_mf_bt3_find; + mf->skip = &lzma_mf_bt3_skip; + break; + + case LZMA_MF_BT4: + mf->find = &lzma_mf_bt4_find; + mf->skip = &lzma_mf_bt4_skip; + break; + + default: + return 1; + } + + const uint32_t hash_bytes = lz_options->match_finder & 0x0F; + if (hash_bytes > mf->nice_len) + return 1; + + const _Bool is_bt = (lz_options->match_finder & 0x10) != 0; + uint32_t hs; + + if (hash_bytes == 2) { + hs = 0xFFFF; + } else { + hs = lz_options->dict_size - 1; + hs |= hs >> 1; + hs |= hs >> 2; + hs |= hs >> 4; + hs |= hs >> 8; + hs >>= 1; + hs |= 0xFFFF; + + if (hs > (1U << 24)) { + if (hash_bytes == 3) + hs = (1U << 24) - 1; + else + hs >>= 1; + } + } + + mf->hash_mask = hs; + + ++hs; + if (hash_bytes > 2) + hs += (1U << 10); + if (hash_bytes > 3) + hs += (1U << 16); + + const uint32_t old_hash_count = mf->hash_count; + const uint32_t old_sons_count = mf->sons_count; + mf->hash_count = hs; + mf->sons_count = mf->cyclic_size; + if (is_bt) + mf->sons_count *= 2; + + if (old_hash_count != mf->hash_count + || old_sons_count != mf->sons_count) { + lzma_free(mf->hash, allocator); + mf->hash = ((void *)0); + + lzma_free(mf->son, allocator); + mf->son = ((void *)0); + } + + mf->depth = lz_options->depth; + if (mf->depth == 0) { + if (is_bt) + mf->depth = 16 + mf->nice_len / 2; + else + mf->depth = 4 + mf->nice_len / 4; + } + + return 0; +} + +int +main () +{ + lzma_mf mf; + lzma_allocator allocator; + lzma_lz_options lz_options; + + void *coder; + uint8_t *restrict out; + size_t *restrict out_pos; + size_t out_size; + + lz_encoder_prepare(&mf, &allocator, &lz_options); + return (int) lzma_lzma_encode(coder, &mf, out, out_pos, out_size, (4294967295U)); +} + + +/* { dg-final { scan-wpa-ipa-dump "Save results of indirect call analysis." "icp"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "For call" 2 "icp"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "Insert 0 prefetch stmt:" 5 "ipa_prefetch"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "Insert 1 prefetch stmt:" 4 "ipa_prefetch"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "Insert 2 prefetch stmt:" 2 "ipa_prefetch"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/ipa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/ipa.exp new file mode 100644 index 0000000000000000000000000000000000000000..c947b1366a63d26f049b51748c91c9f268ddb5d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/ipa.exp @@ -0,0 +1,35 @@ +# Copyright (C) 1997-2020 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/pr101066.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/pr101066.c new file mode 100644 index 0000000000000000000000000000000000000000..1ceb6e43136a91297fcdcd45a74fea1d78046456 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/ipa/pr101066.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fno-ipa-cp -fno-inline" } */ + +int a = 1, c, d, e; +int *b = &a; +static int g(int *h) { + c = *h; + return d; +} +static void f(int *h) { + e = *h; + *b = 0; + g(h); +} +int main() { + f(b); + if (c) + __builtin_abort(); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-1.c new file mode 100644 index 0000000000000000000000000000000000000000..8990f0a1c82fd817fc61d815ea4043b530c1466c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-1.c @@ -0,0 +1,61 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -funroll-loops -ffast-math -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param issue-topn=2 --param filter-mode=0" } */ + +#include + +#define N 131590 +#define F 384477 + +double diagPtr[N]; +double psiPtr[N]; +double ApsiPtr[N]; +int lPtr[F]; +int uPtr[F]; +double lowerPtr[F]; +double upperPtr[F]; + +void +AMUL (double *diagPtr, double *psiPtr, double *ApsiPtr, int *lPtr, + int *uPtr, double *lowerPtr, double *upperPtr, int nCells, int nFaces) +{ + for (int cell=0; cell + +#define N 100000 + +int A_i[N]; +int A_j[N]; +double A_data[N]; +double x_data[N]; +double y_data[N]; +int num_rows = N; + +void +MatMult (int *A_i, int *A_j, double *A_data, double *x_data, + int num_rows, double *y_data) +{ + int i = 0; + int j = 0; + double temp = 0; + for (i = 0; i < num_rows; i++) + { + temp = y_data[i]; + for (j = A_i[i]; j < A_i[i+1]; j++) + temp += A_data[j] * x_data[A_j[j]]; + y_data[i] = temp; + } +} + +int +main (int argc, char *argv[]) +{ + int testIter = 2; + + for (int i = 0; i < testIter; i++) + MatMult (A_i, A_j, A_data, x_data, num_rows, y_data); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "ref_count = (?:\[3-9\]|\[1-9\]\\d{1,}), ninsns = \[1-9\]\\d*, mem_to_insn_ratio = 0.\[2-9\]\\d*" 4 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "Tracing succeeded" 14 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-not "Tracing failed" "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-not "static_data_size:" "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "\{ (?:\\d+\\(\\d+\\) ){1}\}" 2 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-not ", size: (?!(0\.000000))" "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times ", size: 0\.000000" 6 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "\\d\\tx_data\\t\\(0.000000, 1, 1, 0\\)" 2 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "\\d\\tA_j\\t\\(0.000000, 1, 1, 0\\)" 2 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "\\d\\tA_data\\t\\(0.000000, 1, 1, 0\\)" 2 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-not "runtime issue" "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "static issue" 2 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "insert svprfd_gather" 2 "llc_allocate" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-allocate.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-allocate.exp new file mode 100644 index 0000000000000000000000000000000000000000..1fbc4f6efde6b6516f770b3402ef8550fd2cb146 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-allocate.exp @@ -0,0 +1,28 @@ +# Copyright (C) 2022-2023 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 +# . + +load_lib gcc-dg.exp +load_lib target-supports.exp + +# Initialize `dg'. +dg-init + +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] \ + "" "-fllc-allocate" + +# All done. +dg-finish + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-cross-bb-indir-mem-acc.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-cross-bb-indir-mem-acc.c new file mode 100644 index 0000000000000000000000000000000000000000..18122c291cb2c9c68d574a750602ad2c0ba231c0 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-cross-bb-indir-mem-acc.c @@ -0,0 +1,36 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -fllc-allocate -fdump-tree-llc_allocate-details-lineno -c --param=mem-access-ratio=1 --param=mem-access-num=0" } */ + +/* In this deja test case, we test how Phase 2 & 3 of llc-allocate pass deals + with an indirect memory access in a nested loop where the use-block for the + induction variable of this memory access is a child/descendent of its + def-block (we make it by defining the induction variable in the outer loop). + Therefore, the reference can be successfully traced after outer-loop + analysis. */ +#include +#include + +void cross_bb_indir_mem_acc (int *arr1, int *arr2, int *arr3, int *arr4, int n) { + srand (time (NULL)); + + int j_s; + int j_e = arr1[0]; + int k; + + for (int i = 0; i < n; i++) + { + j_s = j_e; + j_e = arr1[i + 1]; + + k = arr3[i]; + + for (int j = j_s; j < j_e; j++) + { + arr4[j] -= arr2[k]; + } + + } +} + +/* { dg-final { scan-tree-dump "Unhandled indirect memory access tracing." "llc_allocate" } } */ +/* { dg-final { scan-tree-dump "Retrace indirect memory access after outer loop analysis:" "llc_allocate" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-extend-outer-loop.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-extend-outer-loop.c new file mode 100644 index 0000000000000000000000000000000000000000..6a27f8c62a012a79683a8660c2e8d017ac59680c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-extend-outer-loop.c @@ -0,0 +1,61 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ +#include +#define N 131590 +#define F 384477 + +int ownStartPtr[F]; +double bPrimePtr[N]; +double diagPtr[N]; +double psiPtr[N]; +double upperPtr[F]; +double lowerPtr[F]; +int uPtr[F]; + +void SMOOTH(int *ownStartPtr, double *bPrimePtr, double *diagPtr, double *psiPtr, int *uPtr, double *lowerPtr, double *upperPtr, int nCells); + +int main(int argc, char *argv[]) +{ + int nCells = N; + int nFaces = F; + int testIter = 2; + for (int i = 0; i < testIter; i++) + { + SMOOTH(ownStartPtr, bPrimePtr, diagPtr, psiPtr, uPtr, lowerPtr, upperPtr, nCells); + } + return 0; +} + + +void SMOOTH(int *ownStartPtr, double *bPrimePtr, double *diagPtr, double *psiPtr, int *uPtr, double *lowerPtr, double *upperPtr, int nCells) +{ + double psii; + int fStart; + int fEnd = ownStartPtr[0]; + + for (int celli = 0; celli < nCells; celli++) + { + fStart = fEnd; + fEnd = ownStartPtr[celli + 1]; + psii = bPrimePtr[celli]; + + for (int facei = fStart; facei + +#define N 131590 + +double diagPtr[N]; +double psiPtr[N]; +double ApsiPtr[N]; + +void +branch_in_loop (double *diagPtr, double *psiPtr, double *ApsiPtr, int nCells) +{ + for (int cell=0; cell 0) + ApsiPtr[cell] = 0; + else + ApsiPtr[cell] = diagPtr[cell]*psiPtr[cell]; + } +} + +int +main (int argc, char *argv[]) +{ + int nCells = N; + int testIter = 100; + + for (int i=0; i + +#define N 131590 + +double diagPtr[N]; +double psiPtr[N]; +double ApsiPtr[N]; + +void +break_in_loop (double *diagPtr, double *psiPtr, double *ApsiPtr, int nCells) +{ + for (int cell=0; cell 0) + break; + ApsiPtr[cell] = diagPtr[cell]*psiPtr[cell]; + } +} + +int +main (int argc, char *argv[]) +{ + int nCells = N; + int testIter = 2; + + for (int i=0; i + +#define N 131 + +double diagPtr[N]; +int psiPtr[N]; +double ApsiPtr[N]; + +void +goto_in_loop (double *diagPtr, int *psiPtr, double *ApsiPtr, int nCells) +{ + for (int cell=0; cellnodes; + while (v > 1) + { + basic_block bb = di->dfs_to_bb[v]; + edge e; + + par = di->dfs_parent[v]; + k = v; + + ei = (reverse) ? ei_start (bb->succs) : ei_start (bb->preds); + + if (reverse) + { + /* If this block has a fake edge to exit, process that first. */ + if (bitmap_bit_p (di->fake_exit_edge, bb->index)) + { + einext = ei; + einext.index = 0; + goto do_fake_exit_edge; + } + } + + /* Search all direct predecessors for the smallest node with a path + to them. That way we have the smallest node with also a path to + us only over nodes behind us. In effect we search for our + semidominator. */ + while (!ei_end_p (ei)) + { + basic_block b; + TBB k1; + + e = ei_edge (ei); + b = (reverse) ? e->dest : e->src; + einext = ei; + ei_next (&einext); + + if (b == en_block) + { + do_fake_exit_edge: + k1 = di->dfs_order[last_basic_block]; + } + else + k1 = di->dfs_order[b->index]; + + /* Call eval() only if really needed. If k1 is above V in DFS tree, + then we know, that eval(k1) == k1 and key[k1] == k1. */ + if (k1 > v) + k1 = di->key[eval (di, k1)]; + if (k1 < k) + k = k1; + + ei = einext; + } + + di->key[v] = k; + link_roots (di, par, v); + di->next_bucket[v] = di->bucket[k]; + di->bucket[k] = v; + + /* Transform semidominators into dominators. */ + for (w = di->bucket[par]; w; w = di->next_bucket[w]) + { + k = eval (di, w); + if (di->key[k] < di->key[w]) + di->dom[w] = k; + else + di->dom[w] = par; + } + /* We don't need to cleanup next_bucket[]. */ + di->bucket[par] = 0; + v--; + } + + /* Explicitly define the dominators. */ + di->dom[1] = 0; + for (v = 2; v <= di->nodes; v++) + if (di->dom[v] != di->key[v]) + di->dom[v] = di->dom[di->dom[v]]; +} + +/* { dg-final { scan-tree-dump-times "Warning: Find cycle at bb index" 2 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump "static issue" "llc_allocate" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-filter-ssa.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-filter-ssa.c new file mode 100644 index 0000000000000000000000000000000000000000..4478f753174eac01da4e342308ef7648d0bfe944 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-filter-ssa.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fipa-pta -fllc-allocate -S -fdump-tree-llc_allocate-details-lineno" } */ + +int a, b; +int *d; +void f(void) +{ + int c; + b %= 1; + + if(1 - (b < 1)) + { + int *q = 0; + + if(a) + { + c = 0; +lbl: + for(*d; *d; ++*d) + if(c ? : a ? : (c = 1) ? : 0) + *q &= 1; + return; + } + + q = (int *)1; + } + goto lbl; +} + +/* { dg-final { scan-tree-dump "Unhandled scenario for non-ssa pointer." "llc-allocate" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-loop-generate.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-loop-generate.c new file mode 100644 index 0000000000000000000000000000000000000000..dc1f0eadcfcb6f8011b95d7394ca80163dcb03bf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-loop-generate.c @@ -0,0 +1,168 @@ +/* { dg-require-effective-target label_values } */ +/* { dg-require-stack-size "4000" } */ +/* { dp-option "-O2 -fllc-allocate" } */ + +#include + +#if __INT_MAX__ >= 2147483647 +typedef unsigned int uint32; +typedef signed int sint32; + +typedef uint32 reg_t; + +typedef unsigned long int host_addr_t; +typedef uint32 target_addr_t; +typedef sint32 target_saddr_t; + +typedef union +{ + struct + { + signed int offset:18; + unsigned int ignore:4; + unsigned int s1:8; + int :2; + signed int simm:14; + unsigned int s3:8; + unsigned int s2:8; + int pad2:2; + } f1; + long long ll; + double d; +} insn_t; + +typedef struct +{ + target_addr_t vaddr_tag; + unsigned long int rigged_paddr; +} tlb_entry_t; + +typedef struct +{ + insn_t *pc; + reg_t registers[256]; + insn_t *program; + tlb_entry_t tlb_tab[0x100]; +} environment_t; + +enum operations +{ + LOAD32_RR, + METAOP_DONE +}; + +host_addr_t +f () +{ + abort (); +} + +reg_t +simulator_kernel (int what, environment_t *env) +{ + register insn_t *pc = env->pc; + register reg_t *regs = env->registers; + register insn_t insn; + register int s1; + register reg_t r2; + register void *base_addr = &&sim_base_addr; + register tlb_entry_t *tlb = env->tlb_tab; + + if (what != 0) + { + int i; + static void *op_map[] = + { + &&L_LOAD32_RR, + &&L_METAOP_DONE, + }; + insn_t *program = env->program; + for (i = 0; i < what; i++) + program[i].f1.offset = op_map[program[i].f1.offset] - base_addr; + } + + sim_base_addr:; + + insn = *pc++; + r2 = (*(reg_t *) (((char *) regs) + (insn.f1.s2 << 2))); + s1 = (insn.f1.s1 << 2); + goto *(base_addr + insn.f1.offset); + + L_LOAD32_RR: + { + target_addr_t vaddr_page = r2 / 4096; + unsigned int x = vaddr_page % 0x100; + insn = *pc++; + + for (;;) + { + target_addr_t tag = tlb[x].vaddr_tag; + host_addr_t rigged_paddr = tlb[x].rigged_paddr; + + if (tag == vaddr_page) + { + *(reg_t *) (((char *) regs) + s1) = *(uint32 *) (rigged_paddr + r2); + r2 = *(reg_t *) (((char *) regs) + (insn.f1.s2 << 2)); + s1 = insn.f1.s1 << 2; + goto *(base_addr + insn.f1.offset); + } + + if (((target_saddr_t) tag < 0)) + { + *(reg_t *) (((char *) regs) + s1) = *(uint32 *) f (); + r2 = *(reg_t *) (((char *) regs) + (insn.f1.s2 << 2)); + s1 = insn.f1.s1 << 2; + goto *(base_addr + insn.f1.offset); + } + + x = (x - 1) % 0x100; + } + + L_METAOP_DONE: + return (*(reg_t *) (((char *) regs) + s1)); + } +} + +insn_t program[2 + 1]; + +void *malloc (); + +int +main () +{ + environment_t env; + insn_t insn; + int i, res; + host_addr_t a_page = (host_addr_t) malloc (2 * 4096); + target_addr_t a_vaddr = 0x123450; + target_addr_t vaddr_page = a_vaddr / 4096; + a_page = (a_page + 4096 - 1) & -4096; + + env.tlb_tab[((vaddr_page) % 0x100)].vaddr_tag = vaddr_page; + env.tlb_tab[((vaddr_page) % 0x100)].rigged_paddr = a_page - vaddr_page * 4096; + insn.f1.offset = LOAD32_RR; + env.registers[0] = 0; + env.registers[2] = a_vaddr; + *(sint32 *) (a_page + a_vaddr % 4096) = 88; + insn.f1.s1 = 0; + insn.f1.s2 = 2; + + for (i = 0; i < 2; i++) + program[i] = insn; + + insn.f1.offset = METAOP_DONE; + insn.f1.s1 = 0; + program[2] = insn; + + env.pc = program; + env.program = program; + + res = simulator_kernel (2 + 1, &env); + + if (res != 88) + abort (); + exit (0); +} +#else +main(){ exit (0); } +#endif diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-nonzero-offset.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-nonzero-offset.c new file mode 100644 index 0000000000000000000000000000000000000000..e87f343dcd81f6ccfbe19246ce54ab28f6f74f6a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-nonzero-offset.c @@ -0,0 +1,50 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -c -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param filter-kernels=0" } */ + +#include + +typedef struct stack_def +{ + int top; /* index to top stack element */ + unsigned long reg_set; /* set of live registers */ + unsigned char reg[128]; /* register - stack mapping */ +} *stack; + +typedef struct block_info_def +{ + struct stack_def stack_in; /* Input stack configuration. */ + struct stack_def stack_out; /* Output stack configuration. */ + unsigned long out_reg_set; /* Stack regs live on output. */ + int done; /* True if block already converted. */ + int predecessors; /* Number of predecessors that need + to be visited. */ +} *block_info; + +typedef struct basic_block_def +{ + void *aux; +} *basic_block; + +unsigned char +convert_regs_exit (basic_block bb, int value_reg_low, int value_reg_high) +{ + stack output_stack; + + output_stack = &(((block_info) bb->aux)->stack_in); + if (value_reg_low == -1) + output_stack->top = -1; + else + { + int reg; + output_stack->top = value_reg_high - value_reg_low; + for (reg = value_reg_low; reg <= value_reg_high; ++reg) + { + (output_stack->reg + 16)[value_reg_high - reg] = reg; + output_stack->reg_set |= (unsigned long) 1 << reg; + } + } + return output_stack->reg[0]; +} + +/* { dg-final { scan-tree-dump-times "runtime issue" 1 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "static issue" 1 "llc_allocate" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl1keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl1keep.c new file mode 100644 index 0000000000000000000000000000000000000000..c0fa2db2f8d2f3a0cf03be48dff1981e8f2ad4d1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl1keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options " -S -O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,0); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL1KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl1strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl1strm.c new file mode 100644 index 0000000000000000000000000000000000000000..bcd1113d1a910a3ce8fb30bdd85c0fac5718e70f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl1strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,1); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL1STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl2keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl2keep.c new file mode 100644 index 0000000000000000000000000000000000000000..46702bfbc5c3555b0b944b9cabc98c8584536897 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl2keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,2); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL2KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl2strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl2strm.c new file mode 100644 index 0000000000000000000000000000000000000000..e359ad178364b5d76e9be5b993347fd0a8f17622 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl2strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,3); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL2STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl3keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl3keep.c new file mode 100644 index 0000000000000000000000000000000000000000..0a9dae0905cd27bcbc60e8048dfe506efe7cc7d2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl3keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,4); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL3KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl3strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl3strm.c new file mode 100644 index 0000000000000000000000000000000000000000..58db40ba1acb672e58cee2a216a6f3fc75e30f44 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl3strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,5); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL3STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl4keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl4keep.c new file mode 100644 index 0000000000000000000000000000000000000000..6f6b7bbd4583c1a65ab61ef0a26600a101bbd4b4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl4keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,6); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL4KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl4strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl4strm.c new file mode 100644 index 0000000000000000000000000000000000000000..b69b4a5e60d7671371c20419813ba001bf32bc91 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pldl4strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],0,7); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PLDL4STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl1keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl1keep.c new file mode 100644 index 0000000000000000000000000000000000000000..f5a474eb5d4ff837431377717a31824cc122e6ee --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl1keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,0); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL1KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl1strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl1strm.c new file mode 100644 index 0000000000000000000000000000000000000000..6798824a9260a0a715a24d6048e7e560546e4ea9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl1strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,1); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL1STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl2keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl2keep.c new file mode 100644 index 0000000000000000000000000000000000000000..c19fcc8302d573a23e8282a1c2ff3bfeb956f85e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl2keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,2); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL2KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl2strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl2strm.c new file mode 100644 index 0000000000000000000000000000000000000000..dde160a2846514b4cf3a71e8c8af34b4904770b2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl2strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,3); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL2STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl3keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl3keep.c new file mode 100644 index 0000000000000000000000000000000000000000..fa698243d80930e4d032e16d40e89abb5f0df42c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl3keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,4); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL3KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl3strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl3strm.c new file mode 100644 index 0000000000000000000000000000000000000000..653f7786e522829826a47036351016e48019bd91 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl3strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,5); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL3STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl4keep.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl4keep.c new file mode 100644 index 0000000000000000000000000000000000000000..16a3b6552cda9028d2ea6acc13b94359879acd86 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl4keep.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,6); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL4KEEP" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl4strm.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl4strm.c new file mode 100644 index 0000000000000000000000000000000000000000..60d671bf53d7fe5081ca6383d89357ad3febf6a6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-prefetch-full-pstl4strm.c @@ -0,0 +1,15 @@ + +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=outer-loop-nums=10 --param=issue-topn=4 --param=force-issue=1 --param=filter-kernels=0" } */ + + +int val[100000]; +int main(){ + for(int i=0;i<100000;i++){ + __builtin_prefetch_full(&val[i],1,7); + val[i]=i+1; + } +} + +/* { dg-final { scan-assembler "PSTL4STRM" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-ref-trace.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-ref-trace.c new file mode 100644 index 0000000000000000000000000000000000000000..be5bac2289985351635076754355fb00819d0117 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-ref-trace.c @@ -0,0 +1,62 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param filter-kernels=0" } */ + +#include +#include + +#define N 1000 + +long a[N] = {0}; +long b[N] = {0}; +long c[N] = {0}; + +double +referenceTrace (double *psiPtr, int *lPtr, int *uPtr, int nCells) +{ + double sum; + for (int cell = 0; cell < nCells; cell++) + { + // Multi-layer pointer + sum += psiPtr[lPtr[cell]]; + psiPtr[uPtr[cell]] = sum; + + // Outer pointer, inner array + sum += psiPtr[b[cell]]; + psiPtr[a[cell]] = sum; + + // Multi-layer array + sum += a[b[cell]]; + c[a[cell]] = sum; + + // Outer array, inner pointer + sum += a[lPtr[cell]]; + c[lPtr[cell]] = sum; + } + return sum; +} + +int +main (int argc, char *argv[]) +{ + int testIter = 2; + + double *psiPtr = NULL; + int *lPtr = NULL; + int *uPtr = NULL; + psiPtr = (double *) calloc (N, sizeof(double)); + lPtr = (int *) calloc (N, sizeof(int)); + uPtr = (int *) calloc (N, sizeof(int)); + + for (int i = 0; i < testIter; i++) + referenceTrace (psiPtr, lPtr, uPtr, N); + + free (psiPtr); + free (lPtr); + free (uPtr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "Tracing succeeded" 24 "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-not "Tracing failed" "llc_allocate" } } */ +/* { dg-final { scan-tree-dump-times "unhandled issue scene" 2 "llc_allocate" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-same-loop-cycle.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-same-loop-cycle.c new file mode 100644 index 0000000000000000000000000000000000000000..551bc9897eefff3fddcbfe09c261ce87e1a029b9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/llc-allocate/llc-same-loop-cycle.c @@ -0,0 +1,125 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param filter-kernels=1 --param=branch-prob-threshold=50 -c -w --param=filter-mode=0" } */ + +typedef unsigned long size_t; +typedef long scalar_t__; + +typedef struct TYPE_13__ TYPE_3__ ; +typedef struct TYPE_12__ TYPE_2__ ; +typedef struct TYPE_11__ TYPE_1__ ; + +struct dom_info {int nodes; int* dfs_parent; int* dfs_order; int* key; int* next_bucket; int* bucket; int* dom; int fake_exit_edge; TYPE_3__** dfs_to_bb; } ; +typedef enum cdi_direction { ____Placeholder_cdi_direction } cdi_direction ; +struct TYPE_11__ {scalar_t__ index; } ; +typedef TYPE_1__ edge_iterator ; +typedef TYPE_2__* edge ; +typedef TYPE_3__* basic_block ; +struct TYPE_13__ {size_t index; int preds; int succs; } ; +struct TYPE_12__ {TYPE_3__* src; TYPE_3__* dest; } ; +typedef int TBB ; + +basic_block ENTRY_BLOCK_PTR ; +basic_block EXIT_BLOCK_PTR ; +scalar_t__ bitmap_bit_p (int,size_t) ; +edge ei_edge (edge_iterator) ; +int ei_end_p (edge_iterator) ; +int ei_next (edge_iterator*) ; +edge_iterator ei_start (int) ; +size_t eval (struct dom_info*,int) ; +size_t last_basic_block ; +int link_roots (struct dom_info*,int,int) ; + +__attribute__((used)) static void +calc_idoms (struct dom_info *di, enum cdi_direction reverse) +{ + TBB v, w, k, par; + basic_block en_block; + edge_iterator ei, einext; + + if (reverse) + en_block = EXIT_BLOCK_PTR; + else + en_block = ENTRY_BLOCK_PTR; + + /* Go backwards in DFS order, to first look at the leafs. */ + v = di->nodes; + while (v > 1) + { + basic_block bb = di->dfs_to_bb[v]; + edge e; + + par = di->dfs_parent[v]; + k = v; + + ei = (reverse) ? ei_start (bb->succs) : ei_start (bb->preds); + + if (reverse) + { + /* If this block has a fake edge to exit, process that first. */ + if (bitmap_bit_p (di->fake_exit_edge, bb->index)) + { + einext = ei; + einext.index = 0; + goto do_fake_exit_edge; + } + } + + /* Search all direct predecessors for the smallest node with a path + to them. That way we have the smallest node with also a path to + us only over nodes behind us. In effect we search for our + semidominator. */ + while (!ei_end_p (ei)) + { + basic_block b; + TBB k1; + + e = ei_edge (ei); + b = (reverse) ? e->dest : e->src; + einext = ei; + ei_next (&einext); + + if (b == en_block) + { + do_fake_exit_edge: + k1 = di->dfs_order[last_basic_block]; + } + else + k1 = di->dfs_order[b->index]; + + /* Call eval() only if really needed. If k1 is above V in DFS tree, + then we know, that eval(k1) == k1 and key[k1] == k1. */ + if (k1 > v) + k1 = di->key[eval (di, k1)]; + if (k1 < k) + k = k1; + + ei = einext; + } + + di->key[v] = k; + link_roots (di, par, v); + di->next_bucket[v] = di->bucket[k]; + di->bucket[k] = v; + + /* Transform semidominators into dominators. */ + for (w = di->bucket[par]; w; w = di->next_bucket[w]) + { + k = eval (di, w); + if (di->key[k] < di->key[w]) + di->dom[w] = k; + else + di->dom[w] = par; + } + /* We don't need to cleanup next_bucket[]. */ + di->bucket[par] = 0; + v--; + } + + /* Explicitly define the dominators. */ + di->dom[1] = 0; + for (v = 2; v <= di->nodes; v++) + if (di->dom[v] != di->key[v]) + di->dom[v] = di->dom[di->dom[v]]; +} + +/* { dg-final { scan-tree-dump "Find same-loop cycle." "llc_allocate" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr107190.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr107190.c new file mode 100644 index 0000000000000000000000000000000000000000..d4e5fa0d0f51d04e88f5720320572a1990a1abf2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr107190.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-fold-phiopt -fmerge-mull -fexpensive-optimizations -fdump-tree-phiopt2-details" } */ + +# define BN_BITS4 32 +# define BN_MASK2 (0xffffffffffffffffL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000L) +# define BN_MASK2h1 (0xffffffff80000000L) +# define LBITS(a) ((a)&BN_MASK2l) +# define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l) +# define L2HBITS(a) (((a)<|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[45]" 14 "optimized" } } */ + +#define A __attribute__((noipa)) +A int f1 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == 0; } +A int f2 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != 0; } +A int f3 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c > 0; } +A int f4 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c < 0; } +A int f5 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c >= 0; } +A int f6 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c <= 0; } +A int f7 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == -1; } +A int f8 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != -1; } +A int f9 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c > -1; } +A int f10 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c <= -1; } +A int f11 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c == 1; } +A int f12 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c != 1; } +A int f13 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c < 1; } +A int f14 (int i, int j) { int c = i == j ? 0 : i < j ? -1 : 1; return c >= 1; } +A int f15 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == 0; } +A int f16 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != 0; } +A int f17 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c > 0; } +A int f18 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c < 0; } +A int f19 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c >= 0; } +A int f20 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c <= 0; } +A int f21 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == -1; } +A int f22 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != -1; } +A int f23 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c > -1; } +A int f24 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c <= -1; } +A int f25 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c == 1; } +A int f26 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c != 1; } +A int f27 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c < 1; } +A int f28 (int i) { int c = i == 5 ? 0 : i < 5 ? -1 : 1; return c >= 1; } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-2.c new file mode 100644 index 0000000000000000000000000000000000000000..9481b764dabf749aec7edf20ddb0938d23e26dcf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-2.c @@ -0,0 +1,35 @@ +/* PR tree-optimization/94589 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 5\\.0" 14 "optimized" } } */ + +#define A __attribute__((noipa)) +A int f1 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c == 0; } +A int f2 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c != 0; } +A int f3 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c > 0; } +A int f4 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c < 0; } +A int f5 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c >= 0; } +A int f6 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c <= 0; } +A int f7 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c == -1; } +A int f8 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c != -1; } +A int f9 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c > -1; } +A int f10 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c <= -1; } +A int f11 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c == 1; } +A int f12 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c != 1; } +A int f13 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c < 1; } +A int f14 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c = 1; else c = 2; return c >= 1; } +A int f15 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c == 0; } +A int f16 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c != 0; } +A int f17 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c > 0; } +A int f18 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c < 0; } +A int f19 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c >= 0; } +A int f20 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c <= 0; } +A int f21 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c == -1; } +A int f22 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c != -1; } +A int f23 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c > -1; } +A int f24 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c <= -1; } +A int f25 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c == 1; } +A int f26 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c != 1; } +A int f27 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c < 1; } +A int f28 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; else if (i > 5.0) c = 1; else c = 2; return c >= 1; } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-3.c new file mode 100644 index 0000000000000000000000000000000000000000..df82fab7334be0b2be5b086bf29cd0325baf5e39 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-3.c @@ -0,0 +1,97 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -g" } */ + +#include "pr94589-1.c" + +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () + +int +main () +{ + C (f1, 7, 8, 0); + C (f1, 8, 8, 1); + C (f1, 9, 8, 0); + C (f2, 7, 8, 1); + C (f2, 8, 8, 0); + C (f2, 9, 8, 1); + C (f3, 7, 8, 0); + C (f3, 8, 8, 0); + C (f3, 9, 8, 1); + C (f4, 7, 8, 1); + C (f4, 8, 8, 0); + C (f4, 9, 8, 0); + C (f5, 7, 8, 0); + C (f5, 8, 8, 1); + C (f5, 9, 8, 1); + C (f6, 7, 8, 1); + C (f6, 8, 8, 1); + C (f6, 9, 8, 0); + C (f7, 7, 8, 1); + C (f7, 8, 8, 0); + C (f7, 9, 8, 0); + C (f8, 7, 8, 0); + C (f8, 8, 8, 1); + C (f8, 9, 8, 1); + C (f9, 7, 8, 0); + C (f9, 8, 8, 1); + C (f9, 9, 8, 1); + C (f10, 7, 8, 1); + C (f10, 8, 8, 0); + C (f10, 9, 8, 0); + C (f11, 7, 8, 0); + C (f11, 8, 8, 0); + C (f11, 9, 8, 1); + C (f12, 7, 8, 1); + C (f12, 8, 8, 1); + C (f12, 9, 8, 0); + C (f13, 7, 8, 1); + C (f13, 8, 8, 1); + C (f13, 9, 8, 0); + C (f14, 7, 8, 0); + C (f14, 8, 8, 0); + C (f14, 9, 8, 1); + D (f15, 4, 0); + D (f15, 5, 1); + D (f15, 6, 0); + D (f16, 4, 1); + D (f16, 5, 0); + D (f16, 6, 1); + D (f17, 4, 0); + D (f17, 5, 0); + D (f17, 6, 1); + D (f18, 4, 1); + D (f18, 5, 0); + D (f18, 6, 0); + D (f19, 4, 0); + D (f19, 5, 1); + D (f19, 6, 1); + D (f20, 4, 1); + D (f20, 5, 1); + D (f20, 6, 0); + D (f21, 4, 1); + D (f21, 5, 0); + D (f21, 6, 0); + D (f22, 4, 0); + D (f22, 5, 1); + D (f22, 6, 1); + D (f23, 4, 0); + D (f23, 5, 1); + D (f23, 6, 1); + D (f24, 4, 1); + D (f24, 5, 0); + D (f24, 6, 0); + D (f25, 4, 0); + D (f25, 5, 0); + D (f25, 6, 1); + D (f26, 4, 1); + D (f26, 5, 1); + D (f26, 6, 0); + D (f27, 4, 1); + D (f27, 5, 1); + D (f27, 6, 0); + D (f28, 4, 0); + D (f28, 5, 0); + D (f28, 6, 1); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-4.c new file mode 100644 index 0000000000000000000000000000000000000000..b2557fb07b0f48b4c31839969a3554c4ed7dcd5f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94589-4.c @@ -0,0 +1,97 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -g -ffast-math" } */ + +#include "pr94589-2.c" + +#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort () +#define D(fn, i, r) if (fn (i) != r) __builtin_abort () + +int +main () +{ + C (f1, 7.0, 8.0, 0); + C (f1, 8.0, 8.0, 1); + C (f1, 9.0, 8.0, 0); + C (f2, 7.0, 8.0, 1); + C (f2, 8.0, 8.0, 0); + C (f2, 9.0, 8.0, 1); + C (f3, 7.0, 8.0, 0); + C (f3, 8.0, 8.0, 0); + C (f3, 9.0, 8.0, 1); + C (f4, 7.0, 8.0, 1); + C (f4, 8.0, 8.0, 0); + C (f4, 9.0, 8.0, 0); + C (f5, 7.0, 8.0, 0); + C (f5, 8.0, 8.0, 1); + C (f5, 9.0, 8.0, 1); + C (f6, 7.0, 8.0, 1); + C (f6, 8.0, 8.0, 1); + C (f6, 9.0, 8.0, 0); + C (f7, 7.0, 8.0, 1); + C (f7, 8.0, 8.0, 0); + C (f7, 9.0, 8.0, 0); + C (f8, 7.0, 8.0, 0); + C (f8, 8.0, 8.0, 1); + C (f8, 9.0, 8.0, 1); + C (f9, 7.0, 8.0, 0); + C (f9, 8.0, 8.0, 1); + C (f9, 9.0, 8.0, 1); + C (f10, 7.0, 8.0, 1); + C (f10, 8.0, 8.0, 0); + C (f10, 9.0, 8.0, 0); + C (f11, 7.0, 8.0, 0); + C (f11, 8.0, 8.0, 0); + C (f11, 9.0, 8.0, 1); + C (f12, 7.0, 8.0, 1); + C (f12, 8.0, 8.0, 1); + C (f12, 9.0, 8.0, 0); + C (f13, 7.0, 8.0, 1); + C (f13, 8.0, 8.0, 1); + C (f13, 9.0, 8.0, 0); + C (f14, 7.0, 8.0, 0); + C (f14, 8.0, 8.0, 0); + C (f14, 9.0, 8.0, 1); + D (f15, 4.0, 0); + D (f15, 5.0, 1); + D (f15, 6.0, 0); + D (f16, 4.0, 1); + D (f16, 5.0, 0); + D (f16, 6.0, 1); + D (f17, 4.0, 0); + D (f17, 5.0, 0); + D (f17, 6.0, 1); + D (f18, 4.0, 1); + D (f18, 5.0, 0); + D (f18, 6.0, 0); + D (f19, 4.0, 0); + D (f19, 5.0, 1); + D (f19, 6.0, 1); + D (f20, 4.0, 1); + D (f20, 5.0, 1); + D (f20, 6.0, 0); + D (f21, 4.0, 1); + D (f21, 5.0, 0); + D (f21, 6.0, 0); + D (f22, 4.0, 0); + D (f22, 5.0, 1); + D (f22, 6.0, 1); + D (f23, 4.0, 0); + D (f23, 5.0, 1); + D (f23, 6.0, 1); + D (f24, 4.0, 1); + D (f24, 5.0, 0); + D (f24, 6.0, 0); + D (f25, 4.0, 0); + D (f25, 5.0, 0); + D (f25, 6.0, 1); + D (f26, 4.0, 1); + D (f26, 5.0, 1); + D (f26, 6.0, 0); + D (f27, 4.0, 1); + D (f27, 5.0, 1); + D (f27, 6.0, 0); + D (f28, 4.0, 0); + D (f28, 5.0, 0); + D (f28, 6.0, 1); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94963.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94963.c new file mode 100644 index 0000000000000000000000000000000000000000..09c0524fb3aaf59b7df3fee40a98cbf91e56bc0d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr94963.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +typedef struct +{ + int p1; + int p2; + int p3; +} P; +struct S +{ + int field; +}; +extern int v2; +extern void foo (struct S *map); +static struct S var; +const P *pv; +int ps; +void +f (void) +{ + if (pv != 0) + for (const P *ph = pv; ph < &pv[ps]; ++ph) + switch (ph->p1) + { + case 1: + v2 = ph->p2; + break; + case 2: + var.field = ph->p3; + break; + } + if (var.field != 0) /* { dg-bogus "uninitialized" } */ + foo (&var); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr97238.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr97238.c new file mode 100644 index 0000000000000000000000000000000000000000..746e93a9750233a5295ebe62d3f4709cbd19134c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/pr97238.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wno-psabi -w" } */ + +typedef int __attribute__ ((__vector_size__ (8))) V; +int b, c, e; +V d; + +V +foo (void) +{ + return (b || e) | c > d | ((b || e) | c > d); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-dont-split.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-dont-split.c new file mode 100644 index 0000000000000000000000000000000000000000..2d42231dcd9cb1ab095c9485ff3b66f7f38889c2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-dont-split.c @@ -0,0 +1,93 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-additional-options "-O1 -fsplit-ldp-stp" } */ +/* + * Tests are: + * Patterns where LDP insns should NOT be split + * */ + +int __RTL (startwith ("split_complex_instructions")) +simple_ldp_after_store () +{ +(function "simple_ldp_after_store" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cinsn 228 (set (reg/i:DI sp) + (reg/i:DI x0))) + (cinsn 238 (set (reg/i:DI x1) + (reg/i:DI x0))) + + (cinsn 101 (set (mem/c:DI + (plus:DI (reg/f:DI sp) + (const_int 32))[1 S4 A32])(reg:DI x0))) + (cinsn 10 (parallel [ + (set (reg:DI x29) + (mem:DI (plus:DI (reg/f:DI sp) (const_int 8)) [1 S4 A32])) + (set (reg:DI x30) + (mem:DI (plus:DI (reg/f:DI sp) + (const_int 16)) [1 S4 A32]))])) + (cinsn 11 (use (reg/i:DI x29))) + (cinsn 12 (use (reg/i:DI x30))) + + /* stp x0, x2, [x1]. */ + (cinsn 102 (parallel [ + (set (mem:DI (reg/f:DI x1) [1 S4 A32]) + (reg:DI x0)) + (set (mem:DI (plus:DI (reg/f:DI x1) (const_int 8)) [1 S4 A32]) + (reg:DI x2))])) + /* ldp x5, x6, [x1]. */ + (cinsn 13 (parallel [ + (set (reg:DI x5) (mem:DI (reg/f:DI x1) [1 S4 A32])) + (set (reg:DI x6) (mem:DI (plus:DI (reg/f:DI x1) + (const_int 8)) [1 S4 A32])) + ])) + (cinsn 14 (use (reg/i:DI x5))) + (cinsn 15 (use (reg/i:DI x6))) + + (cinsn 100 (use (reg/i:DI sp))) + (cinsn 200 (use (reg/i:DI cc))) + (cinsn 300 (use (reg/i:DI x0))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain +) ;; function "simple_ldp_after_store" +} + +int __RTL (startwith ("split_complex_instructions")) +ldp_after_store_in_different_bb () +{ +(function "ldp_after_store_in_different_bb" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cinsn 228 (set (reg/i:DI sp) + (reg/i:DI x0))) + (cinsn 101 (set (mem/c:DI + (plus:DI (reg/f:DI sp) + (const_int 32))[1 S4 A32])(reg:DI x0))) + (edge-to 3 (flags "FALLTHRU")) + ) ;; block 2 + (block 3 + (edge-from 2 (flags "FALLTHRU")) + (cnote 4 [bb 3] NOTE_INSN_BASIC_BLOCK) + (cinsn 10 (parallel [ + (set (reg:DI x29) + (mem:DI (plus:DI (reg/f:DI sp) (const_int 8)) [1 S4 A32])) + (set (reg:DI x30) + (mem:DI (plus:DI (reg/f:DI sp) + (const_int 16)) [1 S4 A32]))])) + (cinsn 11 (use (reg/i:DI sp))) + (cinsn 12 (use (reg/i:DI cc))) + (cinsn 13 (use (reg/i:DI x29))) + (cinsn 14 (use (reg/i:DI x30))) + (cinsn 15 (use (reg/i:DI x0))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 3 + ) ;; insn-chain +) ;; function "ldp_after_store_in_different_bb" +} + +/* Verify that the output code contains exactly 3 ldp. */ +/* { dg-final { scan-assembler-times {ldp\t} 3 } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-split-rearrange.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-split-rearrange.c new file mode 100644 index 0000000000000000000000000000000000000000..b9d74518523ce76413540df4870d780768dcad76 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-split-rearrange.c @@ -0,0 +1,40 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-additional-options "-O1 -fsplit-ldp-stp" } */ +/* + * Test is: + * Pattern where LDP insns should be split with rearrangement in order + * to deal with data dependecy betwen subinstruction. + * */ + +int __RTL (startwith ("split_complex_instructions")) +simple_ldp_after_store () +{ +(function "ldp_equal_registers" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cinsn 228 (set (reg/i:DI x1) + (reg/i:DI x0))) + (cinsn 101 (set (mem/c:DI + (plus:DI (reg/f:DI x1) + (const_int 8))[1 S4 A32])(reg:DI x0))) + (cinsn 10 (parallel [ + (set (reg:DI x1) + (mem:DI (plus:DI (reg/f:DI x1) (const_int 8)) [1 S4 A32])) + (set (reg:DI x2) + (mem:DI (plus:DI (reg/f:DI x1) + (const_int 16)) [1 S4 A32]))])) + (cinsn 11 (use (reg/i:DI sp))) + (cinsn 12 (use (reg/i:DI cc))) + (cinsn 13 (use (reg/i:DI x0))) + (cinsn 14 (use (reg/i:DI x1))) + (cinsn 15 (use (reg/i:DI x2))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain +) ;; function "ldp_equal_registers" +} + +/* Verify that the output code doesn't contain ldp. */ +/* { dg-final { scan-assembler-times ".*ldr.*x2.*x1,.*16.*ldr.*x1.*x1.*8" 1 } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-split.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-split.c new file mode 100644 index 0000000000000000000000000000000000000000..0b280022f64d7f6724ba422161c050d8b40b15b9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/rtl/aarch64/test-ldp-split.c @@ -0,0 +1,297 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-additional-options "-O1 -fsplit-ldp-stp" } */ +/* + * Tests are: + * Patterns where LDP insns should be split + * */ + +int __RTL (startwith ("split_complex_instructions")) +simple_ldp_after_store () +{ +(function "simple_ldp_after_store" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) + /* mov sp, x0. */ + (cinsn 228 (set (reg/i:DI sp) + (reg/i:DI x0))) + /* mov x1, x0. */ + (cinsn 238 (set (reg/i:DI x1) + (reg/i:DI x0))) + + /* str x0, [sp, 8]. */ + (cinsn 101 (set (mem/c:DI + (plus:DI (reg/f:DI sp) + (const_int 8))[1 S4 A32])(reg:DI x0))) + /* ldp x29, x30, [sp, 8]. */ + (cinsn 10 (parallel [ + (set (reg:DI x29) + (mem:DI (plus:DI (reg/f:DI sp) (const_int 8)) [1 S4 A32])) + (set (reg:DI x30) + (mem:DI (plus:DI (reg/f:DI sp) + (const_int 16)) [1 S4 A32]))])) + (cinsn 11 (use (reg/i:DI x29))) + (cinsn 12 (use (reg/i:DI x30))) + + /* str x0, [x1, -16]. */ + (cinsn 102 (set (mem/c:DI (plus:DI (reg/f:DI x1) + (const_int -16)) [1 S4 A32]) + (reg:DI x0))) + /* ldp x3, x4, [x1, -16]. */ + (cinsn 13 (parallel [ + (set (reg:DI x3) + (mem:DI (plus:DI (reg/f:DI x1) (const_int -16)) [1 S4 A32])) + (set (reg:DI x4) + (mem:DI (plus:DI (reg/f:DI x1) (const_int -8)) [1 S4 A32])) + ])) + (cinsn 14 (use (reg/i:DI x3))) + (cinsn 15 (use (reg/i:DI x4))) + + /* str x0, [x1]. */ + (cinsn 103 (set (mem/c:DI (reg/f:DI x1) [1 S4 A32]) + (reg:DI x0))) + /* ldp x5, x6, [x1]. */ + (cinsn 16 (parallel [ + (set (reg:DI x5) (mem:DI (reg/f:DI x1) [1 S4 A32])) + (set (reg:DI x6) (mem:DI (plus:DI (reg/f:DI x1) + (const_int 8)) [1 S4 A32])) + ])) + (cinsn 17 (use (reg/i:DI x5))) + (cinsn 18 (use (reg/i:DI x6))) + + /* ldp x29, x30, [sp], 96. */ + (cinsn 19 (parallel [ + (set (reg/f:DI sp) + (plus:DI (reg/f:DI sp) (const_int 96))) + (set (reg:DI x29) + (mem:DI (reg/f:DI sp) [1 S4 A32])) + (set (reg:DI x30) + (mem:DI (plus:DI (reg/f:DI sp) + (const_int 8)) [1 S4 A32]))])) + (cinsn 20 (use (reg/i:DI x29))) + (cinsn 21 (use (reg/i:DI x30))) + + /* stp x0, x2, [x1, 128]. */ + (cinsn 104 (parallel [ + (set (mem:DI (plus:DI (reg/f:DI x1) (const_int 128)) [1 S4 A32]) + (reg:DI x0)) + (set (mem:DI (plus:DI (reg/f:DI x1) (const_int 136)) [1 S4 A32]) + (reg:DI x2))])) + /* ldp x29, x30, [x1, 120]. */ + (cinsn 22 (parallel [ + (set (reg:DI x29) + (mem:DI (plus:DI (reg/f:DI x1) (const_int 120)) [1 S4 A32])) + (set (reg:DI x30) + (mem:DI (plus:DI (reg/f:DI x1) (const_int 128)) [1 S4 A32]))])) + (cinsn 23 (use (reg/i:DI x29))) + (cinsn 24 (use (reg/i:DI x30))) + + /* stp x0, x2, [x1, 128]. */ + (cinsn 105 (parallel [ + (set (mem:DI (plus:DI (reg/f:DI x1) (const_int 128)) [1 S4 A32]) + (reg:DI x0)) + (set (mem:DI (plus:DI (reg/f:DI x1) (const_int 136)) [1 S4 A32]) + (reg:DI x2))])) + /* ldp x3, x4, [x1, 136]. */ + (cinsn 25 (parallel [ + (set (reg:DI x3) + (mem:DI (plus:DI (reg/f:DI x1) (const_int 136)) [1 S4 A32])) + (set (reg:DI x4) + (mem:DI (plus:DI (reg/f:DI x1) (const_int 144)) [1 S4 A32])) + ])) + (cinsn 26 (use (reg/i:DI x3))) + (cinsn 27 (use (reg/i:DI x4))) + + /* stp w0, w2, [x1, 32]. */ + (cinsn 106 (parallel [ + (set (mem:SI (plus:DI (reg/f:DI x1) (const_int 32)) [1 S4 A32]) + (reg:SI x0)) + (set (mem:SI (plus:DI (reg/f:DI x1) (const_int 36)) [1 S4 A32]) + (reg:SI x2))])) + /* ldp x5, x6, [x1, 32]. */ + (cinsn 28 (parallel [ + (set (reg:DI x5) (mem:DI (plus:DI (reg/f:DI x1) + (const_int 32)) [1 S4 A32])) + (set (reg:DI x6) (mem:DI (plus:DI (reg/f:DI x1) + (const_int 40)) [1 S4 A32])) + ])) + (cinsn 29 (use (reg/i:DI x5))) + (cinsn 30 (use (reg/i:DI x6))) + + /* stp w0, w2, [x1, 40]. */ + (cinsn 107 (parallel [ + (set (mem:SI (plus:DI (reg/f:DI x1) (const_int 40)) [1 S4 A32]) + (reg:SI x0)) + (set (mem:SI (plus:DI (reg/f:DI x1) (const_int 44)) [1 S4 A32]) + (reg:SI x2))])) + /* ldp x5, x6, [x1, 32]. */ + (cinsn 31 (parallel [ + (set (reg:DI x5) (mem:DI (plus:DI (reg/f:DI x1) + (const_int 32)) [1 S4 A32])) + (set (reg:DI x6) (mem:DI (plus:DI (reg/f:DI x1) + (const_int 40)) [1 S4 A32])) + ])) + (cinsn 32 (use (reg/i:DI x5))) + (cinsn 33 (use (reg/i:DI x6))) + + (cinsn 100 (use (reg/i:DI sp))) + (cinsn 200 (use (reg/i:DI cc))) + (cinsn 400 (use (reg/i:DI x0))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain +) ;; function "simple_ldp_after_store" +} + +int __RTL (startwith ("split_complex_instructions")) +ldp_ti_after_store () +{ + (function "ldp_ti_after_store" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) + /* mov sp, x0. */ + (cinsn 228 (set (reg/i:DI sp) + (reg/i:DI x0))) + /* mov x2, x0. */ + (cinsn 238 (set (reg/i:DI x2) + (reg/i:DI x0))) + /* str x0, [sp, 136]. */ + (cinsn 101 (set (mem/c:DI + (plus:DI (reg/f:DI sp) + (const_int 136))[1 S4 A32])(reg:DI x0))) + /* ldp x0, x1, [sp, 136]. */ + (cinsn 81 (set (reg:TI x0 [1 S4 A32]) + (mem/c:TI (plus:DI (reg/f:DI sp) + (const_int 136)) [1 S4 A32]))) + /* str x0, [x2, -16]. */ + (cinsn 102 (set (mem/c:DI (plus:DI (reg/f:DI x2) + (const_int -16)) [1 S4 A32]) + (reg:DI x0))) + /* ldp x3, x4, [x2, -16]. */ + (cinsn 82 (set (reg:TI x3 [1 S4 A32]) + (mem/c:TI (plus:DI (reg/f:DI x2) + (const_int -16)) [1 S4 A32]))) + /* str x0, [x2]. */ + (cinsn 103 (set (mem/c:DI (reg/f:DI x2) [1 S4 A32]) + (reg:DI x0))) + /* ldp x5, x6, [x2]. */ + (cinsn 83 (set (reg:TI x5 [1 S4 A32]) + (mem/c:TI (reg/f:DI x2) [1 S4 A32]))) + + /* stp x0, x1, [sp, -8]. */ + (cinsn 104 (set (mem:TI (plus:DI (reg/v/f:DI sp) + (const_int -8)) [1 S4 A32]) + (reg:TI x0))) + /* ldp x5, x6, [sp], -16. */ + (cinsn 84 (set (reg/v:TI x5 [1 S4 A32]) + (mem:TI (post_dec:DI (reg/v/f:DI sp)) [1 S4 A32]))) + (cinsn 85 (use (reg/i:DI x5))) + (cinsn 86 (use (reg/i:DI x6))) + + /* stp x0, x1, [sp, 8]. */ + (cinsn 105 (set (mem:TI (plus:DI (reg/v/f:DI sp) + (const_int 8)) [1 S4 A32]) + (reg:TI x0))) + /* ldp x5, x6, [sp], -16. */ + (cinsn 87 (set (reg/v:TI x5 [1 S4 A32]) + (mem:TI (post_dec:DI (reg/v/f:DI sp)) [1 S4 A32]))) + (cinsn 88 (use (reg/i:DI x5))) + (cinsn 89 (use (reg/i:DI x6))) + + /* Intersects with insn 102. */ + /* ldp x2, x3, [x2, -16]!. */ + (cinsn 90 (set (reg/v:TI x2 [1 S4 A32]) + (mem:TI (pre_dec:DI (reg/v/f:DI x2)) [1 S4 A32]))) + (cinsn 91 (use (reg/i:DI x2))) + (cinsn 92 (use (reg/i:DI x3))) + + /* mov x2, x0. */ + (cinsn 248 (set (reg/i:DI x2) + (reg/i:DI x0))) + /* str x0, [x2, 16]. */ + (cinsn 106 (set (mem:DI (plus:DI (reg/v/f:DI x2) + (const_int 16)) [1 S4 A32]) + (reg:DI x0))) + /* ldp x3, x4, [x2, 16]!. */ + (cinsn 93 (set (reg/v:TI x3 [1 S4 A32]) + (mem:TI (pre_inc:DI (reg/v/f:DI x2)) [1 S4 A32]))) + (cinsn 94 (use (reg/i:DI x3))) + (cinsn 95 (use (reg/i:DI x4))) + + (cinsn 11 (use (reg/i:DI sp))) + (cinsn 12 (use (reg/i:DI cc))) + (cinsn 13 (use (reg/i:DI x29))) + (cinsn 14 (use (reg/i:DI x30))) + (cinsn 15 (use (reg/i:DI x0))) + (cinsn 16 (use (reg/i:DI x3))) + (cinsn 18 (use (reg/i:DI x1))) + (cinsn 19 (use (reg/i:DI x4))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain +) ;; function "ldp_ti_after_store" +} + +int __RTL (startwith ("split_complex_instructions")) +ldp_after_store_in_different_bb () +{ +(function "ldp_after_store_in_different_bb" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cinsn 228 (set (reg/i:DI sp) + (reg/i:DI x0))) + (cinsn 238 (set (reg/i:DI x1) + (reg/i:DI x0))) + + (cinsn 101 (set (mem/c:DI + (plus:DI (reg/f:DI sp) + (const_int 8))[1 S4 A32])(reg:DI x0))) + (cinsn 102 (set (mem/c:DI (plus:DI (reg/f:DI x1) + (const_int -16)) [1 S4 A32]) + (reg:DI x0))) + (cinsn 103 (set (mem/c:DI (reg/f:DI x1) [1 S4 A32]) + (reg:DI x0))) + (edge-to 3 (flags "FALLTHRU")) + ) ;; block 2 + (block 3 + (edge-from 2 (flags "FALLTHRU")) + (cnote 4 [bb 3] NOTE_INSN_BASIC_BLOCK) + (cinsn 10 (parallel [ + (set (reg:DI x29) + (mem:DI (plus:DI (reg/f:DI sp) (const_int 8)) [1 S4 A32])) + (set (reg:DI x30) + (mem:DI (plus:DI (reg/f:DI sp) + (const_int 16)) [1 S4 A32]))])) + (cinsn 11 (parallel [ + (set (reg:DI x3) + (mem:DI (plus:DI (reg/f:DI x1) (const_int -16)) [1 S4 A32])) + (set (reg:DI x4) + (mem:DI (plus:DI (reg/f:DI x1) (const_int -8)) [1 S4 A32])) + ])) + (cinsn 12 (parallel [ + (set (reg:DI x5) (mem:DI (reg/f:DI x1) [1 S4 A32])) + (set (reg:DI x6) (mem:DI (plus:DI (reg/f:DI x1) + (const_int 8)) [1 S4 A32])) + ])) + (cinsn 13 (use (reg/i:DI sp))) + (cinsn 14 (use (reg/i:DI cc))) + (cinsn 15 (use (reg/i:DI x29))) + (cinsn 16 (use (reg/i:DI x30))) + (cinsn 17 (use (reg/i:DI x0))) + (cinsn 18 (use (reg/i:DI x3))) + (cinsn 19 (use (reg/i:DI x4))) + (cinsn 20 (use (reg/i:DI x5))) + (cinsn 21 (use (reg/i:DI x6))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 3 + ) ;; insn-chain +) ;; function "ldp_after_store_in_different_bb" +} + +/* Verify that the output code doesn't contain ldp. */ +/* { dg-final { scan-assembler-not {ldp\t} } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/complete_struct_relayout.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/complete_struct_relayout.c new file mode 100644 index 0000000000000000000000000000000000000000..811030bf167fbdc6d886c11eb12a6bc44c00ade7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/complete_struct_relayout.c @@ -0,0 +1,60 @@ +// { dg-do run } + +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10000; +node_p n; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + + for (int i = 0; i < MAX; i++) + { + n[i].l = n[i].a; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].l != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in Complete Structure Relayout is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-1.c new file mode 100644 index 0000000000000000000000000000000000000000..63bb695ae14a30c8c938f35df304fa6f304de74b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-1.c @@ -0,0 +1,46 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 1; +node_p n; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-2.c new file mode 100644 index 0000000000000000000000000000000000000000..0f75d5d121cf057d8f898e5a037cdca6d1b7a0ef --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-2.c @@ -0,0 +1,59 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10; +node_p n; +node_p m; + +int main() +{ + int i; + for (i = 0; i < MAX / 5; i++) + { + n = (node_p) calloc(MAX, sizeof(node_t)); + if (i == 0) + { + m = n; + } + } + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + m[i].a = 50; + } + + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-3.c new file mode 100644 index 0000000000000000000000000000000000000000..3dcb674c6e9a610734be8b3d351dfd2a6701809f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_allocation-3.c @@ -0,0 +1,77 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10; +node_p n; +node_p m; + +void test (int, int) __attribute__((noinline)); + +void +test (int num, int flag) +{ + if (num <= 0) + { + return; + } + n = (node_p) calloc (num, sizeof (node_t)); + if (flag) + { + m = n; + } + return; +} + +int +main () +{ + test (MAX, 1); + test (MAX, 0); + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + m[i].a = 50; + } + + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + for (int i = 0; i < MAX; i++) + { + if (m[i].a != 50) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_cast_int.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_cast_int.c new file mode 100644 index 0000000000000000000000000000000000000000..6907158c9b0dc6d3d251b29dcda3bda946a779e9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_cast_int.c @@ -0,0 +1,52 @@ +// { dg-do run } + +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 100; +node_p n; +unsigned long y; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + + for (int i = 0; i < MAX; i++) + { + n[i].b = 50; + } + + node_p x = &n[5]; + y = (unsigned long) x; + y += 8; + + if (*((unsigned long*) y) != 50) + { + abort (); + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "struct node has escaped: \"Type escapes a cast from/to intergral type\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_separate_instance.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_separate_instance.c new file mode 100644 index 0000000000000000000000000000000000000000..9e5e05838e64436500aed343354ed59496ec3ae5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_separate_instance.c @@ -0,0 +1,48 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10000; +node_p n; +node_t t; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + t.a = 100; + + for (int i = 0; i < MAX; i++) + { + n[i].a = t.a; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "struct node has escaped: \"Type escapes via a separate instance\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_skip_void_struct_name.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_skip_void_struct_name.c new file mode 100644 index 0000000000000000000000000000000000000000..c5e4968d91436e51304390c5ab519b6d5ba9e01d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/csr_skip_void_struct_name.c @@ -0,0 +1,53 @@ +// Structures without names should not be optimized +/* { dg-do compile } */ +#include +#include + +typedef struct +{ + int a; + float b; + double s1; + double s2; + double s3; + double s4; + double s5; + double s6; + double s7; + double s8; +} str_t1; + +#define N 1000 + +int num; + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + str_t1 *p1 = calloc (num, sizeof (str_t1)); + + if (p1 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + for (i = 0; i < num; i++) + p1[i].b = 2; + + for (i = 0; i < num; i++) + if (p1[i].a != 1) + abort (); + + for (i = 0; i < num; i++) + if (fabsf (p1[i].b - 2) > 0.0001) + abort (); + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_DTE_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_DTE_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..10b5be86d3cf3a759b5a99fdc0ef7df712f62ac1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_DTE_verify.c @@ -0,0 +1,86 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; +arc_p stop_arcs = NULL; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + net[0]->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + net[0]->arcs->id = 100; + + for (unsigned i = 0; i < 3; i++) + { + net[0]->arcs->id = net[0]->arcs->id + 2; + stop_arcs->cost = net[0]->arcs->id / 2; + stop_arcs->net_add = net[0]; + printf("stop_arcs->cost = %ld\n", stop_arcs->cost); + net[0]->arcs++; + stop_arcs++; + } + + if( net[1] != 0 && stop_arcs != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ele_minus_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ele_minus_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..5ecfa9fe1339a1ba8c3c1418c8337eef29c66fbe --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ele_minus_verify.c @@ -0,0 +1,60 @@ +// verify newarc[cmp-1].flow +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p ap = NULL; + +int +main () +{ + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[0].id); + for (int i = 1; i < MAX; i++) + { + ap[i-1].id = 500; + } + printf("%d\n", ap[0].id); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_escape.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_escape.c new file mode 100644 index 0000000000000000000000000000000000000000..09efe8027165317540e03fa3d8eea9f09f08b9c1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_escape.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + int x; +} network_t; + +struct arc +{ + int flow; + network_t* net_add; +}; + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; +arc_p stop_arcs = NULL; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + net[0]->x = 100; + + for (unsigned i = 0; i < 3; i++) + { + net[0]->x = net[0]->x + 2; + stop_arcs->flow = net[0]->x / 2; + stop_arcs->flow = stop_arcs->flow + 20; + stop_arcs->net_add = net[0]; + stop_arcs++; + } + + if( net[1] != 0 && stop_arcs != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_board_init.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_board_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d217f7bd80e719ca96ab92b9ecdbd394a2c1a6ab --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_board_init.c @@ -0,0 +1,77 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_5__ TYPE_2__; +typedef struct TYPE_4__ TYPE_1__; + +struct TYPE_4__ +{ + int Pin; + int Pull; + int Mode; + int Speed; +}; + +struct TYPE_5__ +{ + int MEMRMP; +}; +typedef TYPE_1__ GPIO_InitTypeDef; + +int BT_RST_PIN; +int BT_RST_PORT; +int CONN_POS10_PIN; +int CONN_POS10_PORT; +int GPIO_HIGH (int, int); +int GPIO_MODE_INPUT; +int GPIO_MODE_OUTPUT_PP; +int GPIO_NOPULL; +int GPIO_PULLUP; +int GPIO_SPEED_FREQ_LOW; +int HAL_GPIO_Init (int, TYPE_1__ *); +scalar_t__ IS_GPIO_RESET (int, int); +TYPE_2__ *SYSCFG; +int __HAL_RCC_GPIOB_CLK_ENABLE (); +int __HAL_RCC_GPIOC_CLK_ENABLE (); + +__attribute__((used)) static void +LBF_DFU_If_Needed (void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + __HAL_RCC_GPIOC_CLK_ENABLE (); + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Pin = BT_RST_PIN; + HAL_GPIO_Init (BT_RST_PORT, &GPIO_InitStruct); + + GPIO_HIGH (BT_RST_PORT, BT_RST_PIN); + __HAL_RCC_GPIOB_CLK_ENABLE (); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Pin = CONN_POS10_PIN; + HAL_GPIO_Init (CONN_POS10_PORT, &GPIO_InitStruct); + + if (IS_GPIO_RESET (CONN_POS10_PORT, CONN_POS10_PIN)) + { + SYSCFG->MEMRMP = 0x00000001; + asm ( + "LDR R0, =0x000000\n\t" + "LDR SP, [R0, #0]\n\t" + ); + asm ( + "LDR R0, [R0, #0]\n\t" + "BX R0\n\t" + ); + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_claw.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_claw.c new file mode 100644 index 0000000000000000000000000000000000000000..f9e2cf471c837b4d49c41736a1f611059fffbb49 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_claw.c @@ -0,0 +1,84 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_2__ TYPE_1__; + +struct net_device +{ + struct claw_privbk* ml_priv; +}; +struct clawctl +{ + int linkid; +}; +struct claw_privbk +{ + int system_validate_comp; + TYPE_1__* p_env; + int ctl_bk; +}; +typedef int __u8; +struct TYPE_2__ +{ + scalar_t__ packing; + int api_type; +}; + +int CLAW_DBF_TEXT (int, int, char*); +int CONNECTION_REQUEST; +int HOST_APPL_NAME; +scalar_t__ PACKING_ASK; +scalar_t__ PACK_SEND; +int WS_APPL_NAME_IP_NAME; +int WS_APPL_NAME_PACKED; +int claw_send_control (struct net_device*, int, int, int, int, int, int); +int setup; + +__attribute__((noinline)) int +claw_send_control (struct net_device* net, int a, int b, int c, int d, int e, + int f) +{ + return net->ml_priv->system_validate_comp + a + b + c + d + f; +} + +__attribute__((used)) static int +claw_snd_conn_req (struct net_device *dev, __u8 link) +{ + int rc; + struct claw_privbk *privptr = dev->ml_priv; + struct clawctl *p_ctl; + CLAW_DBF_TEXT (2, setup, "snd_conn"); + rc = 1; + p_ctl = (struct clawctl *)&privptr->ctl_bk; + p_ctl->linkid = link; + if (privptr->system_validate_comp == 0x00) + { + return rc; + } + if (privptr->p_env->packing == PACKING_ASK) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + WS_APPL_NAME_PACKED, WS_APPL_NAME_PACKED); + } + if (privptr->p_env->packing == PACK_SEND) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + WS_APPL_NAME_IP_NAME, WS_APPL_NAME_IP_NAME); + } + if (privptr->p_env->packing == 0) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + HOST_APPL_NAME, privptr->p_env->api_type); + } + return rc; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_dtrace.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_dtrace.c new file mode 100644 index 0000000000000000000000000000000000000000..c86c4bb3cd0c8eb95f9e9d2e3bbe3e08b8e2f275 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_dtrace.c @@ -0,0 +1,56 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_4__ TYPE_2__; +typedef struct TYPE_3__ TYPE_1__; + +typedef int uint8_t; +typedef int uint16_t; + +struct TYPE_4__ +{ + size_t cpu_id; +}; + +struct TYPE_3__ +{ + int cpuc_dtrace_flags; +}; + +TYPE_2__ *CPU; +volatile int CPU_DTRACE_FAULT; +TYPE_1__ *cpu_core; +scalar_t__ dtrace_load8 (uintptr_t); + +__attribute__((used)) static int +dtrace_bcmp (const void *s1, const void *s2, size_t len) +{ + volatile uint16_t *flags; + flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + if (s1 == s2) + return (0); + if (s1 == NULL || s2 == NULL) + return (1); + if (s1 != s2 && len != 0) + { + const uint8_t *ps1 = s1; + const uint8_t *ps2 = s2; + do + { + if (dtrace_load8 ((uintptr_t)ps1++) != *ps2++) + return (1); + } + while (--len != 0 && !(*flags & CPU_DTRACE_FAULT)); + } + return (0); +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_gc.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_gc.c new file mode 100644 index 0000000000000000000000000000000000000000..8484d29d256b70941f9d75c2673fbee3c3341018 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_gc.c @@ -0,0 +1,162 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +struct mrb_context +{ + size_t stack; + size_t stbase; + size_t stend; + size_t eidx; + int *ci; + int *cibase; + int status; +}; + +struct RObject +{ + int dummy; +}; + +struct RHash +{ + int dummy; +}; + +struct RFiber +{ + struct mrb_context *cxt; +}; + +struct RClass +{ + int dummy; +}; + +struct RBasic +{ + int tt; +}; + +struct RArray +{ + int dummy; +}; + +typedef int mrb_state; +typedef int mrb_gc; +typedef int mrb_callinfo; +size_t ARY_LEN (struct RArray *); +size_t MRB_ENV_STACK_LEN (struct RBasic *); +int MRB_FIBER_TERMINATED; + +#define MRB_TT_ARRAY 140 +#define MRB_TT_CLASS 139 +#define MRB_TT_DATA 138 +#define MRB_TT_ENV 137 +#define MRB_TT_EXCEPTION 136 +#define MRB_TT_FIBER 135 +#define MRB_TT_HASH 134 +#define MRB_TT_ICLASS 133 +#define MRB_TT_MODULE 132 +#define MRB_TT_OBJECT 131 +#define MRB_TT_PROC 130 +#define MRB_TT_RANGE 129 +#define MRB_TT_SCLASS 128 + +size_t ci_nregs (int *); +int gc_mark_children (int *, int *, struct RBasic *); +size_t mrb_gc_mark_hash_size (int *, struct RHash *); +size_t mrb_gc_mark_iv_size (int *, struct RObject *); +size_t mrb_gc_mark_mt_size (int *, struct RClass *); + +__attribute__((used)) static size_t +gc_gray_mark (mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) +{ + size_t children = 0; + gc_mark_children (mrb, gc, obj); + switch (obj->tt) + { + case MRB_TT_ICLASS: + children++; + break; + + case MRB_TT_CLASS: + case MRB_TT_SCLASS: + case MRB_TT_MODULE: + { + struct RClass *c = (struct RClass *)obj; + children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj); + children += mrb_gc_mark_mt_size (mrb, c); + children ++; + } + break; + + case MRB_TT_OBJECT: + case MRB_TT_DATA: + case MRB_TT_EXCEPTION: + children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj); + break; + + case MRB_TT_ENV: + children += MRB_ENV_STACK_LEN (obj); + break; + + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber *)obj)->cxt; + size_t i; + mrb_callinfo *ci; + if (!c || c->status == MRB_FIBER_TERMINATED) + break; + + i = c->stack - c->stbase; + if (c->ci) + { + i += ci_nregs (c->ci); + } + if (c->stbase + i > c->stend) + i = c->stend - c->stbase; + + children += i; + children += c->eidx; + if (c->cibase) + { + for (i = 0, ci = c->cibase; ci <= c->ci; i++, ci++) + ; + } + children += i; + } + break; + + case MRB_TT_ARRAY: + { + struct RArray *a = (struct RArray *)obj; + children += ARY_LEN (a); + } + break; + + case MRB_TT_HASH: + children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj); + children += mrb_gc_mark_hash_size (mrb, (struct RHash *)obj); + break; + + case MRB_TT_PROC: + case MRB_TT_RANGE: + children += 2; + break; + default: + break; + } + + return children; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_hpsa.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_hpsa.c new file mode 100644 index 0000000000000000000000000000000000000000..300b2dac4db1ea877c4eef600b150fc9d49f3804 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_hpsa.c @@ -0,0 +1,126 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_6__ TYPE_3__; +typedef struct TYPE_5__ TYPE_2__; +typedef struct TYPE_4__ TYPE_1__; + +struct io_accel2_cmd +{ + int dummy; +}; + +struct hpsa_tmf_struct +{ + int it_nexus; +}; + +struct hpsa_scsi_dev_t +{ + int nphysical_disks; + int ioaccel_handle; + struct hpsa_scsi_dev_t **phys_disk; +}; + +struct ctlr_info +{ + TYPE_3__ *pdev; + struct io_accel2_cmd *ioaccel2_cmd_pool; +}; +struct TYPE_4__ +{ + int LunAddrBytes; +}; + +struct TYPE_5__ +{ + TYPE_1__ LUN; +}; + +struct CommandList +{ + size_t cmdindex; + int cmd_type; + struct hpsa_scsi_dev_t *phys_disk; + TYPE_2__ Header; +}; + +struct TYPE_6__ +{ + int dev; +}; + +int BUG (); +#define CMD_IOACCEL1 132 +#define CMD_IOACCEL2 131 +#define CMD_IOCTL_PEND 130 +#define CMD_SCSI 129 +#define IOACCEL2_TMF 128 +int dev_err (int *, char *, int); +scalar_t__ hpsa_is_cmd_idle (struct CommandList *); +int le32_to_cpu (int); +int test_memcmp (unsigned char *, int *, int); + +__attribute__((used)) static bool +hpsa_cmd_dev_match (struct ctlr_info *h, struct CommandList *c, + struct hpsa_scsi_dev_t *dev, unsigned char *scsi3addr) +{ + int i; + bool match = false; + struct io_accel2_cmd * c2 = &h->ioaccel2_cmd_pool[c->cmdindex]; + struct hpsa_tmf_struct *ac = (struct hpsa_tmf_struct *)c2; + + if (hpsa_is_cmd_idle (c)) + return false; + + switch (c->cmd_type) + { + case CMD_SCSI: + case CMD_IOCTL_PEND: + match = !test_memcmp (scsi3addr, &c->Header.LUN.LunAddrBytes, + sizeof (c->Header.LUN.LunAddrBytes)); + break; + + case CMD_IOACCEL1: + case CMD_IOACCEL2: + if (c->phys_disk == dev) + { + match = true; + } + else + { + for (i = 0; i < dev->nphysical_disks && !match; i++) + { + match = dev->phys_disk[i] == c->phys_disk; + } + } + break; + + case IOACCEL2_TMF: + for (i = 0; i < dev->nphysical_disks && !match; i++) + { + match = dev->phys_disk[i]->ioaccel_handle == + le32_to_cpu (ac->it_nexus); + } + break; + + case 0: + match = false; + break; + default: + dev_err (&h->pdev->dev, "unexpected cmd_type: %d\n", c->cmd_type); + BUG (); + } + + return match; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_mv_udc_core.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_mv_udc_core.c new file mode 100644 index 0000000000000000000000000000000000000000..9397b98eaef0eed1b594cb13fd9e87dccd78e037 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_mv_udc_core.c @@ -0,0 +1,82 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_4__ TYPE_2__; +typedef struct TYPE_3__ TYPE_1__; +typedef int u32; + +struct mv_udc +{ + TYPE_2__ *op_regs; + TYPE_1__ *ep_dqh; + struct mv_ep *eps; +}; + +struct mv_ep +{ + TYPE_1__ *dqh; + struct mv_udc *udc; +}; + +struct TYPE_4__ +{ + int *epctrlx; +}; + +struct TYPE_3__ +{ + int max_packet_length; + int next_dtd_ptr; +}; + +int EP0_MAX_PKT_SIZE; +int EPCTRL_RX_ENABLE; +int EPCTRL_RX_EP_TYPE_SHIFT; +int EPCTRL_TX_ENABLE; +int EPCTRL_TX_EP_TYPE_SHIFT; +int EP_QUEUE_HEAD_IOS; +int EP_QUEUE_HEAD_MAX_PKT_LEN_POS; +int EP_QUEUE_HEAD_NEXT_TERMINATE; +int USB_ENDPOINT_XFER_CONTROL; +int readl (int *); +int writel (int, int *); + +__attribute__((used)) static void +ep0_reset (struct mv_udc *udc) +{ + struct mv_ep *ep; + u32 epctrlx; + int i = 0; + for (i = 0; i < 2; i++) + { + ep = &udc->eps[i]; + ep->udc = udc; + ep->dqh = &udc->ep_dqh[i]; + ep->dqh->max_packet_length = + (EP0_MAX_PKT_SIZE << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) + | EP_QUEUE_HEAD_IOS; + ep->dqh->next_dtd_ptr = EP_QUEUE_HEAD_NEXT_TERMINATE; + epctrlx = readl (&udc->op_regs->epctrlx[0]); + if (i) + { + epctrlx |= EPCTRL_TX_ENABLE + | (USB_ENDPOINT_XFER_CONTROL << EPCTRL_TX_EP_TYPE_SHIFT); + } + else + { + epctrlx |= EPCTRL_RX_ENABLE + | (USB_ENDPOINT_XFER_CONTROL << EPCTRL_RX_EP_TYPE_SHIFT); + } + writel (epctrlx, &udc->op_regs->epctrlx[0]); + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_tcp_usrreq.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_tcp_usrreq.c new file mode 100644 index 0000000000000000000000000000000000000000..0ae75e13e8f5b4d89640b65e269bcaaacd37c0d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_tcp_usrreq.c @@ -0,0 +1,58 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +struct tcpcb +{ + int t_state; +}; + +struct socket +{ + int dummy; +}; + +struct proc +{ + int dummy; +}; + +struct inpcb +{ + scalar_t__ inp_lport; +}; + +int COMMON_END (int); +int COMMON_START (); +int PRU_LISTEN; +int TCPS_LISTEN; +int in_pcbbind (struct inpcb *, int *, struct proc *); +struct inpcb* sotoinpcb (struct socket *); + +__attribute__((used)) static void +tcp_usr_listen (struct socket *so, struct proc *p) +{ + int error = 0; + struct inpcb *inp = sotoinpcb (so); + struct tcpcb *tp; + + COMMON_START (); + if (inp->inp_lport == 0) + { + error = in_pcbbind (inp, NULL, p); + } + if (error == 0) + { + tp->t_state = TCPS_LISTEN; + } + COMMON_END (PRU_LISTEN); +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_ui_main.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_ui_main.c new file mode 100644 index 0000000000000000000000000000000000000000..512fb37a7f48fff187d2ec3b52491b27cf97a359 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_extr_ui_main.c @@ -0,0 +1,61 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_4__ TYPE_2__; +typedef struct TYPE_3__ TYPE_1__; + +struct TYPE_4__ +{ + size_t modCount; + TYPE_1__ *modList; +}; + +struct TYPE_3__ +{ + void *modDescr; + void *modName; +}; + +size_t MAX_MODS; +void *String_Alloc (char *); +int test_strlen (char *); +int trap_FD_GetFileList (char *, char *, char *, int); +TYPE_2__ uiInfo; + +__attribute__((used)) static void +UI_LoadMods () +{ + int numdirs; + char dirlist[2048]; + char *dirptr; + char *descptr; + int i; + int dirlen; + + uiInfo.modCount = 0; + numdirs = trap_FD_GetFileList ("$modelist", "", dirlist, sizeof (dirlist)); + dirptr = dirlist; + for (i = 0; i < numdirs; i++) + { + dirlen = test_strlen (dirptr) + 1; + descptr = dirptr + dirlen; + uiInfo.modList[uiInfo.modCount].modName = String_Alloc (dirptr); + uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc (descptr); + dirptr += dirlen + test_strlen (descptr) + 1; + uiInfo.modCount++; + if (uiInfo.modCount >= MAX_MODS) + { + break; + } + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_func_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_func_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..74ea93bbc59282b7912d29605bb9610ae1158240 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_func_ptr.c @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +#include + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +int num; + +int (*foo)(int d); +int f (int t); + +typedef struct str_t str_t1; +struct str_t +{ + int a; + float b; + int (*foo)(int d); +}; + +int main () +{ + int i, r; + r = rand (); + num = r > N ? N : r; + str_t1 * p1 = calloc (num, sizeof (str_t1)); + if (p1 == NULL) + return 0; + for (i = 0; i < num; i++) + { + p1[i].foo = malloc (1 * sizeof (f)); + p1[i].foo = f; + p1[i].foo (i); + } + + for (i = 0; i < num; i++) + p1[i].a = 1; + + for (i = 0; i < num; i++) + p1[i].b = 2; + + for (i = 0; i < num; i++) + if (p1[i].a != 1) + abort (); + + for (i = 0; i < num; i++) + if (abs (p1[i].b - 2) > 0.0001) + abort (); + + return 0; +} + +int f (int t) +{ + if ( t < 0) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_mem_ref_offset.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_mem_ref_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..6148770282cfb758be4c84e58f9673045c150302 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_mem_ref_offset.c @@ -0,0 +1,58 @@ +/* Supports the MEM_REF offset. + _1 = MEM[(struct arc *)ap_4 + 72B].flow; + Old rewrite:_1 = ap.reorder.0_8->flow; + New rewrite:_1 = MEM[(struct arc.reorder.0 *)ap.reorder.0_8 + 64B].flow. */ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + const int MAX = 100; + /* A similar scenario can be reproduced only by using local variables. */ + arc_p ap = NULL; + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..0570d8952094d075339cf02baabc45842ef22b58 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct T_HASH_ENTRY +{ + unsigned int hash; + unsigned int klen; + char *key; +} iHashEntry; + +typedef struct T_HASH +{ + unsigned int size; + unsigned int fill; + unsigned int keys; + + iHashEntry **array; +} uHash; + +uHash *retval; + +int +main() { + retval->array = (iHashEntry **)calloc(sizeof(iHashEntry *), retval->size); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_diff.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_diff.c new file mode 100644 index 0000000000000000000000000000000000000000..4c395264da942ff7d5ac3e9796ada1938868b514 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_diff.c @@ -0,0 +1,71 @@ +// support POINTER_DIFF_EXPR & NOP_EXPR to avoid +// escape_unhandled_rewrite, "Type escapes via a unhandled rewrite stmt" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + arc_t *old_arcs; + node_t *node; + node_t *stop; + size_t off; + network_t* net; + + for( ; node->number < stop->number; node++ ) + { + off = node->basic_arc - old_arcs; + node->basic_arc = (arc_t *)(net->arcs + off); + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 3 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_negate_expr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_negate_expr.c new file mode 100644 index 0000000000000000000000000000000000000000..e59a4b48429bb8e638c1ab3c15f151b915f631c5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_negate_expr.c @@ -0,0 +1,55 @@ +// support NEGATE_EXPR rewriting +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + int64_t susp = 0; + const int MAX = 100; + arc_p ap = (arc_p) calloc(MAX, sizeof(arc_t)); + ap -= susp; + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..48cd7932a670b4d18deaf2f393fc31eb737aaba1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/dfe_ptr_ptr.c @@ -0,0 +1,55 @@ +// release escape_ptr_ptr, "Type is used in a pointer to a pointer [not handled yet]"; +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_t **ap = NULL; + +int +main () +{ + ap = (arc_t**) malloc(MAX * sizeof(arc_t*)); + (*ap)[0].id = 300; + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_cast_int.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_cast_int.c new file mode 100644 index 0000000000000000000000000000000000000000..6f67fc556afca98085f22ae1cfd238f69a342ce6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_cast_int.c @@ -0,0 +1,91 @@ +// Escape cast int for pointer compression +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + node_p n1 = (node_p) 0x123456; + + for (unsigned i = 0; i < MAX; i++) + { + node->pred = n1; + node = node + 1; + } + + node = net->nodes; + + for (unsigned i = 0; i < MAX; i++) + { + if (node->pred != n1) + { + abort (); + } + node = node + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in pointer compression" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_compress_and_decomress.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_compress_and_decomress.c new file mode 100644 index 0000000000000000000000000000000000000000..d0b8d1afa48b16b71971992c86b19c8452c4916e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_compress_and_decomress.c @@ -0,0 +1,90 @@ +// Support basic pointer compression and decompression +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + + for (unsigned i = 0; i < MAX; i++) + { + node->pred = node; + node = node + 1; + } + + node = net->nodes; + + for (unsigned i = 0; i < MAX; i++) + { + if (node->pred != node) + { + abort (); + } + node = node + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in pointer compression is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_ptr2void.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_ptr2void.c new file mode 100644 index 0000000000000000000000000000000000000000..5022c1967bc79798ac42210e458f0071dd6f1fbc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_ptr2void.c @@ -0,0 +1,87 @@ +// Partially support escape_cast_void for pointer compression. +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs, sorted_arcs; + int x; + node_p nodes, stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +network_t* net = NULL; +int cnt = 0; + +__attribute__((noinline)) int +primal_feasible (network_t *net) +{ + void* stop; + node_t *node; + + node = net->nodes; + stop = (void *)net->stop_nodes; + for( node++; node < (node_t *)stop; node++ ) + { + net->x = 1; + printf( "PRIMAL NETWORK SIMPLEX: "); + } + return 0; +} + +int +main () +{ + net = (network_t*) calloc (1, 20); + net->nodes = calloc (MAX, sizeof (node_t)); + net->stop_nodes = net->nodes + MAX - 1; + cnt = primal_feasible( net ); + + net = (network_t*) calloc (1, 20); + if( !(net->arcs) ) + { + return -1; + } + return cnt; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in pointer compression is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_simple_rewrite_pc.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_simple_rewrite_pc.c new file mode 100644 index 0000000000000000000000000000000000000000..98943c9b81315858abc38d388847a0efc67b4b33 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_simple_rewrite_pc.c @@ -0,0 +1,112 @@ +// Check simplify rewrite chance for pointer compression and decompression +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; +arc_p arc; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + arc = net->arcs; + + for (unsigned i = 0; i < MAX; i++) + { + arc->head = node; + arc->head->child = node; + node->potential = i + 1; + arc->cost = arc->head->potential; + arc->tail = node->sibling; + if (i % 2) + node->pred = net->nodes + i; + else + node->pred = NULL; + + if (node->pred && node->pred->child != NULL) + node->number = 0; + else + node->number = 1; + + node = node + 1; + arc = arc + 1; + } + + node = net->nodes; + arc = net->arcs; + + for (unsigned i = 0; i < MAX; i++) + { + node_p t = i % 2 ? node : NULL; + int tt = i % 2 ? 0 : 1; + if (arc->head->pred != t || arc->cost == 0 + || arc->tail != node->sibling || node->number != tt) + { + abort (); + } + arc = arc + 1; + node = node + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in pointer compression is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_skip_void_struct_name.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_skip_void_struct_name.c new file mode 100644 index 0000000000000000000000000000000000000000..a0e191267b7a0b7c2d22cca530a3d710b4241a00 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/pc_skip_void_struct_name.c @@ -0,0 +1,53 @@ +// Structures without names should not be optimized +/* { dg-do compile } */ +#include +#include + +typedef struct +{ + int a; + float b; + double s1; + double s2; + double s3; + double s4; + double s5; + double s6; + double s7; + double s8; +} str_t1; + +#define N 1000 + +int num; + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + str_t1 *p1 = calloc (num, sizeof (str_t1)); + + if (p1 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + for (i = 0; i < num; i++) + p1[i].b = 2; + + for (i = 0; i < num; i++) + if (p1[i].a != 1) + abort (); + + for (i = 0; i < num; i++) + if (fabsf (p1[i].b - 2) > 0.0001) + abort (); + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in pointer compression" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_DTE_struct_instance_field.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_DTE_struct_instance_field.c new file mode 100644 index 0000000000000000000000000000000000000000..1b6a462e2715c36ddb361b5d0306cf2e45e4c3f2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_DTE_struct_instance_field.c @@ -0,0 +1,75 @@ +// escape_instance_field, "Type escapes via a field of instance". +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; + node_t node; +} network_t; + + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; + node_t node; +}; + + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + net[0]->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + /* Contains an escape type and has structure instance field. */ + net[0]->arcs->node = net[0]->node; + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_DTE_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_DTE_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..346c7126446a35b7dc5c5ff8caefad78ff6b3dde --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_DTE_verify.c @@ -0,0 +1,94 @@ +// Verify in escape_dependent_type_escapes, +// the multi-layer dereference is rewriting correctly,and the memory access +// is correct. + +// release +// escape_dependent_type_escapes, +// "Type uses a type which escapes or is used by a type which escapes" +// avoid escape_cast_another_ptr, "Type escapes a cast to a different pointer" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; +arc_p stop_arcs = NULL; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + net[0]->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + net[0]->arcs->id = 100; + + for (unsigned i = 0; i < 3; i++) + { + net[0]->arcs->id = net[0]->arcs->id + 2; + stop_arcs->cost = net[0]->arcs->id / 2; + stop_arcs->net_add = net[0]; + printf("stop_arcs->cost = %ld\n", stop_arcs->cost); + net[0]->arcs++; + stop_arcs++; + } + + if( net[1] != 0 && stop_arcs != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_check_ptr_layers_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_check_ptr_layers_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..8eb16c8d678c83871c3e6b3a6f49a4acc76cb1cc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_check_ptr_layers_bug.c @@ -0,0 +1,24 @@ +/* check_ptr_layers bugfix.*/ +/* { dg-do compile } */ +struct { + char a; +} **b = 0, *e = 0; +long c; +char d = 9; +int f; + +void g() +{ + for (; f;) + if (c) + (*e).a++; + if (!d) + for (;;) + b &&c; +} +int +main() +{ + g(); +} +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_create_fields_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_create_fields_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..7d7641f011d6c9f9efb5285134ea92fa2db36a1f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_create_fields_bug.c @@ -0,0 +1,82 @@ +// bugfix: +// Common members do not need to reconstruct. +// Otherwise, eg:int* -> int** and void* -> void**. +/* { dg-do compile } */ + +#include +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t* cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t** org_cost; +}; + +struct a +{ + int t; + int t1; +}; + +__attribute__((noinline)) int +f(int i, int j) +{ + struct a *t = NULL; + struct a t1 = {i, j}; + t = &t1; + auto int g(void) __attribute__((noinline)); + int g(void) + { + return t->t + t->t1; + } + return g(); +} + +arc_t **ap = NULL; +const int MAX = 100; + +int +main() +{ + if (f(1, 2) != 3) + { + abort (); + } + ap = (arc_t**) malloc(MAX * sizeof(arc_t*)); + (*ap)[0].id = 300; + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_create_new_func_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_create_new_func_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..63fb3f8284cb9d6218abc2419593cc30c2969632 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_create_new_func_bug.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ + +#include +#include + +#define MallocOrDie(x) sre_malloc((x)) + +struct gki_elem { + char *key; + int idx; + struct gki_elem *nxt; +}; + +typedef struct { + struct gki_elem **table; + + int primelevel; + int nhash; + int nkeys; +} GKI; + +void +Die(char *format, ...) +{ + exit(1); +} + +void * +sre_malloc(size_t size) +{ + void *ptr; + + if ((ptr = malloc (size)) == NULL) + { + Die("malloc of %ld bytes failed", size); + } + return ptr; +} + + +__attribute__((noinline)) int +GKIStoreKey(GKI *hash, char *key) +{ + hash->table[0] = MallocOrDie(sizeof(struct gki_elem)); +} + +int +main () +{ + GKI *hash; + char *key; + GKIStoreKey(hash, key); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ele_minus_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ele_minus_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..8c431e15ffd3d259ef81ac89a457dc5b68de36b7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ele_minus_verify.c @@ -0,0 +1,60 @@ +// verify newarc[cmp-1].flow +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p ap = NULL; + +int +main () +{ + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[0].id); + for (int i = 1; i < MAX; i++) + { + ap[i-1].id = 500; + } + printf("%d\n", ap[0].id); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_escape_by_base.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_escape_by_base.c new file mode 100644 index 0000000000000000000000000000000000000000..efc95a4cd56e1bb10a0db989b77e0d201b360fdd --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_escape_by_base.c @@ -0,0 +1,83 @@ +// release type is used by a type which escapes. +// avoid escape_cast_another_ptr, "Type escapes a cast to a different pointer" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +network_t* net = NULL; +arc_p stop_arcs = NULL; +int cnt = 0; + +int +main () +{ + net = (network_t*) calloc (1, 20); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + if(!(net->arcs)) + { + return -1; + } + + for( int i = 0; i < MAX; i++, net->arcs = stop_arcs) + { + cnt++; + } + + net = (network_t*) calloc (1, 20); + if( !(net->arcs) ) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_external_func_types.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_external_func_types.c new file mode 100644 index 0000000000000000000000000000000000000000..2a9bea78369abb1ab4f7547f3a3ba96102f598d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_external_func_types.c @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-shared" } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + int x; + arc_p arcs, sorted_arcs; + node_p nodes, stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +extern int bcf_sr_add_reader (network_t *); +extern int bcf_hdr_dup (arc_p); + +int +test () +{ + network_t *net = (network_t *) calloc (1, 20); + + if (!bcf_sr_add_reader(net)) + printf("error"); + arc_p arc = net->nodes->basic_arc; + if(!bcf_hdr_dup(arc)) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_int_cast_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_int_cast_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..75fc10575d58ccbc49955c8497807668462fd766 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_int_cast_ptr.c @@ -0,0 +1,72 @@ +// release escape_cast_another_ptr, "Type escapes a cast to a different pointer" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +typedef int cmp_t(const void *, const void *); + +__attribute__((noinline)) void +spec_qsort(void *a, cmp_t *cmp) +{ + char *pb = NULL; + while (cmp(pb, a)) + { + pb += 1; + } +} + +static int arc_compare( arc_t **a1, int a2 ) +{ + if( (*a1)->id < a2 ) + { + return -1; + } + return 1; +} + +int +main() +{ + spec_qsort(NULL, (int (*)(const void *, const void *))arc_compare); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_mem_ref_offset.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_mem_ref_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..9fb06877bcbf068e2d47a91b5a214ed1b8f89c6b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_mem_ref_offset.c @@ -0,0 +1,58 @@ +/* Supports the MEM_REF offset. + _1 = MEM[(struct arc *)ap_4 + 72B].flow; + Old rewrite:_1 = ap.reorder.0_8->flow; + New rewrite:_1 = MEM[(struct arc.reorder.0 *)ap.reorder.0_8 + 64B].flow. */ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + const int MAX = 100; + /* A similar scenario can be reproduced only by using local variables. */ + arc_p ap = NULL; + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..e8eb0eaa09a549805d5486c8726e4b82003842b3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct T_HASH_ENTRY +{ + unsigned int hash; + unsigned int klen; + char *key; +} iHashEntry; + +typedef struct T_HASH +{ + unsigned int size; + unsigned int fill; + unsigned int keys; + + iHashEntry **array; +} uHash; + +uHash *retval; + +int +main() { + retval->array = (iHashEntry **)calloc(sizeof(iHashEntry *), retval->size); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_pass_conflict.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_pass_conflict.c new file mode 100644 index 0000000000000000000000000000000000000000..bd535afd08d1ed5dc3657a4089f38e314e821a86 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_pass_conflict.c @@ -0,0 +1,109 @@ +// For testing: +/* +Compile options: gcc -O3 -g +-flto -flto-partition=one -fipa-reorder-fields -fipa-struct-reorg +-v -save-temps -fdump-ipa-all-details test.c -o test + +in COMPLETE_STRUCT_RELAYOUT pass: +N type: struct node.reorder.0 new = "Type escapes a cast to a different pointer" +copy$head_26 = test_arc.reorder.0_49->head; + +type : struct arc.reorder.0(1599) { +fields = { +field (5382) {type = cost_t} +field (5383) {type = struct node.reorder.0 *} // but node has escaped. +field (5384) {type = struct node.reorder.0 *} +field (5386) {type = struct arc.reorder.0 *} +field (5387) {type = struct arc.reorder.0 *} +field (5388) {type = flow_t} +field (5389) {type = cost_t} +field (5381) {type = int} +field (5385) {type = short int} +} + +// The types of the two types are inconsistent after the rewriting. +newarc_2(D)->tail = tail_1(D); +vs +struct_reorder.0_61(D)->tail = tail_1(D); +*/ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +__attribute__((noinline)) void +replace_weaker_arc( arc_t *newarc, node_t *tail, node_t *head) +{ + printf("test"); +} + +__attribute__((noinline)) int64_t +switch_arcs(arc_t** deleted_arcs, arc_t* arcnew) +{ + int64_t count = 0; + arc_t *test_arc, copy; + + if (!test_arc->ident) + { + copy = *test_arc; + count++; + *test_arc = arcnew[0]; + replace_weaker_arc(arcnew, NULL, NULL); + } + return count; +} + +int +main () +{ + switch_arcs(NULL, NULL); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr2void_lto.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr2void_lto.c new file mode 100644 index 0000000000000000000000000000000000000000..11393a197a357dcdaae6353cb199aac31eef9c89 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr2void_lto.c @@ -0,0 +1,87 @@ +// escape_cast_void, "Type escapes a cast to/from void*" +// stop_393 = net.stop_nodes; void *stop; +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs, sorted_arcs; + int x; + node_p nodes, stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +network_t* net = NULL; +int cnt = 0; + +__attribute__((noinline)) int +primal_feasible (network_t *net) +{ + void* stop; + node_t *node; + + node = net->nodes; + stop = (void *)net->stop_nodes; + for( node++; node < (node_t *)stop; node++ ) + { + printf( "PRIMAL NETWORK SIMPLEX: " ); + } + return 0; +} + +int +main () +{ + net = (network_t*) calloc (1, 20); + net->nodes = calloc (MAX, sizeof (node_t)); + net->stop_nodes = calloc (MAX, sizeof (node_t)); + cnt = primal_feasible( net ); + + net = (network_t*) calloc (1, 20); + if( !(net->arcs) ) + { + return -1; + } + return cnt; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_diff.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_diff.c new file mode 100644 index 0000000000000000000000000000000000000000..d601fae64d4d8e919835155339a7d38c69a0a9a3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_diff.c @@ -0,0 +1,71 @@ +// support POINTER_DIFF_EXPR & NOP_EXPR to avoid +// escape_unhandled_rewrite, "Type escapes via a unhandled rewrite stmt" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + arc_t *old_arcs; + node_t *node; + node_t *stop; + size_t off; + network_t* net; + + for( ; node->number < stop->number; node++ ) + { + off = node->basic_arc - old_arcs; + node->basic_arc = (arc_t *)(net->arcs + off); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 3" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_negate_expr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_negate_expr.c new file mode 100644 index 0000000000000000000000000000000000000000..4d5f25aa1645e702617101b7da8c1201f3daacea --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_negate_expr.c @@ -0,0 +1,55 @@ +// support NEGATE_EXPR rewriting +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + int64_t susp = 0; + const int MAX = 100; + arc_p ap = (arc_p) calloc(MAX, sizeof(arc_t)); + ap -= susp; + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_offset.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..b3891fde9280142a50ed3fcb023c6541f7aa4d42 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_offset.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ + +#include +#include + +struct node +{ + struct node *left, *right; + double a, b, c, d, e, f; +} +*a; +int b, c; +void +CreateNode (struct node **p1) +{ + *p1 = calloc (10, sizeof (struct node)); +} + +int +main () +{ + a->left = 0; + struct node *t = a; + CreateNode (&t->right); + + struct node p = *a; + b = 1; + if (p.left) + b = 0; + if (b) + printf (" Tree.\n"); +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..4df79e4f0e8d2a35d638127f23172907226ade87 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_ptr.c @@ -0,0 +1,55 @@ +// release escape_ptr_ptr, "Type is used in a pointer to a pointer [not handled yet]"; +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_t **ap = NULL; + +int +main () +{ + ap = (arc_t**) malloc(MAX * sizeof(arc_t*)); + (*ap)[0].id = 300; + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_ptr_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_ptr_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..49d2106d1dc6d083c6f6debc5ff42031b3b86d76 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_ptr_ptr_ptr.c @@ -0,0 +1,58 @@ +// release escape_ptr_ptr, "Type is used in a pointer to a pointer [not handled yet]" + +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p **ap; + + +int +main () +{ + ap = (arc_p**) calloc(MAX, sizeof(arc_p*)); + (**ap)[0].id = 500; + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rescusive_type.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rescusive_type.c new file mode 100644 index 0000000000000000000000000000000000000000..f71c7894f361b9a6b8eaa5071328c005f1a5fe63 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rescusive_type.c @@ -0,0 +1,57 @@ +// release escape_rescusive_type, "Recusive type" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p ap = NULL; + +int +main () +{ + ap = (arc_p) calloc (MAX, sizeof (arc_t)); + ap[0].id = 100; + ap[0].head = (node_p) calloc (MAX, sizeof (node_t)); + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_assign_more_cmp.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_assign_more_cmp.c new file mode 100644 index 0000000000000000000000000000000000000000..721cee2c6ae74564564001f4b608194c52cdaeac --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_assign_more_cmp.c @@ -0,0 +1,65 @@ +// support more gimple assign rhs code +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +__attribute__((noinline)) int +compare(arc_p p1, arc_p p2) +{ + return p1 < p2; +} + +int n = 0; +int m = 0; + +int +main () +{ + scanf ("%d %d", &n, &m); + arc_p p = calloc (10, sizeof (struct arc)); + if (compare (&p[n], &p[m])) + { + printf ("ss!"); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_cond_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_cond_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..3871d3d99f14ef43d01d76700c340257916f5b49 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_cond_bug.c @@ -0,0 +1,72 @@ +// rewrite_cond bugfix; +/* +if (iterator_600 != 0B) +old rewrite: _1369 = iterator.reorder.0_1249 != 0B; if (_1369 != 1) +new rewrite: if (iterator.reorder.0_1249 != 0B) +*/ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct list_elem +{ + arc_t* arc; + struct list_elem* next; +}list_elem; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int i = 0; + +int +main () +{ + register list_elem *first_list_elem; + register list_elem* iterator; + iterator = first_list_elem->next; + while (iterator) + { + iterator = iterator->next; + i++; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 3" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_cond_more_cmp.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_cond_more_cmp.c new file mode 100644 index 0000000000000000000000000000000000000000..5ad206433e02387b2da88df97ccb873e13a4dda4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_cond_more_cmp.c @@ -0,0 +1,58 @@ +// support if (_150 >= _154) +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main() +{ + arc_p **ap = (arc_p**) malloc(1 * sizeof(arc_p*)); + arc_p **arcs_pointer_sorted = (arc_p**) malloc(1 * sizeof(arc_p*)); + arcs_pointer_sorted[0] = (arc_p*) calloc (1, sizeof(arc_p)); + + if (arcs_pointer_sorted >= ap) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_phi_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_phi_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..a002f98892ea734e8da409ec912b81de0855aa8d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_rewrite_phi_bug.c @@ -0,0 +1,81 @@ +/* +Exclude the rewriting error caused by +first_list_elem = (list_elem *)NULL; +rewriting PHI:first_list_elem_700 = PHI <0B(144), 0B(146)> +into: +first_list_elem.reorder.0_55 = PHI <(144), (146)> +*/ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct list_elem +{ + arc_t* arc; + struct list_elem* next; +}list_elem; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout, firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail, head; + short ident; + arc_p nextout, nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; + +list_elem* new_list_elem; +list_elem* first_list_elem; + +int +main () +{ + int i = 0; + list_elem *first_list_elem; + list_elem *new_list_elem; + arc_t *arcout; + for( ; i < MAX && arcout->ident == -1; i++); + + first_list_elem = (list_elem *)NULL; + for( ; i < MAX; i++) + { + new_list_elem = (list_elem*) calloc(1, sizeof(list_elem)); + new_list_elem->next = first_list_elem; + first_list_elem = new_list_elem; + } + if (first_list_elem != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 3" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_shwi.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_shwi.c new file mode 100644 index 0000000000000000000000000000000000000000..2bb326ff20057364ebbde5039f97f4003dc4447d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_shwi.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +struct foo {int dx; long dy; int dz; }; +struct goo {long offset; struct foo* pfoo; }; + +void* func (long); + +__attribute__((used)) static void +test(struct goo* g) +{ + void* pvoid; + struct foo* f; + + for (f = g->pfoo; f->dx; f++) + { + if (f->dy) + break; + } + f--; + + pvoid = func(f->dz + g->offset); + return; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_visible_func.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_visible_func.c new file mode 100644 index 0000000000000000000000000000000000000000..f77a062bda6c0dee37a9ada6905b50d4bddd9db5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_visible_func.c @@ -0,0 +1,92 @@ +// release escape_visible_function, "Type escapes via expternally visible function call" +// compile options: gcc -O3 -fno-inline -fwhole-program +// -flto-partition=one -fipa-struct-reorg arc_compare.c -fdump-ipa-all -S -v +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +__attribute__((noinline)) static int +arc_compare( arc_t **a1, arc_t **a2 ) +{ + if( (*a1)->flow > (*a2)->flow ) + { + return 1; + } + if( (*a1)->flow < (*a2)->flow ) + { + return -1; + } + if( (*a1)->id < (*a2)->id ) + { + return -1; + } + + return 1; +} + +__attribute__((noinline)) void +spec_qsort(void *array, int nitems, int size, + int (*cmp)(const void*,const void*)) +{ + for (int i = 0; i < nitems - 1; i++) + { + if (cmp (array , array)) + { + printf ("CMP 1\n"); + } + else + { + printf ("CMP 2\n"); + } + } +} + +typedef int cmp_t(const void *, const void *); + +int +main () +{ + void *p = calloc (100, sizeof (arc_t **)); + spec_qsort (p, 100, 0, (int (*)(const void *, const void *))arc_compare); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_void_ptr_param_func.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_void_ptr_param_func.c new file mode 100644 index 0000000000000000000000000000000000000000..cba6225a5e9c875015289485f90f091ee591398f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/rf_void_ptr_param_func.c @@ -0,0 +1,54 @@ +// Add a safe func mechanism. +// avoid escape_unkown_field, "Type escapes via an unkown field accessed" +// avoid escape_cast_void, "Type escapes a cast to/from void*" eg: GIMPLE_NOP +/* { dg-do compile } */ + +#include +#include + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct arc +{ + int id; + int64_t cost; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +void +__attribute__((noinline)) spec_qsort (void *a, size_t es) +{ + char *pa; + char *pb; + int cmp_result; + + while ((*(arc_t **)a)->id < *((int *)a)) + { + if (cmp_result == 0) + { + spec_qsort (a, es); + pa = (char *)a - es; + a += es; + *(long *)pb = *(long *)pa; + } + else + { + a -= pa - pb; + } + } +} + +int +main() +{ + arc_p **arcs_pointer_sorted; + spec_qsort (arcs_pointer_sorted[0], sizeof (arc_p)); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/semi_relayout_rewrite.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/semi_relayout_rewrite.c new file mode 100644 index 0000000000000000000000000000000000000000..aca8400ca15b636f6dfaeabe920751b6d00de9cf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/semi_relayout_rewrite.c @@ -0,0 +1,86 @@ +// Check simplify rewrite chance for semi-relayout +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; +arc_p arc; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + arc = net->arcs; + + for (unsigned i = 0; i < MAX; i++) + { + arc->head = node; + arc->head->child = node; + node->potential = i + 1; + arc->cost = arc->head->potential; + arc->tail = node->sibling; + node = node + 1; + arc = arc + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in semi-relayout is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_address_of_field.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_address_of_field.c new file mode 100644 index 0000000000000000000000000000000000000000..9d58edab80a1ab7482ecd96ace02fa9ad30b57b9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_address_of_field.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ + +static struct S { + int *p1; + int *p2; +} s; + +typedef __UINTPTR_TYPE__ uintptr_t; + +int +foo () +{ + int i = 1; + int j = 2; + struct S s; + int **p; + s.p1 = &i; + s.p2 = &j; + p = &s.p1; + uintptr_t pi = (uintptr_t) p; + pi = pi + sizeof (int *); + p = (int **)pi; + **p = 3; + return j; +} + +int +main () +{ + if (foo () != 3) + { + __builtin_abort (); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "struct S has escaped: \"Type escapes via taking the address of field\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_convert_mem.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_convert_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..a99ee0de48429404d55247d572777321b7d009d3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_convert_mem.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +struct T1 { + long var1; + int var2; +}; + +struct T2 { + long var1; + int var2; +}; + +void test (void*); + +__attribute__((used)) void +foo (struct T2 *t2) +{ + struct T1* t1 = (void *)(&t2[1]); + void* data = (void *)(&t1[1]); + + test(data); + return; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_maxmin_expr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_maxmin_expr.c new file mode 100644 index 0000000000000000000000000000000000000000..e3d219fe1e085f3010a3b5603bd804ac6f8e91c7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_maxmin_expr.c @@ -0,0 +1,25 @@ +// { dg-do compile } + +#include + +struct S { + unsigned long a; + unsigned long b; +}; + +struct S* s; +struct S* t = (struct S*) 1000; + +int +main () +{ + s = (struct S*) calloc (1000, sizeof (struct S)); + s = s > t ? s : t; + if (s == 0) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in struct split." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_pointer_and.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_pointer_and.c new file mode 100644 index 0000000000000000000000000000000000000000..9a4b10d9aef61d9a651b203876095294891e69a8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_pointer_and.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +struct test {long val; struct test* next; }; + +unsigned long P_DATA; + +void func (struct test*); + +__attribute__((used)) static void +foo (struct test* pt) +{ + struct test t; + + t.next = (void *)((unsigned long)pt->next & P_DATA); + func(&t); + return; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_pointer_minus.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_pointer_minus.c new file mode 100644 index 0000000000000000000000000000000000000000..a0614a1bae7b355073346e1d99b693b665ec9a72 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/sr_pointer_minus.c @@ -0,0 +1,33 @@ +// { dg-do compile } + +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; +}; + +int max; +int x; + +node_p n; +node_p z; + +int +main () +{ + n = (node_p) calloc (max, sizeof (node_t)); + + node_p xp = &n[x]; + + if (xp - z == 10) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "has escaped: \"Type escapes via a unhandled rewrite stmt\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct-reorg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct-reorg.exp new file mode 100644 index 0000000000000000000000000000000000000000..107f990f5f1272acd9baf0c753ebb0a13b8090b5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct-reorg.exp @@ -0,0 +1,104 @@ +# Copyright (C) 1997-2019 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 +# . + +load_lib gcc-dg.exp +load_lib target-supports.exp + +# Initialize `dg'. +dg-init +torture-init + +set STRUCT_REORG_TORTURE_OPTIONS [list \ + { -O3 } \ + { -Ofast } ] + +set-torture-options $STRUCT_REORG_TORTURE_OPTIONS {{}} + +# -fipa-struct-reorg +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/wo_prof_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_ratio_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_prof_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/struct_reorg*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/sr_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/csr_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/complete_struct_relayout.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-reorder-fields +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/rf*.c]] \ + "" "-fipa-reorder-fields -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=1 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/wo_prof_*.c]] \ + "" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_ratio_*.c]] \ + "" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_prof_*.c]] \ + "" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/struct_reorg*.c]] \ + "" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/sr_*.c]] \ + "" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/csr_*.c]] \ + "" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/complete_struct_relayout.c]] \ + "" "-fipa-struct-reorg=1 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=2 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/wo_prof_*.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_ratio_*.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_prof_*.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/struct_reorg*.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/sr_*.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/csr_*.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/complete_struct_relayout.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/rf*.c]] \ + "" "-fipa-struct-reorg=2 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=3 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dfe*.c]] \ + "" "-fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest $srcdir/$subdir/struct_reorg-7.c \ + "" "-fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=4 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pc*.c]] \ + "" "-fipa-struct-reorg=4 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=5 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pc*.c]] \ + "" "-fipa-struct-reorg=5 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=6 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/semi_relayout*.c]] \ + "" "-fipa-struct-reorg=6 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# All done. +torture-finish +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-1.c new file mode 100644 index 0000000000000000000000000000000000000000..a73ff8e7ec94ae0f0711ccdea60fdc237444dac9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-1.c @@ -0,0 +1,30 @@ +// { dg-do compile } +// { dg-options "-O3 -flto-partition=one -fipa-struct-reorg -fdump-ipa-all -fwhole-program" } + +struct a +{ + int t, t1; +}; + +static struct a *b; + +void *xmalloc(int); + + +void f(void) +{ + b = xmalloc (sizeof(*b)); +} + +int g(void) +{ + return b->t; +} + +int main() +{ + f (); + return g (); +} + +/* { dg-final { scan-ipa-dump "No structures to transform in struct split." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-10.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-10.c new file mode 100644 index 0000000000000000000000000000000000000000..ec422f76f60841f5100711661d8b02c852c0322f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-10.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */ + +struct a { + int b; + char c; +}; +struct { + double d; + _Bool e; +} * f; +struct g { + struct a h; +} i; +long j; +void k(); +void l() { k(i); } +void k(struct a m) { + f->e = 0; + for (;;) + l(); +} +int main() { + for (; j; f = 0) { + struct g *n = 0; + char o = n->h.c; + } + l(); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-11.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-11.c new file mode 100644 index 0000000000000000000000000000000000000000..3e42aa84a3f801e2a94abbdd671abb5b06bfb292 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-11.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */ + +struct a { + int b; + double c; +}; +struct d { + struct a e; +}; +int f; +int main() { + _Bool g; + struct d **h = 0; + g = *h += f; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-12.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-12.c new file mode 100644 index 0000000000000000000000000000000000000000..d434f9fe0036335efbe1e9c33c36a7faeb6a615f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-12.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */ + +struct foo { + long element1; + long element2; +}; + +struct goo { + struct foo element_foo; +}; + +struct goo g1; + +void func () { + struct foo (*local)[] = 0; + long idx; + (g1).element_foo = (*local)[idx]; +} + +struct foo g2; +int main () { + func (); + g2 = g1.element_foo; + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-2.c new file mode 100644 index 0000000000000000000000000000000000000000..d7ab7d21c6270f8eb3d63a9b465252d2ca570229 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-2.c @@ -0,0 +1,29 @@ +// { dg-do run } + +#include + +struct a +{ + int t; + int t1; +}; + +__attribute__((noinline)) int f(int i, int j) +{ + struct a *t; + struct a t1 = {i, j}; + t = &t1; + auto int g(void) __attribute__((noinline)); + int g(void) + { + return t->t + t->t1; + } + return g(); +} + +int main() +{ + assert (f(1, 2) == 3); +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 2" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-3.c new file mode 100644 index 0000000000000000000000000000000000000000..9e5b192eb02d43e0ab22e20664fef9ad0d27fd59 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-3.c @@ -0,0 +1,28 @@ +// { dg-do compile } +// { dg-options "-O3 -flto-partition=one -fipa-struct-reorg -fdump-ipa-all -fwhole-program" } + +#include +typedef struct { + long laststart_offset; + unsigned regnum; +} compile_stack_elt_t; +typedef struct { + compile_stack_elt_t *stack; + unsigned size; +} compile_stack_type; +__attribute__((noinline)) void f (const char *p, const char *pend, int c) +{ + compile_stack_type compile_stack; + while (p != pend) + if (c) + compile_stack.stack = realloc (compile_stack.stack, + (compile_stack.size << 1) + * sizeof (compile_stack_elt_t)); +} + +int main() +{ + f (NULL, NULL, 1); +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-4.c new file mode 100644 index 0000000000000000000000000000000000000000..27b4b56e0d296724e3189b8b0170775e6c2fb816 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-4.c @@ -0,0 +1,59 @@ +/* { dg-do run } */ + +extern void abort (void); + +struct S +{ + int b; + int *c; +}; +static int d, e; + +static struct S s; + +static int * +__attribute__((noinline, const)) +foo (void) +{ + return &s.b; +} + +int * +__attribute__((noinline)) +bar (int **f) +{ + s.c = &d; + *f = &e; + /* As nothing ever takes the address of any int * field in struct S, + the write to *f can't alias with the s.c field. */ + return s.c; +} + +int +__attribute__((noinline)) +baz (int *x) +{ + s.b = 1; + *x = 4; + /* Function foo takes address of an int field in struct S, + so *x can alias with the s.b field (and it does in this testcase). */ + return s.b; +} + +int +__attribute__((noinline)) +t (void) +{ + int *f = (int *) 0; + return 10 * (bar (&f) != &d) + baz (foo ()); +} + +int +main (void) +{ + if (t () != 4) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in struct split." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-5.c new file mode 100644 index 0000000000000000000000000000000000000000..273baa9a368c43c70bb280e68aaecc44dd9e960a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-5.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-flto -fno-use-linker-plugin" } */ + +struct D +{ + int n; + int c [8]; +}; + +struct A +{ + int i; + char *p; +}; + +struct B +{ + struct A *a; + struct D *d; +}; + +int dtInsert1 (struct B *b) +{ + struct A a = { 0, 0 }; + struct D *d; + b->a = &a; + d = b->d; + &d->c [d->n]; + return 0; +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-6.c new file mode 100644 index 0000000000000000000000000000000000000000..455f9b501d66c68780db79ae563963db093f3216 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-6.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-flto -fno-use-linker-plugin" } */ + +typedef struct basic_block_def *basic_block; +typedef struct gimple_seq_node_d *gimple_seq_node; +typedef struct gimple_seq_d *gimple_seq; +typedef struct +{ + gimple_seq_node ptr; + gimple_seq seq; + basic_block bb; +} gimple_stmt_iterator; +typedef void *gimple; +extern void exit(int); +struct gimple_seq_node_d +{ + gimple stmt; + struct gimple_seq_node_d *next; +}; +struct gimple_seq_d +{ +}; +static __inline__ gimple_stmt_iterator +gsi_start (gimple_seq seq) +{ + gimple_stmt_iterator i; + i.seq = seq; + return i; +} +static __inline__ unsigned char +gsi_end_p (gimple_stmt_iterator i) +{ + return i.ptr == ((void *)0); +} +static __inline__ void +gsi_next (gimple_stmt_iterator *i) +{ + i->ptr = i->ptr->next; +} +static __inline__ gimple +gsi_stmt (gimple_stmt_iterator i) +{ + return i.ptr->stmt; +} +void +c_warn_unused_result (gimple_seq seq) +{ + gimple_stmt_iterator i; + for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i)) + { + gimple g = gsi_stmt (i); + if (!g) exit(0); + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-7.c new file mode 100644 index 0000000000000000000000000000000000000000..afc0bd86ca5aba475bbe1de806f3ce06cc7228a5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-7.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +#include +#include + +struct gki_elem { + char *key; + int idx; +}; + +typedef struct { + struct gki_elem *table; + + int primelevel; + int nhash; + int nkeys; +} GKI; + +void * +sre_malloc(size_t size) +{ + void *ptr = malloc (size); + return ptr; +} + +__attribute__((noinline)) int +GKIStoreKey(GKI *hash) +{ + hash->table = sre_malloc(sizeof(struct gki_elem)); +} + +int +main () +{ + GKI *hash = malloc (sizeof(GKI)); + GKIStoreKey(hash); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-8.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-8.c new file mode 100644 index 0000000000000000000000000000000000000000..9bcfaf3681b16e913c367f0349cf69c02c5da9e2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-8.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +#include +#include +#include + +typedef struct { + unsigned char blue; + unsigned char green; +} Pixel; + +typedef struct { + unsigned short colormaplength; + Pixel *colormapdata; +} TargaImage; + +TargaImage *img; + +int main() { + img = (TargaImage *) malloc( sizeof(TargaImage) ); + if (img->colormaplength > 0) { + img->colormapdata = (Pixel *) malloc(sizeof(Pixel) * img->colormaplength); + memset(img->colormapdata, 0, (sizeof(Pixel) * img->colormaplength) ); + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-9.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-9.c new file mode 100644 index 0000000000000000000000000000000000000000..052f4e3bdc180d0c241cfae8d5f3f2a065e040ca --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/struct_reorg-9.c @@ -0,0 +1,54 @@ +/* { dg-do run } */ + +extern void abort(void); + +struct packed_ushort { + unsigned short ucs; +} __attribute__((packed)); + +struct source { + int pos, length; +}; + +static int flag; + +static void __attribute__((noinline)) fetch(struct source *p) +{ + p->length = 128; +} + +static struct packed_ushort __attribute__((noinline)) next(struct source *p) +{ + struct packed_ushort rv; + + if (p->pos >= p->length) { + if (flag) { + flag = 0; + fetch(p); + return next(p); + } + flag = 1; + rv.ucs = 0xffff; + return rv; + } + rv.ucs = 0; + return rv; +} + +int main(void) +{ + struct source s; + int i; + + s.pos = 0; + s.length = 0; + flag = 0; + + for (i = 0; i < 16; i++) { + struct packed_ushort rv = next(&s); + if ((i == 0 && rv.ucs != 0xffff) + || (i > 0 && rv.ucs != 0)) + abort(); + } + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_global_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_global_array.c new file mode 100644 index 0000000000000000000000000000000000000000..9e0f84da8cab77626c07fcbd287bc798fd5bdb20 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_global_array.c @@ -0,0 +1,29 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#define N 1000 +str_t A[N]; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_global_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_global_var.c new file mode 100644 index 0000000000000000000000000000000000000000..c868347e33f1017d0e921fa4bfd93837d4cb47fa --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_global_var.c @@ -0,0 +1,42 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +str_t *p; + +int +main () +{ + int i, sum; + + p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].a = p[i].b + 1; + + for (i = 0; i < N; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_local_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_local_array.c new file mode 100644 index 0000000000000000000000000000000000000000..185ff3125ee06f1feea3eb93c1c829c97337dc98 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_local_array.c @@ -0,0 +1,37 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i; + str_t A[N]; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_local_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_local_var.c new file mode 100644 index 0000000000000000000000000000000000000000..6294fb2a22280f7b6eff205828502210a64c6ccf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_local_var.c @@ -0,0 +1,40 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i, sum; + + str_t * p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].a = p[i].b + 1; + + for (i = 0; i < N; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_single_str_global.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_single_str_global.c new file mode 100644 index 0000000000000000000000000000000000000000..3ca4e0e7180740ea4edf85a9a98199a88adb510b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_prof_single_str_global.c @@ -0,0 +1,31 @@ +#include +typedef struct +{ + int a; + int b; +}str_t; + +#define N 3 + +str_t str; + +int +main () +{ + int i; + int res = 1<<(1< + +typedef struct +{ + int a; + float b; +}str_t1; + +typedef struct +{ + int c; + float d; +}str_t2; + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +str_t1 *p1; +str_t2 *p2; +int num; + +void +foo (void) +{ + int i; + + for (i=0; i < num; i++) + p2[i].c = 2; +} + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + p1 = malloc (num * sizeof (str_t1)); + p2 = malloc (num * sizeof (str_t2)); + + if (p1 == NULL || p2 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + foo (); + + for (i = 0; i < num; i++) + if (p1[i].a != 1 || p2[i].c != 2) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 2" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_ratio_cold_str.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_ratio_cold_str.c new file mode 100644 index 0000000000000000000000000000000000000000..afa145a5722eb0b1f9f22db6d0b70fe417758d18 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/w_ratio_cold_str.c @@ -0,0 +1,43 @@ +#include +typedef struct +{ + int a; + int b; +}str_t1; + +typedef struct +{ + float a; + float b; +}str_t2; + +#define N1 1000 +#define N2 100 +str_t1 A1[N1]; +str_t2 A2[N2]; + +int +main () +{ + int i; + + for (i = 0; i < N1; i++) + A1[i].a = 0; + + for (i = 0; i < N2; i++) + A2[i].a = 0; + + for (i = 0; i < N1; i++) + if (A1[i].a != 0) + abort (); + + for (i = 0; i < N2; i++) + if (A2[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* Arrays are not handled. */ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_array_field.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_array_field.c new file mode 100644 index 0000000000000000000000000000000000000000..7fa6ae27521d42afc876a437181879c8e88bcf85 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_array_field.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct basic +{ + int a; + int b[10]; +} type_struct; + +type_struct *str1; + +int main() +{ + int i; + + str1 = malloc (10 * sizeof (type_struct)); + + for (i=0; i<=9; i++) + str1[i].a = str1[i].b[0]; + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_array_through_pointer.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_array_through_pointer.c new file mode 100644 index 0000000000000000000000000000000000000000..b3bde58365a7843eaaf6ce7a4bd438dd2765f667 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_array_through_pointer.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i; + str_t A[N]; + str_t *p = A; + + for (i = 0; i < N; i++) + p[i].a = 0; + + for (i = 0; i < N; i++) + if (p[i].a != 0) + abort (); + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_double_malloc.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_double_malloc.c new file mode 100644 index 0000000000000000000000000000000000000000..f2bb82b94aa52f158eecadf3e5d70ca8774bdfe1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_double_malloc.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include + +typedef struct test_struct +{ + int a; + int b; +} type_struct; + +typedef type_struct **struct_pointer2; + +struct_pointer2 str1; + +int main() +{ + int i, j; + + str1 = malloc (2 * sizeof (type_struct *)); + + for (i = 0; i <= 1; i++) + str1[i] = malloc (2 * sizeof (type_struct)); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_empty_str.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_empty_str.c new file mode 100644 index 0000000000000000000000000000000000000000..0685cf8fe747c1926240328069b58f99967fd4e6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_empty_str.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include + +struct S { int a; struct V *b; }; +typedef struct { int c; } T; +typedef struct { int d; int e; } U; + +void * +fn (void *x) +{ + return x; +} + +int +foo (struct S *s) +{ + T x; + + T y = *(T *)fn (&x); + return y.c; +} + +int +bar (struct S *s) +{ + U x; + + U y = *(U *)fn (&x); + return y.d + s->a; +} + +int +main () +{ + struct S s; + + foo(&s) + bar (&s); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform in struct split" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_arg_to_local.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_arg_to_local.c new file mode 100644 index 0000000000000000000000000000000000000000..1a0a5a9c6d3c337b83176bc66146b8197ff1c977 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_arg_to_local.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include +struct str +{ + int a; + float b; +}; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +foo (struct str * p_str) +{ + static int sum = 0; + + sum = sum + p_str->a; + return sum; +} + +int +main () +{ + int i, sum; + struct str * p = malloc (N * sizeof (struct str)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + sum = foo (p+i); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_replace_type.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_replace_type.c new file mode 100644 index 0000000000000000000000000000000000000000..d0a7b505eeeb9270a9af8a0c71b97d631c4e48b7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_replace_type.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ + +#include + +struct AngleDef +{ + double K; + double th0; +}; +typedef struct AngleDef angldef; + +struct bndangdihe +{ + int nbond; + int nangl; + int ndihe; +}; +typedef struct bndangdihe bah; + +struct ambprmtop +{ + double *AnglK; + double *AnglEq; + bah nBAH; + angldef *AParam; + char source[512]; + char eprulesource[512]; +}; +typedef struct ambprmtop prmtop; + +static void OrderBondParameters (prmtop *tp) +{ + int i; + tp->AParam = (angldef *)malloc (tp->nBAH.nangl * sizeof (angldef)); + for (i = 0; i < tp->nBAH.nangl; i++) + { + tp->AParam[i].K = tp->AnglK[i]; + tp->AParam[i].th0 = tp->AnglEq[i]; + } +} + +void main () +{ + prmtop *tp = (prmtop *)malloc (100 * sizeof (prmtop)); + OrderBondParameters (tp); +} + +/*---------------------------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform in struct split." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_return-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_return-1.c new file mode 100644 index 0000000000000000000000000000000000000000..d0dce8b536f182b6595368c499f69e1528845d40 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_return-1.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-ipa-sra" } */ + +#include + +struct A { + int d; + int d1; +}; + +struct A a; + +struct A *foo () __attribute__((noinline)); +struct A *foo () +{ + a.d = 5; + return &a; +} + +int +main () +{ + a.d = 0; + foo (); + + if (a.d != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped. .Type escapes via a return" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_return.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_return.c new file mode 100644 index 0000000000000000000000000000000000000000..71167182d50a919da1cce2ff306b493fe3de038d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_return.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-ipa-sra" } */ + +#include + +struct A { + int d; +}; + +struct A a; + +struct A foo () __attribute__((noinline)); +struct A foo () +{ + a.d = 5; + return a; +} + +int +main () +{ + a.d = 0; + foo (); + + if (a.d != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped: \"Type escapes via a return" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_str_init.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_str_init.c new file mode 100644 index 0000000000000000000000000000000000000000..74fa11f3940cabafe7ffdbeec46f54cb883ea499 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_str_init.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + int b; +}str_t; + +#define N 2 + +str_t A[2] = {{1,1},{2,2}}; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + A[i].b = A[i].a; + + for (i = 0; i < N; i++) + if (A[i].b != A[i].a) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_array.c new file mode 100644 index 0000000000000000000000000000000000000000..9533538c47c0940c795048d5d374d93bb792e0ef --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_array.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#define N 1000 + +typedef struct +{ + str_t A[N]; + int c; +}str_with_substr_t; + +str_with_substr_t a; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + a.A[i].b = 0; + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_pointer.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_pointer.c new file mode 100644 index 0000000000000000000000000000000000000000..baf617816d6cec401e3e42d07d0841a58b7a8437 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_pointer.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +typedef struct +{ + str_t * sub_str; + int c; +}str_with_substr_t; + +int foo; + +int +main (void) +{ + int i; + str_with_substr_t A[N]; + str_t a[N]; + + for (i=0; i < N; i++) + A[i].sub_str = &(a[i]); + + for (i=0; i < N; i++) + A[i].sub_str->a = 5; + + foo = A[56].sub_str->a; + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped...Type is used in an array" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_value.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_value.c new file mode 100644 index 0000000000000000000000000000000000000000..33fce3b235048a331ea9e70a62cc124e780c958e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_escape_substr_value.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + + +typedef struct +{ + str_t sub_str; + int c; +}str_with_substr_t; + +int +main () +{ + int i; + str_with_substr_t A[N]; + + for (i = 0; i < N; i++) + A[i].sub_str.a = 5; + + for (i = 0; i < N; i++) + if (A[i].sub_str.a != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped...Type is used in an array" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_global_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_global_array.c new file mode 100644 index 0000000000000000000000000000000000000000..100a93868e561735e248422be14f4899e7a26d39 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_global_array.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#define N 1000 +str_t A[N]; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_global_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_global_var.c new file mode 100644 index 0000000000000000000000000000000000000000..669d0b886ac58636c85992976c9750baf7b89bab --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_global_var.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +str_t *p; + +int +main () +{ + int i, sum; + + p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].b = p[i].a + 1; + + for (i = 0; i < N; i++) + if (p[i].b != p[i].a + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_local_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_local_array.c new file mode 100644 index 0000000000000000000000000000000000000000..ce6c1544c203c5c1ea280df6fab323f6fcd93d00 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_local_array.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i; + str_t A[N]; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_local_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_local_var.c new file mode 100644 index 0000000000000000000000000000000000000000..eca2ebf32ec52a370907d53bdd6757df57515827 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_local_var.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i, sum; + + str_t * p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].b = p[i].a + 1; + + for (i = 0; i < N; i++) + if (p[i].b != p[i].a + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_malloc_size_var-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_malloc_size_var-1.c new file mode 100644 index 0000000000000000000000000000000000000000..6f8f94d7d5937054015b46ff1e8619b06d79f7fb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_malloc_size_var-1.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + long i, num; + + num = rand(); + num = num > N ? N : num; + str_t * p = malloc (num * sizeof (str_t)); + + if (p == 0) + return 0; + + for (i = 1; i <= num; i++) + p[i-1].b = i; + + for (i = 1; i <= num; i++) + p[i-1].a = p[i-1].b + 1; + + for (i = 0; i < num; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_malloc_size_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_malloc_size_var.c new file mode 100644 index 0000000000000000000000000000000000000000..2ca729d1f5daa9f9d1bf5645bc9c7855b2ab3689 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_malloc_size_var.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i, num; + + num = rand(); + num = num > N ? N : num; + str_t * p = malloc (num * sizeof (str_t)); + + if (p == 0) + return 0; + + for (i = 0; i < num; i++) + p[i].b = i; + + for (i = 0; i < num; i++) + p[i].a = p[i].b + 1; + + for (i = 0; i < num; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_mult_field_peeling.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_mult_field_peeling.c new file mode 100644 index 0000000000000000000000000000000000000000..6000b2919ab460dfde6e6a29bfca4942f2c07f61 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_mult_field_peeling.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; + int c; + float d; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 1600 +#define N 100 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 100 +#endif + +int +main () +{ + int i; + str_t *p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].a = 5; + + for (i = 0; i < N; i++) + if (p[i].a != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* Two more fields structure is not splitted. */ +/* { dg-final { scan-ipa-dump "No structures to transform in struct split." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_single_str_global.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_single_str_global.c new file mode 100644 index 0000000000000000000000000000000000000000..f4a10340912d0c3575c7b1eb1e6c4e075647f7f4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_single_str_global.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + int b; +}str_t; + +#define N 3 + +str_t str; + +int +main () +{ + int i; + int res = 1<<(1< +typedef struct +{ + int a; + int b; +}str_t; + +#define N 3 + +int +main () +{ + int i; + int res = 1<<(1< +typedef struct +{ + int a; + int *b; +}str_t; + +#define N 3 + +str_t *p; + +int +main () +{ + str_t str; + int i; + int res = 1 << (1 << N); + p = &str; + str.a = 2; + + p->b = &(p->a); + + for (i=0; i < N; i++) + p->a = *(p->b)*(*(p->b)); + + if (p->a != res) + abort (); + + /* POSIX ignores all but the 8 low-order bits, but other + environments may not. */ + return (p->a & 255); +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped...Type escapes a cast to a different" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_two_strs.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_two_strs.c new file mode 100644 index 0000000000000000000000000000000000000000..bc8eacc779ed2b0dbeb10587a4b620fb9c322bc2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/struct/wo_prof_two_strs.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include + +typedef struct +{ + int a; + float b; +}str_t1; + +typedef struct +{ + int c; + float d; +}str_t2; + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +str_t1 *p1; +str_t2 *p2; +int num; + +void +foo (void) +{ + int i; + + for (i=0; i < num; i++) + p2[i].c = 2; +} + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + p1 = malloc (num * sizeof (str_t1)); + p2 = malloc (num * sizeof (str_t2)); + + if (p1 == NULL || p2 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + foo (); + + for (i = 0; i < num; i++) + if (p1[i].a != 1 || p2[i].c != 2) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform in struct split is 2" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/torture/dg-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/torture/dg-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..94c48fc0003210005f99a63041bffba3169ab7f9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/torture/dg-torture.exp @@ -0,0 +1,7 @@ +# This harness is for tests that should be run at all optimisation levels. + +load_lib gcc-dg.exp + +dg-init +gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c $srcdir/c-c++-common/torture/*.c]] "" "" +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/torture/pr94949.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/torture/pr94949.c new file mode 100755 index 0000000000000000000000000000000000000000..6182d77b3cdaca4a62f7f457f2413bce3f9ced3e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/torture/pr94949.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fallow-store-data-races" } */ + +static int x = 1; +static volatile int y = -1; +int +main() +{ + for (int i = 0; i < 128; ++i) + { + if (i == y) + x = i; + } + if (x != 1) + __builtin_abort (); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/andnot-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/andnot-2.c new file mode 100644 index 0000000000000000000000000000000000000000..e0955ce3ffd9d1cf9bd47e6a5da5b7d5e32c1047 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/andnot-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop3-raw -w -Wno-psabi" } */ + +typedef long vec __attribute__((vector_size(16))); +vec f(vec x){ + vec y = x < 10; + return y & (y == 0); +} + +/* { dg-final { scan-tree-dump-not "_expr" "forwprop3" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-1.c new file mode 100644 index 0000000000000000000000000000000000000000..27b69b0e91cbdd4b7203ea5a8bf2f34d3bf52b5f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (++len != len_limit) + if (pb[len] != cur[len]) + break; + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 1 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-2.c new file mode 100644 index 0000000000000000000000000000000000000000..d102364f2ca3b77cb5686aec27692ab3f2a70868 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-2.c @@ -0,0 +1,90 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define EMPTY_HASH_VALUE 0 +#define my_min(x, y) ((x) < (y) ? (x) : (y)) +#define true 1 + +typedef struct { + uint32_t len; + uint32_t dist; +} lzma_match; + + +lzma_match * +func ( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size, + lzma_match *matches, + uint32_t len_best) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (true) + { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) + { + *ptr0 = EMPTY_HASH_VALUE; + *ptr1 = EMPTY_HASH_VALUE; + return matches; + } + + uint32_t *const pair = son + ((cyclic_pos - delta + (delta > cyclic_pos ? cyclic_size : 0)) << 1); + + const uint8_t *const pb = cur -delta; + uint32_t len = my_min(len0, len1); + + if (pb[len] == cur[len]) + { + while (++len != len_limit) + if (pb[len] != cur[len]) + break; + + if (len_best < len) + { + len_best = len; + matches->len = len; + matches->dist = delta - 1; + ++matches; + + if (len == len_limit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return matches; + } + } + } + + if (pb[len] < cur[len]) + { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } + else + { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 1 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-3.c new file mode 100644 index 0000000000000000000000000000000000000000..52dd6b02b8f11c935123b8bf3ab80cec04cdd64b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-3.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len != len_limit) + { + if (pb[len] != cur[len]) + break; + len = len + 1; + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 1 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-4.c new file mode 100644 index 0000000000000000000000000000000000000000..d3185d32601486280c99d64260d3aaf5bade05a5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-4.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len != len_limit) + { + if (pb[len] != cur[len]) + break; + len = len + 2; + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-5.c new file mode 100644 index 0000000000000000000000000000000000000000..9743dc6231fbcbf255bb641c094cc27ef18c0c41 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-5.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (++len != len_limit) + if (pb[len] != cur[len-1]) + break; + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-6.c new file mode 100644 index 0000000000000000000000000000000000000000..2323d5bf796afcfa47207610b581f23ec484b791 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-6.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len++ != len_limit) + if (pb[len] != cur[len]) + break; + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-7.c new file mode 100644 index 0000000000000000000000000000000000000000..33db62fa420094d60593f30f10b2f12a78e81dca --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-7.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len != len_limit) + { + len = len + 1; + if (pb[len] != cur[len]) + break; + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-8.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-8.c new file mode 100644 index 0000000000000000000000000000000000000000..8c96d24a120b2cc6b503a638547c7c07680dd000 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/awiden-compare-8.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (++len != len_limit) + { + if (pb[len] != cur[len]) + { + len = len - 1; + break; + } + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-1.c new file mode 100644 index 0000000000000000000000000000000000000000..6494636477cc415612b6c339d218118d0fbe5901 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-1.c @@ -0,0 +1,67 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-do run { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -ftree-slp-transpose-vectorize -fdump-tree-ldist-all-details -save-temps" } */ + +#include +#include + +static unsigned inline abs2 (unsigned a) +{ + unsigned s = ((a>>15)&0x10001)*0xffff; + return (a+s)^s; +} + +int foo (unsigned char *oxa, int ia, unsigned char *oxb, int ib) +{ + unsigned tmp[4][4]; + unsigned a0, a1, a2, a3; + int sum = 0; + for (int i = 0; i < 4; i++, oxa += ia, oxb += ib) + { + a0 = (oxa[0] - oxb[0]) + ((oxa[4] - oxb[4]) << 16); + a1 = (oxa[1] - oxb[1]) + ((oxa[5] - oxb[5]) << 16); + a2 = (oxa[2] - oxb[2]) + ((oxa[6] - oxb[6]) << 16); + a3 = (oxa[3] - oxb[3]) + ((oxa[7] - oxb[7]) << 16); + int t0 = a0 + a1; + int t1 = a0 - a1; + int t2 = a2 + a3; + int t3 = a2 - a3; + tmp[i][0] = t0 + t2; + tmp[i][2] = t0 - t2; + tmp[i][1] = t1 + t3; + tmp[i][3] = t1 - t3; + } + for (int i = 0; i < 4; i++) + { + int t0 = tmp[0][i] + tmp[1][i]; + int t1 = tmp[0][i] - tmp[1][i]; + int t2 = tmp[2][i] + tmp[3][i]; + int t3 = tmp[2][i] - tmp[3][i]; + a0 = t0 + t2; + a2 = t0 - t2; + a1 = t1 + t3; + a3 = t1 - t3; + sum += abs2 (a0) + abs2 (a1) + abs2 (a2) + abs2 (a3); + } + return (((unsigned short) sum) + ((unsigned) sum >>16)) >> 1; +} + +int main () +{ + unsigned char oxa[128] = {0}; + unsigned char oxb[128] = {0}; + for (int i = 0; i < 128; i++) + { + oxa[i] += i * 3; + oxb[i] = i * 2; + } + int sum = foo (oxa, 16, oxb, 32); + if (sum != 736) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "Insertion done: 4 temp arrays inserted" 1 "ldist" } } */ +/* { dg-final { scan-tree-dump-times "distributed: split to 2 loops" 1 "ldist" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-2.c new file mode 100644 index 0000000000000000000000000000000000000000..1b50fd27d6a03a9a512e6acd65fcfe0a59760061 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -ftree-slp-transpose-vectorize -fdump-tree-ldist-all-details" } */ + +unsigned a0[4], a1[4], a2[4], a3[4]; + +void foo (unsigned char *oxa, int ia, unsigned char *oxb, int ib) +{ + for (int i = 0; i < 4; i++, oxa += ia, oxb += ib) + { + a0[i] = (oxa[0] - oxb[0]) + ((oxa[4] - oxb[4]) << 16); + a1[i] = (oxa[1] - oxb[1]) + ((oxa[5] - oxb[5]) << 16); + a2[i] = (oxa[2] - oxb[2]) + ((oxa[6] - oxb[6]) << 16); + a3[i] = (oxa[3] - oxb[3]) + ((oxa[7] - oxb[7]) << 16); + } +} + +/* { dg-final { scan-tree-dump-times "Loop 1 not distributed." 1 "ldist" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-3.c new file mode 100644 index 0000000000000000000000000000000000000000..94b992b050dcc005da2ef8c24d570b186e9c7b87 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/ins-ldist-3.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -ftree-slp-transpose-vectorize -fdump-tree-ldist-all-details" } */ + +unsigned a0[4], a1[4], a2[4], a3[4]; + +void foo (unsigned char *oxa, int ia, unsigned char *oxb, int ib) +{ + for (int i = 0; i < 4; i++, oxa += ia, oxb += ib) + { + a0[i] = ((oxa[0] - oxb[0]) + ((oxa[4] - oxb[4]) << 16)) + 1; + a1[i] = ((oxa[1] - oxb[1]) + ((oxa[5] - oxb[5]) << 16)) - 2; + a2[i] = ((oxa[2] - oxb[2]) + ((oxa[6] - oxb[6]) << 16)) * 3; + a3[i] = ((oxa[3] - oxb[3]) + ((oxa[7] - oxb[7]) << 16)) / 4; + } +} + +/* { dg-final { scan-tree-dump-times "Insertion done: 4 temp arrays inserted" 1 "ldist" } } */ +/* { dg-final { scan-tree-dump-times "Insertion removed" 1 "ldist" } } */ +/* { dg-final { scan-tree-dump-times "Loop 1 not distributed." 1 "ldist" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-condition-fail.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-condition-fail.c new file mode 100644 index 0000000000000000000000000000000000000000..05b4ceddead066ed3b78b4b60300b2f0b56e0206 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-condition-fail.c @@ -0,0 +1,85 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -march=armv8.1-a -floop-crc -fdump-tree-loop_crc-details" } */ + +#include +#include +typedef unsigned long ulg; +typedef unsigned char uch; + +static const ulg crc_32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +ulg updcrc (s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + if (n) + if (n) do { + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + } while (--n || c != 0) ; + } + crc = c; +exit1: + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} +/* { dg-final { scan-tree-dump-times "Wrong loop form for crc matching." 1 "loop_crc"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-form-fail-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-form-fail-2.c new file mode 100644 index 0000000000000000000000000000000000000000..8002540bb3538a784a6fdcbb1b2ab7f2f599b472 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-form-fail-2.c @@ -0,0 +1,90 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -march=armv8.1-a -floop-crc -fdump-tree-loop_crc-details" } */ + +#include +#include +typedef unsigned long ulg; +typedef unsigned char uch; + +static const ulg crc_32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +int test[5] = {0}; + +ulg updcrc (s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + if (n) + if (n) do { + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + } while (--n) ; + } + do { + c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); + test[c%5] = c; + } while (--n) ; + crc = c; + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} +/* { dg-final { scan-tree-dump-times "Table check fail. not only single array is read." 1 "loop_crc"} } */ +/* { dg-final { scan-tree-dump-times "Wrong crc table for crc matching." 1 "loop_crc"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-form-fail.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-form-fail.c new file mode 100644 index 0000000000000000000000000000000000000000..a95c6c65774ecaa6e90905b5d779eb159083ccf1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-loop-form-fail.c @@ -0,0 +1,112 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -march=armv8.1-a -floop-crc -fdump-tree-loop_crc-details" } */ + +#include +#include +typedef unsigned long ulg; +typedef unsigned char uch; + +static const ulg crc_32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +/* check when the loop have a innor loop, should fail. */ +ulg updcrc (s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + if (n) + do { + c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); + for (int i = 0; i < 5; i++) { + c++; + } + + } while (--n); + } + crc = c; + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} + +/* check when the loop have a second backedge, should fail. */ +ulg updcrc1(s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + if (n) + do { + c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); + } while (--n || c != 0) ; + } + crc = c; + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} +/* { dg-final { scan-tree-dump-times "Table check fail. not only single array is read." 1 "loop_crc"} } */ +/* { dg-final { scan-tree-dump-times "Wrong crc table for crc matching." 1 "loop_crc"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-sucess.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-sucess.c new file mode 100644 index 0000000000000000000000000000000000000000..f1e415339626bf516aede9d59d401ea0345638e3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-sucess.c @@ -0,0 +1,83 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -march=armv8.1-a -floop-crc -fdump-tree-loop_crc-details" } */ + +#include +#include +typedef unsigned long ulg; +typedef unsigned char uch; + +static const ulg crc_32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +ulg updcrc (s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + if (n) do { + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + } while (--n); + } + crc = c; + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} +/* { dg-final { scan-tree-dump-times "The 1th loop form is success matched,and the loop can be optimized." 1 "loop_crc"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-table-check-fail.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-table-check-fail.c new file mode 100644 index 0000000000000000000000000000000000000000..bf7ab49e99a2bad5c0514fa642225000d2bfa145 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/loop-crc-table-check-fail.c @@ -0,0 +1,114 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -march=armv8.1-a -floop-crc -fdump-tree-loop_crc-details" } */ + +#include +#include +typedef unsigned long ulg; +typedef unsigned char uch; + +static const ulg crc_32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf1L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +int test[5] = {0}; + +/* check when the loop is doing more then 1 array read or writing an array, both should fail. */ +ulg updcrc (s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + if (n) + do { + c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8) * test[c%5]; + } while (--n) ; + } + do { + c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); + test[c%5] = c; + } while (--n) ; + crc = c; + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} + +/* check when the loop is not working on a correct crc_table. should fail. */ +ulg updcrc1(s, n) + uch *s; /* pointer to bytes to pump through */ + unsigned n; /* number of bytes in s[] */ +{ + register ulg c; /* temporary variable */ + + static ulg crc = (ulg)0xffffffffL; /* shift register contents */ + + if (s == NULL) { + c = 0xffffffffL; + } else { + c = crc; + if (n) + do { + c = crc_32_tab[(c ^ (*s++)) & 0xff] ^ (c >> 8); + } while (--n) ; + } + crc = c; + return c ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} +/* { dg-final { scan-tree-dump-times "Table check fail. not only single array is read." 2 "loop_crc"} } */ +/* { dg-final { scan-tree-dump-times "Wrong crc table for crc matching." 3 "loop_crc"} } */ +/* { dg-final { scan-tree-dump-times "Table check fail. Table not matching." 1 "loop_crc"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-21.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-21.c new file mode 100644 index 0000000000000000000000000000000000000000..9f3d5695728bb3d981a1552f410e6c45dec3a83f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-21.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt4-details" } */ + +int f(unsigned s) +{ + int i; + for (i = 0; i < s; ++i) + ; + + return i; +} + +/* { dg-final { scan-tree-dump "converted to straightline code" "phiopt4" } } */ +/* Make sure we fold the detected MAX. */ +/* { dg-final { scan-tree-dump-not "MAX" "phiopt4" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-22.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-22.c new file mode 100644 index 0000000000000000000000000000000000000000..23b67964401d74d7483f351d8f3666c057436352 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-22.c @@ -0,0 +1,11 @@ +/* PR tree-optimization/97690 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-fold-phiopt -fdump-tree-phiopt2" } */ + +int foo (_Bool d) { return d ? 2 : 0; } +int bar (_Bool d) { return d ? 1 : 0; } +int baz (_Bool d) { return d ? -__INT_MAX__ - 1 : 0; } +int qux (_Bool d) { return d ? 1024 : 0; } + +/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " << " 3 "phiopt2" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-25.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-25.c new file mode 100644 index 0000000000000000000000000000000000000000..c52c92e1d4503fa71dc98669767aebad9ee45f4a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/phi-opt-25.c @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +unsigned short test_bswap16(unsigned short x) +{ + return x ? __builtin_bswap16(x) : 0; +} + +unsigned int test_bswap32(unsigned int x) +{ + return x ? __builtin_bswap32(x) : 0; +} + +unsigned long long test_bswap64(unsigned long long x) +{ + return x ? __builtin_bswap64(x) : 0; +} + +int test_clrsb(int x) +{ + return x ? __builtin_clrsb(x) : (__SIZEOF_INT__*8-1); +} + +int test_clrsbl(long x) +{ + return x ? __builtin_clrsbl(x) : (__SIZEOF_LONG__*8-1); +} + +int test_clrsbll(long long x) +{ + return x ? __builtin_clrsbll(x) : (__SIZEOF_LONG_LONG__*8-1); +} + +#if 0 +/* BUILT_IN_FFS is transformed by match.pd */ +int test_ffs(unsigned int x) +{ + return x ? __builtin_ffs(x) : 0; +} + +int test_ffsl(unsigned long x) +{ + return x ? __builtin_ffsl(x) : 0; +} + +int test_ffsll(unsigned long long x) +{ + return x ? __builtin_ffsll(x) : 0; +} +#endif + +int test_parity(int x) +{ + return x ? __builtin_parity(x) : 0; +} + +int test_parityl(long x) +{ + return x ? __builtin_parityl(x) : 0; +} + +int test_parityll(long long x) +{ + return x ? __builtin_parityll(x) : 0; +} + +int test_popcount(int x) +{ + return x ? __builtin_popcount(x) : 0; +} + +int test_popcountl(long x) +{ + return x ? __builtin_popcountl(x) : 0; +} + +int test_popcountll(long long x) +{ + return x ? __builtin_popcountll(x) : 0; +} + +/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr39612.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr39612.c new file mode 100755 index 0000000000000000000000000000000000000000..884f905148fa36bed754afce069d0a00ef02bb07 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr39612.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-lim2-details -Wuninitialized" } */ + +void foo(int *); +void f2(int dst[3], int R) +{ + int i, inter[2]; + + for (i = 1; i < R; i++) { + if (i & 8) + { + inter[0] = 1; + inter[1] = 1; + } + } + + foo(inter); +} + +/* { dg-final { scan-tree-dump-times "Executing store motion" 2 "lim2" } } */ +/* { dg-final { scan-tree-dump-not " = inter\\\[\[0-1\]\\\];" "lim2" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr89430-7-comp-ref.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr89430-7-comp-ref.c new file mode 100644 index 0000000000000000000000000000000000000000..c35a2afc70b96351a9660bf2f93fff477e1b446c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr89430-7-comp-ref.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cselim-details" } */ + +typedef union { + int i; + float f; +} U; + +int foo(U *u, int b, int i) +{ + u->i = 0; + if (b) + u->i = i; + return u->i; +} + +/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c new file mode 100644 index 0000000000000000000000000000000000000000..f9e66aefb1370be4b6f7ac22ef11b8ce1b90776f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr89430-8-mem-ref-size.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cselim-details" } */ + +int *t; + +int f1 (int tt) +{ + int *t1 = t; + *t1 = -5; + if (*t1 < tt) + *((unsigned *) t1) = 5; + return *t1; +} + +/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr95906.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr95906.c new file mode 100644 index 0000000000000000000000000000000000000000..3d820a58e9303823e146559ad3dfa1e2d714c81e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr95906.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop3-raw -w -Wno-psabi" } */ + +// FIXME: this should further optimize to a MAX_EXPR +typedef signed char v16i8 __attribute__((vector_size(16))); +v16i8 f(v16i8 a, v16i8 b) +{ + v16i8 cmp = (a > b); + return (cmp & a) | (~cmp & b); +} + +/* { dg-final { scan-tree-dump-not "bit_(and|ior)_expr" "forwprop3" } } */ +/* { dg-final { scan-tree-dump-times "vec_cond_expr" 1 "forwprop3" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96232-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96232-2.c new file mode 100644 index 0000000000000000000000000000000000000000..9f51820edfffa35e7bccec012e452b61c3a51880 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96232-2.c @@ -0,0 +1,18 @@ +/* PR tree-optimization/96232 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump " 38 - " "optimized" } } */ +/* { dg-final { scan-tree-dump " \\+ 97;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "PHI <" "optimized" } } */ + +int +foo (_Bool x) +{ + return x ? 37 : 38; +} + +int +bar (_Bool x) +{ + return x ? 98 : 97; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96928-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96928-1.c new file mode 100644 index 0000000000000000000000000000000000000000..88c13806aa56deefa1c38dcd4350ce3aab8d0e1c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96928-1.c @@ -0,0 +1,48 @@ +/* PR tree-optimization/96928 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-fold-phiopt -fdump-tree-phiopt2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ + +int +foo (int a) +{ + if (a < 0) + return ~a; + return a; +} + +int +bar (int a, int b) +{ + if (a < 0) + return ~b; + return b; +} + +unsigned +baz (int a, unsigned int b) +{ + if (a < 0) + return ~b; + return b; +} + +unsigned +qux (int a, unsigned int c) +{ + if (a >= 0) + return ~c; + return c; +} + +int +corge (int a, int b) +{ + if (a >= 0) + return b; + return ~b; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96928.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96928.c new file mode 100644 index 0000000000000000000000000000000000000000..e8fd82fc26ed25d77cdae577cc4fa9b857962525 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr96928.c @@ -0,0 +1,41 @@ +/* PR tree-optimization/96928 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ +/* The following check is done at optimized because a ^ (~b) is rewritten as ~(a^b) + and in the case of match.pd optimizing these ?:, the ~ is moved out already + by the time we get to phiopt2. */ +/* { dg-final { scan-tree-dump-times "\\\^ c_\[0-9]*\\\(D\\\);" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ + +int +foo (int a) +{ + return a < 0 ? ~a : a; +} + +int +bar (int a, int b) +{ + return a < 0 ? ~b : b; +} + +unsigned +baz (int a, unsigned int b) +{ + return a < 0 ? ~b : b; +} + +unsigned +qux (int a, unsigned int c) +{ + return a >= 0 ? ~c : c; +} + +int +corge (int a, int b) +{ + return a >= 0 ? b : ~b; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr97503.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr97503.c new file mode 100644 index 0000000000000000000000000000000000000000..3a3dae6c786feb91e0755c5aced2b28effe47067 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/pr97503.c @@ -0,0 +1,19 @@ +/* PR tree-optimization/97503 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-additional-options "-mbmi -mlzcnt" { target i?86-*-* x86_64-*-* } } */ +/* { dg-final { scan-tree-dump-times "\.CLZ" 2 "optimized" { target { { i?86-*-* x86_64-*-* aarch64-*-* powerpc*-*-* } && lp64 } } } } */ +/* { dg-final { scan-tree-dump-not "__builtin_clz" "optimized" { target { { i?86-*-* x86_64-*-* aarch64-*-* powerpc*-*-*} && lp64 } } } } */ +/* { dg-final { scan-tree-dump-not "PHI <" "optimized" { target { { i?86-*-* x86_64-*-* aarch64-*-* powerpc*-*-*} && lp64 } } } } */ + +int +foo (int x) +{ + return x ? __builtin_clz (x) : 32; +} + +int +bar (unsigned long long x) +{ + return x ? __builtin_clzll (x) : 64; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/split-path-12.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/split-path-12.c new file mode 100644 index 0000000000000000000000000000000000000000..19a130d9bf1f1eb5360ba4f7c12f578e36a5136b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/split-path-12.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsplit-paths -fdump-tree-split-paths-details " } */ + +double +foo(double *d1, double *d2, double *d3, int num, double *ip) +{ + double dmax[3]; + + for (int i = 0; i < num; i++) { + dmax[0] = d1[i] < dmax[0] ? dmax[0] : d1[i]; + dmax[1] = d2[i] < dmax[1] ? dmax[1] : d2[i]; + dmax[2] = d3[i] < dmax[2] ? dmax[2] : d3[i]; + ip[i] = dmax[2]; + } + + return dmax[0] + dmax[1] + dmax[2]; +} + +/* { dg-final { scan-tree-dump "appears to be optimized to a join point for if-convertable half-diamond" "split-paths" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/tree-ssa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/tree-ssa.exp new file mode 100644 index 0000000000000000000000000000000000000000..7d262ffd0fb5965718ed04a60ed757ef7dbbc428 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/tree-ssa/tree-ssa.exp @@ -0,0 +1,36 @@ +# Copyright (C) 1997-2020 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/uaddsub.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/uaddsub.c new file mode 100644 index 0000000000000000000000000000000000000000..96c26d308b4f999c74836948fa7a531bf457d019 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/uaddsub.c @@ -0,0 +1,143 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fuaddsub-overflow-match-all -fdump-tree-optimized" } */ +#include + +typedef unsigned __int128 uint128_t; +typedef struct uint256_t +{ + uint128_t lo; + uint128_t hi; +} uint256_t; + +uint16_t add16 (uint8_t a, uint8_t b) +{ + uint8_t tmp = a + b; + uint8_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint16_t res = overflow; + res <<= 8; + res += tmp; + return res; +} + +uint32_t add32 (uint16_t a, uint16_t b) +{ + uint16_t tmp = a + b; + uint16_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint32_t res = overflow; + res <<= 16; + res += tmp; + return res; +} + +uint64_t add64 (uint32_t a, uint32_t b) +{ + uint32_t tmp = a + b; + uint32_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint64_t res = overflow; + res <<= 32; + res += tmp; + return res; +} + +uint128_t add128 (uint64_t a, uint64_t b) +{ + uint64_t tmp = a + b; + uint64_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint128_t res = overflow; + res <<= 64; + res += tmp; + return res; +} + +uint256_t add256 (uint128_t a, uint128_t b) +{ + uint128_t tmp = a + b; + uint128_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint256_t res; + res.hi = overflow; + res.lo = tmp; + return res; +} + +uint16_t sub16 (uint8_t a, uint8_t b) +{ + uint8_t tmp = a - b; + uint8_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint16_t res = overflow; + res <<= 8; + res += tmp; + return res; +} + +uint32_t sub32 (uint16_t a, uint16_t b) +{ + uint16_t tmp = a - b; + uint16_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint32_t res = overflow; + res <<= 16; + res += tmp; + return res; +} + +uint64_t sub64 (uint32_t a, uint32_t b) +{ + uint32_t tmp = a - b; + uint32_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint64_t res = overflow; + res <<= 32; + res += tmp; + return res; +} + +uint128_t sub128 (uint64_t a, uint64_t b) +{ + uint64_t tmp = a - b; + uint64_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint128_t res = overflow; + res <<= 64; + res += tmp; + return res; +} + +uint256_t sub256 (uint128_t a, uint128_t b) +{ + uint128_t tmp = a - b; + uint128_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint256_t res; + res.hi = overflow; + res.lo = tmp; + return res; +} + +/* { dg-final { scan-tree-dump-times "= .ADD_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "= .SUB_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 5 "optimized" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-1.c new file mode 100644 index 0000000000000000000000000000000000000000..8237a8b9ea3ac6e5f654ff9ee3603fd92a702e46 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-1.c @@ -0,0 +1,53 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include "tree-vect.h" + +#define N 4 +#define M 256 + +int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) +{ + int i = 0; + int sum = 0; + unsigned c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; + for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + c2[i] = pix1[2] - pix2[2]; + c3[i] = pix1[3] - pix2[3]; + c4[i] = pix1[4] - pix2[4]; + c5[i] = pix1[5] - pix2[5]; + c6[i] = pix1[6] - pix2[6]; + c7[i] = pix1[7] - pix2[7]; + } + for (int i = 0; i < N; i++) + { + sum += c0[i] + c1[i] + c2[i] + c3[i] + c4[i] + c5[i] + c6[i] + c7[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned char input1[M]; + unsigned char input2[M]; + int i1 = 16; + int i2 = 8; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 2; + input2[i] = i; + } + int sum = foo (input1, i1, input2, i2); + if (sum != 1264) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-2.c new file mode 100644 index 0000000000000000000000000000000000000000..b01a0410ee9ae1bc1a05a224221d87769c8285bc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-2.c @@ -0,0 +1,50 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-additional-options "-fno-tree-loop-vectorize" } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include "tree-vect.h" + +#define N 8 +#define M 256 + +int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) +{ + int i = 0; + int sum = 0; + unsigned short c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; + for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + c2[i] = pix1[2] - pix2[2]; + c3[i] = pix1[3] - pix2[3]; + } + for (int i = 0; i < N; i++) + { + sum += c0[i] + c1[i] + c2[i] + c3[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned char input1[M]; + unsigned char input2[M]; + int i1 = 5; + int i2 = 4; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 4; + input2[i] = i * 2; + } + int sum = foo (input1, i1, input2, i2); + if (sum != 1440) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-3.c new file mode 100644 index 0000000000000000000000000000000000000000..529581c59b694dde2ddf0f7376fce9a3e5f080a4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-3.c @@ -0,0 +1,54 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-additional-options "-fno-tree-loop-vectorize" } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include "tree-vect.h" + +#define N 4 +#define M 256 + +int foo (unsigned short *pix1, int i_pix1, unsigned short *pix2, int i_pix2) +{ + int i = 0; + int sum = 0; + unsigned c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; + for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + c2[i] = pix1[2] - pix2[2]; + c3[i] = pix1[3] - pix2[3]; + c4[i] = pix1[4] - pix2[4]; + c5[i] = pix1[5] - pix2[5]; + c6[i] = pix1[6] - pix2[6]; + c7[i] = pix1[7] - pix2[7]; + } + for (int i = 0; i < N; i++) + { + sum += c0[i] + c1[i] + c2[i] + c3[i] + c4[i] + c5[i] + c6[i] + c7[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned short input1[M]; + unsigned short input2[M]; + int i1 = 8; + int i2 = 4; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 4; + input2[i] = i; + } + int sum = foo (input1, i1, input2, i2); + if (sum != 1680) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-4.c new file mode 100644 index 0000000000000000000000000000000000000000..0b4adea9b3c7dc8af602a3ff1725905c1b24b403 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-4.c @@ -0,0 +1,53 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include "tree-vect.h" + +#define N 4 +#define M 256 + +int foo (unsigned *pix1, int i_pix1, unsigned *pix2, int i_pix2) +{ + int i = 0; + int sum = 0; + unsigned c0[N], c1[N], c2[N], c3[N], c4[N], c5[N], c6[N], c7[N]; + for (i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + c2[i] = pix1[2] - pix2[2]; + c3[i] = pix1[3] - pix2[3]; + c4[i] = pix1[4] - pix2[4]; + c5[i] = pix1[5] - pix2[5]; + c6[i] = pix1[6] - pix2[6]; + c7[i] = pix1[7] - pix2[7]; + } + for (int i = 0; i < N; i++) + { + sum += c0[i] + c1[i] + c2[i] + c3[i] + c4[i] + c5[i] + c6[i] + c7[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned input1[M]; + unsigned input2[M]; + int i1 = 12; + int i2 = 6; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 7; + input2[i] = i * 3; + } + int sum = foo (input1, i1, input2, i2); + if (sum != 3616) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-5.c new file mode 100644 index 0000000000000000000000000000000000000000..81a248840eb093702a67621b16efdbf44b432e9d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-5.c @@ -0,0 +1,73 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include +#include "tree-vect.h" + +#define N 4 +#define M 256 +#define eps 1e-8 + +double foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) +{ + unsigned a0[N]; + unsigned a1[N]; + unsigned a2[N]; + unsigned a3[N]; + + int b0[N]; + int b1[N]; + int b2[N]; + int b3[N]; + + for (int i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + a0[i] = (pix1[0] - pix2[0]) + ((pix1[4] + pix2[4]) << 16); + a1[i] = (pix1[1] - pix2[1]) + ((pix1[5] + pix2[5]) << 16); + a2[i] = (pix1[2] - pix2[2]) + ((pix1[6] + pix2[6]) << 16); + a3[i] = (pix1[3] - pix2[3]) + ((pix1[7] + pix2[7]) << 16); + } + + for (int i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + b0[i] = (pix1[0] - pix2[0]) + (pix1[4] + pix2[4]); + b1[i] = (pix1[1] - pix2[1]) + (pix1[5] + pix2[5]); + b2[i] = (pix1[2] - pix2[2]) + (pix1[6] + pix2[6]); + b3[i] = (pix1[3] - pix2[3]) + (pix1[7] + pix2[7]); + } + + double sum = 0; + for (int i = 0; i < N; i++) + { + sum += a0[i] + a1[i] + a2[i] + a3[i] + b0[i] + b1[i] + b2[i] + b3[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned char input1[M]; + unsigned char input2[M]; + int i1 = 8; + int i2 = 3; + unsigned char m = 2; + unsigned short n = 12; + float t = 3.0; + double k = 4.2; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 6; + input2[i] = i * 3; + } + double sum = foo (input1, i1, input2, i2); + if (fabs (sum - 78648144) > eps) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +/* { dg-final { scan-tree-dump-times "vectorizable_store for slp transpose" 2 "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-6.c new file mode 100644 index 0000000000000000000000000000000000000000..3e134ac02713c9ef4e18cc7a000a10ed21b49324 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-6.c @@ -0,0 +1,67 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_float } */ +#include +#include +#include +#include "tree-vect.h" + +#define N 4 +#define M 256 +#define eps 1e-8 + +float foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) +{ + unsigned a0[N]; + unsigned a1[N]; + unsigned a2[N]; + unsigned a3[N]; + + float c0[N]; + float c1[N]; + float c2[N]; + float c3[N]; + + for (int i = 0; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + a0[i] = (pix1[0] - pix2[0]) + ((pix1[4] - pix2[4]) << 16); + a1[i] = (pix1[1] - pix2[1]) + ((pix1[5] - pix2[5]) << 16); + a2[i] = (pix1[2] - pix2[2]) + ((pix1[6] - pix2[6]) << 16); + a3[i] = (pix1[3] - pix2[3]) + ((pix1[7] - pix2[7]) << 16); + + c0[i] = (pix1[0] * pix2[0]) + (pix1[4] * pix2[4]); + c1[i] = (pix1[1] * pix2[1]) + (pix1[5] * pix2[5]); + c2[i] = (pix1[2] * pix2[2]) + (pix1[6] * pix2[6]); + c3[i] = (pix1[3] * pix2[3]) + (pix1[7] * pix2[7]); + } + + float sum = 0; + for (int i = 0; i < N; i++) + { + sum += a0[i] + a1[i] + a2[i] + a3[i] + c0[i] + c1[i] + c2[i] + c3[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned char input1[M]; + unsigned char input2[M]; + int i1 = 18; + int i2 = 6; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 4; + input2[i] = i * 2; + } + float sum = foo (input1, i1, input2, i2); + if (fabs (sum - 106041168) > eps) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ +/* { dg-final { scan-tree-dump-times "vectorizable_store for slp transpose" 2 "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-7.c new file mode 100644 index 0000000000000000000000000000000000000000..2074d9aa889433253e46f8c262144c3a564fc90d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-7.c @@ -0,0 +1,53 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-additional-options "-fno-tree-loop-vectorize" } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include "tree-vect.h" + +#define N 16 +#define M 256 + +int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) +{ + int i = 0; + int sum = 0; + unsigned char c0[N], c1[N]; + for (int i = 0; i < N/2; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + } + for (int i = N/2; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + } + for (int i = 0; i < N; i++) + { + sum += c0[i] + c1[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned char input1[M]; + unsigned char input2[M]; + int i1 = 6; + int i2 = 4; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 5; + input2[i] = i * 2; + } + int sum = foo (input1, i1, input2, i2); + if (sum != 3280) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-8.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-8.c new file mode 100644 index 0000000000000000000000000000000000000000..a154f012ace66b353cbe4085ecb47028f56d7e8f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-8.c @@ -0,0 +1,53 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-additional-options "-fno-tree-loop-vectorize" } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include "tree-vect.h" + +#define N 32 +#define M 256 + +int foo (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) +{ + int i = 0; + int sum = 0; + unsigned char c0[N], c1[N]; + for (int i = 0; i < N/2; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + } + for (int i = N/2; i < N; i++, pix1 += i_pix1, pix2 += i_pix2) + { + c0[i] = pix1[0] - pix2[0]; + c1[i] = pix1[1] - pix2[1]; + } + for (int i = 0; i < N; i++) + { + sum += c0[i] + c1[i]; + } + return sum; +} + +int main (int argc, const char* argv[]) +{ + unsigned char input1[M]; + unsigned char input2[M]; + int i1 = 6; + int i2 = 4; + check_vect (); + for (int i = 0; i < M; i++) + { + input1[i] = i * 5; + input2[i] = i * 2; + } + int sum = foo (input1, i1, input2, i2); + if (sum != 7584) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized using transposed version" "slp1" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-9.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-9.c new file mode 100755 index 0000000000000000000000000000000000000000..f20a67c6e78a748ab485e03f723387913f7b1b51 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/transpose-9.c @@ -0,0 +1,56 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-additional-options "-mtune=tsv110 --param=tree-forwprop-perm=1 -fdump-tree-forwprop-details" } */ +/* { dg-require-effective-target vect_int } */ +#include +#include +#include "tree-vect.h" + +typedef unsigned short int sum_t; +typedef unsigned int sum2_t; +typedef long int intptr_t; +typedef unsigned char data; +#define BITS_PER_SUM (8 * sizeof(sum_t)) + +static sum2_t bar(sum2_t a ) +{ + sum2_t s = ((a>>(BITS_PER_SUM-1))&(((sum2_t)1<>BITS_PER_SUM)) >> 1; +} +/* { dg-final { scan-tree-dump "Initial permutations were reduced:" "forwprop4" } } */ +/* { dg-final { scan-tree-dump "Permutations were moved through binary operations:" "forwprop4" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/tree-vect.h b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/tree-vect.h new file mode 100644 index 0000000000000000000000000000000000000000..c4b8144121666cd125176613fd9381a860b4159f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/tree-vect.h @@ -0,0 +1,93 @@ +/* Check if system supports SIMD */ +#include + +#if defined(__i386__) || defined(__x86_64__) +# include "cpuid.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif +extern void abort (void); +extern void exit (int); +#ifdef __cplusplus +} +#endif + +static void +sig_ill_handler (int sig) +{ + exit(0); +} + +static void __attribute__((noinline)) +check_vect (void) +{ + signal(SIGILL, sig_ill_handler); +#if defined(__PAIRED__) + /* 750CL paired-single instruction, 'ps_mul %v0,%v0,%v0'. */ + asm volatile (".long 0x10000032"); +#elif defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(powerpc) + /* Altivec instruction, 'vor %v0,%v0,%v0'. */ + asm volatile (".long 0x10000484"); +#elif defined(__i386__) || defined(__x86_64__) + { + unsigned int a, b, c, d, + want_level, want_b = 0, want_c = 0, want_d = 0; + + /* Determine what instruction set we've been compiled for, and detect + that we're running with it. This allows us to at least do a compile + check for, e.g. SSE4.1 when the machine only supports SSE2. */ +# if defined(__AVX2__) + want_level = 7, want_b = bit_AVX2; +# elif defined(__AVX__) + want_level = 1, want_c = bit_AVX; +# elif defined(__SSE4_2__) + want_level = 1, want_c = bit_SSE4_2; +# elif defined(__SSE4_1__) + want_level = 1, want_c = bit_SSE4_1; +# elif defined(__SSSE3__) + want_level = 1, want_c = bit_SSSE3; +# else + want_level = 1, want_d = bit_SSE2; +# endif + + if (!__get_cpuid_count (want_level, 0, &a, &b, &c, &d) + || ((b & want_b) | (c & want_c) | (d & want_d)) == 0) + exit (0); + } +#elif defined(__sparc__) + asm volatile (".word\t0x81b007c0"); +#elif defined(__arm__) + { + /* On some processors without NEON support, this instruction may + be a no-op, on others it may trap, so check that it executes + correctly. */ + long long a = 0, b = 1; + asm ("vorr %P0, %P1, %P2" + : "=w" (a) + : "0" (a), "w" (b)); + if (a != 1) + exit (0); + } +#elif defined(__mips_msa) + asm volatile ("or.v $w0,$w0,$w0"); +#endif + signal (SIGILL, SIG_DFL); +} + +#if defined (__ARM_FEATURE_SVE) +# if __ARM_FEATURE_SVE_BITS == 0 +# define VECTOR_BITS 1024 +# else +# define VECTOR_BITS __ARM_FEATURE_SVE_BITS +# endif +#else +# define VECTOR_BITS 128 +#endif + +/* Which most of our tests are going to #define for internal use, and + which might be exposed by system headers related to signal.h on some + targets, notably VxWorks. */ +#undef OFFSET + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect-perm-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect-perm-1.c new file mode 100644 index 0000000000000000000000000000000000000000..014fac38e467e647b773ac57b38f9d25936d779c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect-perm-1.c @@ -0,0 +1,45 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -fdump-tree-vect-all-details -save-temps" } */ + +#include +#include + +static unsigned inline abs2 (unsigned a) +{ + unsigned s = ((a>>15)&0x10001)*0xffff; + return (a+s)^s; +} + +int foo (unsigned *a00, unsigned *a11, unsigned *a22, unsigned *a33) +{ + unsigned tmp[4][4]; + unsigned a0, a1, a2, a3; + int sum = 0; + for (int i = 0; i < 4; i++) + { + int t0 = a00[i] + a11[i]; + int t1 = a00[i] - a11[i]; + int t2 = a22[i] + a33[i]; + int t3 = a22[i] - a33[i]; + tmp[i][0] = t0 + t2; + tmp[i][2] = t0 - t2; + tmp[i][1] = t1 + t3; + tmp[i][3] = t1 - t3; + } + for (int i = 0; i < 4; i++) + { + int t0 = tmp[0][i] + tmp[1][i]; + int t1 = tmp[0][i] - tmp[1][i]; + int t2 = tmp[2][i] + tmp[3][i]; + int t3 = tmp[2][i] - tmp[3][i]; + a0 = t0 + t2; + a2 = t0 - t2; + a1 = t1 + t3; + a3 = t1 - t3; + sum += abs2 (a0) + abs2 (a1) + abs2 (a2) + abs2 (a3); + } + return (((unsigned short) sum) + ((unsigned) sum >>16)) >> 1; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 16 "vect" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect-reduc-12.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect-reduc-12.c new file mode 100644 index 0000000000000000000000000000000000000000..913f1ef28dfd0aa2a2cfc0103f758c3cc51b7a77 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect-reduc-12.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -funsafe-math-optimizations -fno-tree-reassoc -ftree-vect-analyze-slp-group" } */ +void f(double *a, double *res, double m) { + double res1, res0; + res1 = 0; + res0 = 0; + for (int i = 0; i < 1000; i+=8) { + res0 += a[i] * m; + res1 += a[i+1] * m; + res0 += a[i+2] * m; + res1 += a[i+3] * m; + res0 += a[i+4] * m; + res1 += a[i+5] * m; + res0 += a[i+6] * m; + res1 += a[i+7] * m; + } + res[0] += res0; + res[1] += res1; +} +/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect.exp new file mode 100644 index 0000000000000000000000000000000000000000..d92e1ba5bad93e3f044a06b3aaf7a9100c08f28e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.dg/vect/vect.exp @@ -0,0 +1,325 @@ +# Copyright (C) 1997-2020 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp +load_lib clearcap.exp + +# Set up flags used for tests that don't specify options. +global DEFAULT_VECTCFLAGS +set DEFAULT_VECTCFLAGS "" + +# Set up a list of effective targets to run vector tests for all supported +# targets. +global EFFECTIVE_TARGETS +set EFFECTIVE_TARGETS "" + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +# Skip these tests for targets that do not support generating vector +# code. Set additional target-dependent vector flags, which can be +# overridden by using dg-options in individual tests. +if ![check_vect_support_and_set_flags] { + return +} + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-ftree-vectorize" "-fno-tree-loop-distribute-patterns" "-fno-vect-cost-model" "-fno-common" + +# Initialize `dg'. +dg-init +clearcap-init + +global VEC_FLAGS +set VEC_FLAGS $DEFAULT_VECTCFLAGS + +global O1_VECTCFLAGS +set O1_VECTCFLAGS $DEFAULT_VECTCFLAGS +lappend O1_VECTCFLAGS "-O1" +lappend O1_VECTCFLAGS "-fdump-tree-vect-details" + +global O_VECTCFLAGS +set O_VECTCFLAGS $DEFAULT_VECTCFLAGS +lappend O_VECTCFLAGS "-O" +lappend O_VECTCFLAGS "-fdump-tree-vect-details" + +lappend DEFAULT_VECTCFLAGS "-O2" + +# Tests that should be run without generating dump info +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/nodump-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# "-O -fdump-tree-veclower2" +lappend VEC_FLAGS "-O" "-fdump-tree-veclower2" +et-dg-runtest dg-runtest [lsort [glob -nocomplain \ + $srcdir/$subdir/vec-scal-*.\[cS\]]] \ + "" $VEC_FLAGS + +set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" +lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" + +# Main loop. +set VECT_ADDITIONAL_FLAGS [list ""] +if { [check_effective_target_lto] } { + lappend VECT_ADDITIONAL_FLAGS "-flto -ffat-lto-objects" +} +foreach flags $VECT_ADDITIONAL_FLAGS { + et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/pr*.\[cS\]]] \ + $flags $DEFAULT_VECTCFLAGS + et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/vect-*.\[cS\]]] \ + $flags $DEFAULT_VECTCFLAGS + et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/slp-*.\[cS\]]] \ + $flags $DEFAULT_VECTCFLAGS + et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/bb-slp*.\[cS\]]] \ + $flags $VECT_SLP_CFLAGS +} + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS +set SAVED_VECT_SLP_CFLAGS $VECT_SLP_CFLAGS + +# --param vect-max-version-for-alias-checks=0 tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "--param" "vect-max-version-for-alias-checks=0" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -ftree-slp-transpose-vectorize SLP tests +set VECT_SLP_CFLAGS $SAVED_VECT_SLP_CFLAGS +lappend VECT_SLP_CFLAGS "-ftree-slp-transpose-vectorize" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/transpose-*.\[cS\]]] \ + "" "-ftree-slp-transpose-vectorize -fdump-tree-slp-details -O3" + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/fast-math-\[ipsv\]*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -ffast-math SLP tests +set VECT_SLP_CFLAGS $SAVED_VECT_SLP_CFLAGS +lappend VECT_SLP_CFLAGS "-ffast-math" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/fast-math-bb-slp-*.\[cS\]]] \ + "" $VECT_SLP_CFLAGS + +# -fno-fast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-fast-math" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-fast-math-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-math-errno tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-math-errno" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-math-errno-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fwrapv tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fwrapv" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/wrapv-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -ftrapv tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ftrapv" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/trapv-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-dce tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-dce" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-tree-dce-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fsection-anchors tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fsection-anchors" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/section-anchors-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# alignment-sensitive -fsection-anchors tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fsection-anchors" \ + "-fdump-ipa-increase_alignment-details" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/aligned-section-anchors-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-section-anchors tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-section-anchors" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-section-anchors-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -funswitch-loops tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-funswitch-loops" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/unswitch-loops-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-trapping-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-trapping-math" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-trapping-math-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-scevccp-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-scevccp-pr*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-scevccp-outer-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop -fno-tree-reassoc +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" "-fno-tree-reassoc" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-scevccp-noreassoc-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-scevccp-slp-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-dominator-opts +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-dominator-opts" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-tree-dom-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-pre +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-pre" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-tree-pre-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With -Os +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-Os" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/Os-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With --param ggc-min-expand=0 --param ggc-min-heapsize=0 +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "--param" "ggc-min-expand=0" "--param" "ggc-min-heapsize=0" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/ggc-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With -O3. +# Don't allow IPA cloning, because it throws our counts out of whack. +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-O3" "-fno-ipa-cp-clone" + +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/O3-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With -O1 +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/O1-*.\[cS\]]] \ + "" $O1_VECTCFLAGS + +# With -O +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/O-*.\[cS\]]] \ + "" $O_VECTCFLAGS + +# -fno-tree-reassoc +set VECT_SLP_CFLAGS $SAVED_VECT_SLP_CFLAGS +lappend VECT_SLP_CFLAGS "-fno-tree-reassoc" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-tree-reassoc-bb-slp-*.\[cS\]]] \ + "" $VECT_SLP_CFLAGS + +# -fno-tree-fre +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-fre" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-tree-fre-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-fre -fno-tree-pre +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-fre" "-fno-tree-pre" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-fre-pre*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-sra +set VECT_SLP_CFLAGS $SAVED_VECT_SLP_CFLAGS +lappend VECT_SLP_CFLAGS "-fno-tree-sra" +et-dg-runtest dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/no-tree-sra-bb-slp-*.\[cS\]]] \ + "" $VECT_SLP_CFLAGS + + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +clearcap-finish +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aarch64.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aarch64.exp new file mode 100644 index 0000000000000000000000000000000000000000..5119a6dbb2024a06993794d7440f57ced6a9f11c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aarch64.exp @@ -0,0 +1,45 @@ +# Specific regression driver for AArch64. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. +# Contributed by ARM Ltd. +# +# This file is part of GCC. +# +# GCC 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, or (at your option) +# any later version. +# +# GCC 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 +# . */ + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an AArch64 target. +if {![istarget aarch64*-*-*] } then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aes-decrypt.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aes-decrypt.c new file mode 100644 index 0000000000000000000000000000000000000000..966ec553212ccc5bad889fedd5ff6be6e1b69158 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aes-decrypt.c @@ -0,0 +1,478 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline --save-temps -fcrypto-accel-aes -march=armv8.2-a+lse+crypto" } */ + +#include +#include +#include +#include +#include + +typedef uint8_t u8; +typedef uint32_t u32; + +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; + +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; + +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; + +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; + +static const u8 Td4[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; + +#define GETU32(pt) \ + ( \ + ((u32)(pt)[0] << 24) \ + ^ ((u32)(pt)[1] << 16) \ + ^ ((u32)(pt)[2] << 8) \ + ^ ((u32)(pt)[3]) \ + ) + +#define PUTU32(ct, st) \ + { \ + (ct)[0] = (u8)((st) >> 24); \ + (ct)[1] = (u8)((st) >> 16); \ + (ct)[2] = (u8)((st) >> 8); \ + (ct)[3] = (u8)(st); \ + } + +void +aes_decrypt (const unsigned char *in, unsigned char *out, + const u32 *rk, int nr) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + int r = nr >> 1; + + s0 = GETU32 (in ) ^ rk[0]; + s1 = GETU32 (in + 4) ^ rk[1]; + s2 = GETU32 (in + 8) ^ rk[2]; + s3 = GETU32 (in + 12) ^ rk[3]; + + for (;;) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]; + s1 = + Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]; + s2 = + Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]; + s3 = + Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]; + } + + s0 = + ((u32)Td4[(t0 >> 24) ] << 24) ^ + ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t2 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t1 ) & 0xff]) ^ + rk[0]; + PUTU32 (out , s0); + + s1 = + ((u32)Td4[(t1 >> 24) ] << 24) ^ + ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t3 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t2 ) & 0xff]) ^ + rk[1]; + PUTU32 (out + 4, s1); + + s2 = + ((u32)Td4[(t2 >> 24) ] << 24) ^ + ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t0 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t3 ) & 0xff]) ^ + rk[2]; + PUTU32 (out + 8, s2); + + s3 = + ((u32)Td4[(t3 >> 24) ] << 24) ^ + ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t1 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t0 ) & 0xff]) ^ + rk[3]; + PUTU32 (out + 12, s3); +} + +int main () +{ + const u8 input[16] = { 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, + 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 }; + + const u8 expected[16] = { 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, + 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 }; + + const u8 key[] = { 0xa8, 0xf9, 0x14, 0xd0, 0x89, 0x25, 0xee, 0xc9, + 0xc8, 0x0c, 0x3f, 0xe1, 0xa6, 0x0c, 0x63, 0xb6, + 0x63, 0x5a, 0x7b, 0x0c, 0xfe, 0xea, 0x19, 0x13, + 0x90, 0x88, 0x39, 0xb0, 0xb4, 0xfb, 0x4c, 0x66, + 0x5a, 0x92, 0x7d, 0xdf, 0x9d, 0xb0, 0x62, 0x1f, + 0x6e, 0x62, 0x20, 0xa3, 0x24, 0x73, 0x75, 0xd6, + 0x47, 0x76, 0xc0, 0x12, 0xc7, 0x22, 0x1f, 0xc0, + 0xf3, 0xd2, 0x42, 0xbc, 0x4a, 0x11, 0x55, 0x75, + 0x76, 0xd8, 0xfc, 0x6e, 0x80, 0x54, 0xdf, 0xd2, + 0x34, 0xf0, 0x5d, 0x7c, 0xb9, 0xc3, 0x17, 0xc9, + 0xfc, 0x0a, 0xa3, 0x6e, 0xf6, 0x8c, 0x23, 0xbc, + 0xb4, 0xa4, 0x82, 0xae, 0x8d, 0x33, 0x4a, 0xb5, + 0x13, 0x44, 0x88, 0x90, 0x0a, 0x86, 0x80, 0xd2, + 0x42, 0x28, 0xa1, 0x12, 0x39, 0x97, 0xc8, 0x1b, + 0xf7, 0x13, 0x1f, 0x7c, 0x19, 0xc2, 0x08, 0x42, + 0x48, 0xae, 0x21, 0xc0, 0x7b, 0xbf, 0x69, 0x09, + 0xeb, 0x05, 0x75, 0xcc, 0xee, 0xd1, 0x17, 0x3e, + 0x51, 0x6c, 0x29, 0x82, 0x33, 0x11, 0x48, 0xc9, + 0xa7, 0x08, 0x37, 0x2b, 0x05, 0xd4, 0x62, 0xf2, + 0xbf, 0xbd, 0x3e, 0xbc, 0x62, 0x7d, 0x61, 0x4b, + 0x16, 0x15, 0x7e, 0x2b, 0xa6, 0xd2, 0xae, 0x28, + 0x88, 0x15, 0xf7, 0xab, 0x3c, 0x4f, 0xcf, 0x09 }; + + u8 output[16] = { 0 }; + + aes_decrypt (input, output, (u32*) key, 10); + + if (memcmp (output, expected, 16) != 0) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler "rev32" } } */ +/* { dg-final { scan-assembler "aesimc" } } */ +/* { dg-final { scan-assembler "aesd" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aes-encrypt.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aes-encrypt.c new file mode 100644 index 0000000000000000000000000000000000000000..e3f3c446f9484b4a9993d8decb43fdbc043ef66c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/aes-encrypt.c @@ -0,0 +1,443 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline --save-temps -fcrypto-accel-aes -march=armv8.2-a+lse+crypto" } */ + +#include +#include +#include +#include +#include + +typedef uint8_t u8; +typedef uint32_t u32; + +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; + +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; + +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; + +static const u32 Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; + +#define GETU32(pt) \ + ( \ + ((u32)(pt)[0] << 24) \ + ^ ((u32)(pt)[1] << 16) \ + ^ ((u32)(pt)[2] << 8) \ + ^ ((u32)(pt)[3]) \ + ) + +#define PUTU32(ct, st) \ + { \ + (ct)[0] = (u8)((st) >> 24); \ + (ct)[1] = (u8)((st) >> 16); \ + (ct)[2] = (u8)((st) >> 8); \ + (ct)[3] = (u8)(st); \ + } + +void +aes_encrypt (const unsigned char *in, unsigned char *out, + const u32 *rk, int nr) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + int r = nr >> 1; + + s0 = GETU32 (in ) ^ rk[0]; + s1 = GETU32 (in + 4) ^ rk[1]; + s2 = GETU32 (in + 8) ^ rk[2]; + s3 = GETU32 (in + 12) ^ rk[3]; + + for (;;) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) + break; + + s0 = + Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]; + s1 = + Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]; + s2 = + Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]; + s3 = + Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]; + } + + s0 = + (Te2[(t0 >> 24) ] & 0xff000000) ^ + (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32 (out , s0); + + s1 = + (Te2[(t1 >> 24) ] & 0xff000000) ^ + (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32 (out + 4, s1); + + s2 = + (Te2[(t2 >> 24) ] & 0xff000000) ^ + (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32 (out + 8, s2); + + s3 = + (Te2[(t3 >> 24) ] & 0xff000000) ^ + (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32 (out + 12, s3); +} + + +int main () +{ + const u8 input[16] = { 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, + 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 }; + + const u8 expected[16] = { 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, + 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 }; + + const u8 key[] = { 0x16, 0x15, 0x7e, 0x2b, 0xa6, 0xd2, 0xae, 0x28, + 0x88, 0x15, 0xf7, 0xab, 0x3c, 0x4f, 0xcf, 0x09, + 0x17, 0xfe, 0xfa, 0xa0, 0xb1, 0x2c, 0x54, 0x88, + 0x39, 0x39, 0xa3, 0x23, 0x05, 0x76, 0x6c, 0x2a, + 0xf2, 0x95, 0xc2, 0xf2, 0x43, 0xb9, 0x96, 0x7a, + 0x7a, 0x80, 0x35, 0x59, 0x7f, 0xf6, 0x59, 0x73, + 0x7d, 0x47, 0x80, 0x3d, 0x3e, 0xfe, 0x16, 0x47, + 0x44, 0x7e, 0x23, 0x1e, 0x3b, 0x88, 0x7a, 0x6d, + 0x41, 0xa5, 0x44, 0xef, 0x7f, 0x5b, 0x52, 0xa8, + 0x3b, 0x25, 0x71, 0xb6, 0x00, 0xad, 0x0b, 0xdb, + 0xf8, 0xc6, 0xd1, 0xd4, 0x87, 0x9d, 0x83, 0x7c, + 0xbc, 0xb8, 0xf2, 0xca, 0xbc, 0x15, 0xf9, 0x11, + 0x7a, 0xa3, 0x88, 0x6d, 0xfd, 0x3e, 0x0b, 0x11, + 0x41, 0x86, 0xf9, 0xdb, 0xfd, 0x93, 0x00, 0xca, + 0x0e, 0xf7, 0x54, 0x4e, 0xf3, 0xc9, 0x5f, 0x5f, + 0xb2, 0x4f, 0xa6, 0x84, 0x4f, 0xdc, 0xa6, 0x4e, + 0x21, 0x73, 0xd2, 0xea, 0xd2, 0xba, 0x8d, 0xb5, + 0x60, 0xf5, 0x2b, 0x31, 0x2f, 0x29, 0x8d, 0x7f, + 0xf3, 0x66, 0x77, 0xac, 0x21, 0xdc, 0xfa, 0x19, + 0x41, 0x29, 0xd1, 0x28, 0x6e, 0x00, 0x5c, 0x57, + 0xa8, 0xf9, 0x14, 0xd0, 0x89, 0x25, 0xee, 0xc9, + 0xc8, 0x0c, 0x3f, 0xe1, 0xa6, 0x0c, 0x63, 0xb6 }; + + u8 output[16] = { 0 }; + + aes_encrypt (input, output, (u32*) key, 10); + + if (memcmp (output, expected, 16) != 0) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler "rev32" } } */ +/* { dg-final { scan-assembler "aesmc" } } */ +/* { dg-final { scan-assembler "aese" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/ccmp_3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/ccmp_3.c new file mode 100644 index 0000000000000000000000000000000000000000..b509ba81010f52c12cfa2dd343b02256a456146b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/ccmp_3.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O -fdump-rtl-expand-details -fccmp2" } */ + +int func (int a, int b, int c) +{ + while(1) + { + if(a-- == 0 || b >= c) + { + return 1; + } + } +} + +/* { dg-final { scan-assembler-times "\tccmp\t" 1} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_1.c new file mode 100644 index 0000000000000000000000000000000000000000..ef336aeec4f870a39a0fd3336c36ea868a7e575f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_1.c @@ -0,0 +1,149 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** adds (w[0-9]+), w0, #4 +** csel w0, \1, wzr, g[te] +** ret +*/ +/* +** f2: +** adds (w[0-9]+), w0, #4 +** csel w0, \1, wzr, g[te] +** ret +*/ +/* +** f3: +** adds (w[0-9]+), w0, #5 +** csinc w0, \1, wzr, gt +** ret +*/ +/* +** f4: +** adds (w[0-9]+), w0, #3 +** csinv w0, \1, wzr, ge +** ret +*/ + +#ifndef TYPE +#define TYPE int32_t +#define TYPE_MIN INT32_MIN +#define TYPE_MAX INT32_MAX +#define VALUE -4 +#endif + +#include + +TYPE __attribute__((noipa)) +f1 (TYPE x) +{ + return (x > VALUE ? x - VALUE : 0); +} + +TYPE __attribute__((noipa)) +f2 (TYPE x) +{ + return (x > VALUE ? x : VALUE) - VALUE; +} + +TYPE __attribute__((noipa)) +f3 (TYPE x) +{ + return (x > VALUE ? x : VALUE) - (VALUE - 1); +} + +TYPE __attribute__((noipa)) +f4 (TYPE x) +{ + return (x > VALUE ? x : VALUE) - (VALUE + 1); +} + +TYPE __attribute__((noipa)) +f5 (TYPE x) +{ + return (x > VALUE ? x : VALUE) - (VALUE + 2); +} + +TYPE __attribute__((noipa)) +f6 (TYPE x) +{ + return (x > VALUE ? x : VALUE) - (VALUE - 2); +} + +int +main (void) +{ + TYPE max_test = TYPE_MAX; + if (TYPE_MIN < 0 && VALUE < 0) + max_test += VALUE; + + if (f1 (TYPE_MIN) != 0) + __builtin_abort (); + if (f1 (VALUE - 1) != 0) + __builtin_abort (); + if (f1 (VALUE) != 0) + __builtin_abort (); + if (f1 (VALUE + 1) != 1) + __builtin_abort (); + if (f1 (max_test) != max_test - VALUE) + __builtin_abort (); + + if (f2 (TYPE_MIN) != 0) + __builtin_abort (); + if (f2 (VALUE - 1) != 0) + __builtin_abort (); + if (f2 (VALUE) != 0) + __builtin_abort (); + if (f2 (VALUE + 1) != 1) + __builtin_abort (); + if (f2 (max_test) != max_test - VALUE) + __builtin_abort (); + + if (f3 (TYPE_MIN) != 1) + __builtin_abort (); + if (f3 (VALUE - 1) != 1) + __builtin_abort (); + if (f3 (VALUE) != 1) + __builtin_abort (); + if (f3 (VALUE + 1) != 2) + __builtin_abort (); + if (f3 (max_test - 1) != max_test - VALUE) + __builtin_abort (); + + if (f4 (TYPE_MIN) != -1) + __builtin_abort (); + if (f4 (VALUE - 1) != -1) + __builtin_abort (); + if (f4 (VALUE) != -1) + __builtin_abort (); + if (f4 (VALUE + 1) != 0) + __builtin_abort (); + if (f4 (max_test) != max_test - VALUE - 1) + __builtin_abort (); + + if (f5 (TYPE_MIN) != -2) + __builtin_abort (); + if (f5 (VALUE - 1) != -2) + __builtin_abort (); + if (f5 (VALUE) != -2) + __builtin_abort (); + if (f5 (VALUE + 1) != -1) + __builtin_abort (); + if (f5 (max_test) != max_test - VALUE - 2) + __builtin_abort (); + + if (f6 (TYPE_MIN) != 2) + __builtin_abort (); + if (f6 (VALUE - 1) != 2) + __builtin_abort (); + if (f6 (VALUE) != 2) + __builtin_abort (); + if (f6 (VALUE + 1) != 3) + __builtin_abort (); + if (VALUE <= max_test - 2 && f6 (max_test - 2) != max_test - VALUE) + __builtin_abort (); + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_2.c new file mode 100644 index 0000000000000000000000000000000000000000..a2a1295d91856d27043a613354d7a22dd42ff792 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_2.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** adds (x[0-9]+), x0, #4094 +** csel x0, \1, xzr, g[te] +** ret +*/ +/* +** f2: +** adds (x[0-9]+), x0, #4094 +** csel x0, \1, xzr, g[te] +** ret +*/ +/* +** f3: +** adds (x[0-9]+), x0, #4095 +** csinc x0, \1, xzr, gt +** ret +*/ +/* +** f4: +** adds (x[0-9]+), x0, #4093 +** csinv x0, \1, xzr, ge +** ret +*/ + +#define TYPE int64_t +#define TYPE_MIN INT64_MIN +#define TYPE_MAX INT64_MAX +#define VALUE -4094 + +#include "max_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_3.c new file mode 100644 index 0000000000000000000000000000000000000000..a9792ecc94d991513588618ed30889c733850ddd --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_3.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** adds (w[0-9]+), w0, #4095 +** csel w0, \1, wzr, g[te] +** ret +*/ +/* +** f2: +** adds (w[0-9]+), w0, #4095 +** csel w0, \1, wzr, g[te] +** ret +*/ +/* +** f3: +** adds (w[0-9]+), w0, #4096 +** csinc w0, \1, wzr, gt +** ret +*/ +/* +** f4: +** adds (w[0-9]+), w0, #4094 +** csinv w0, \1, wzr, ge +** ret +*/ + +#define TYPE int32_t +#define TYPE_MIN INT32_MIN +#define TYPE_MAX INT32_MAX +#define VALUE -4095 + +#include "max_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_4.c new file mode 100644 index 0000000000000000000000000000000000000000..5090fa101921f2d2c717cb027c4e724552e4c376 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_4.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** adds (x[0-9]+), x0, #4096 +** csel x0, \1, xzr, g[te] +** ret +*/ +/* +** f2: +** adds (x[0-9]+), x0, #4096 +** csel x0, \1, xzr, g[te] +** ret +*/ +/* f3 out of range */ +/* +** f4: +** adds (x[0-9]+), x0, #4095 +** csinv x0, \1, xzr, ge +** ret +*/ + +#define TYPE int64_t +#define TYPE_MIN INT64_MIN +#define TYPE_MAX INT64_MAX +#define VALUE -4096 + +#include "max_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_5.c new file mode 100644 index 0000000000000000000000000000000000000000..63f3b34424e378363ec0a5be7522babdd6169039 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_5.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** adds (w[0-9]+), w0, #4095 +** csel w0, \1, wzr, (cs|hi) +** ret +*/ +/* +** f2: +** adds (w[0-9]+), w0, #4095 +** csel w0, \1, wzr, (cs|hi) +** ret +*/ +/* +** f3: +** adds (w[0-9]+), w0, #4096 +** csinc w0, \1, wzr, hi +** ret +*/ +/* +** f4: +** adds (w[0-9]+), w0, #4094 +** csinv w0, \1, wzr, cs +** ret +*/ + +#define TYPE uint32_t +#define TYPE_MIN 0 +#define TYPE_MAX UINT32_MAX +#define VALUE (uint32_t)-4095 + +#include "max_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_6.c new file mode 100644 index 0000000000000000000000000000000000000000..ad592c69052f6d088cffb055c296ae5f6665ac14 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_6.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ + +#define TYPE uint64_t +#define TYPE_MIN 0 +#define TYPE_MAX UINT64_MAX +#define VALUE (uint64_t)-2 + +#include "max_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_7.c new file mode 100644 index 0000000000000000000000000000000000000000..ac9f27dec61c69d174dd55b41a79f33716c8b108 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/max_plus_7.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** adds (x[0-9]+), x0, #3 +** csel x0, \1, xzr, (cs|hi) +** ret +*/ +/* +** f2: +** adds (x[0-9]+), x0, #3 +** csel x0, \1, xzr, (cs|hi) +** ret +*/ +/* +** f3: +** adds (x[0-9]+), x0, #4 +** csinc x0, \1, xzr, hi +** ret +*/ +/* +** f4: +** adds (x[0-9]+), x0, #2 +** csinv x0, \1, xzr, cs +** ret +*/ + +#define TYPE uint64_t +#define TYPE_MIN 0 +#define TYPE_MAX UINT64_MAX +#define VALUE (uint64_t)-3 + +#include "max_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_1.c new file mode 100644 index 0000000000000000000000000000000000000000..f4c9106dfcabf46b1f35d49cba2184f8cd80da9b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_1.c @@ -0,0 +1,149 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** subs (w[0-9]+), w0, #?4 +** csel w0, \1, wzr, l[te] +** ret +*/ +/* +** f2: +** subs (w[0-9]+), w0, #?4 +** csel w0, \1, wzr, l[te] +** ret +*/ +/* +** f3: +** subs (w[0-9]+), w0, #?3 +** csinc w0, \1, wzr, le +** ret +*/ +/* +** f4: +** subs (w[0-9]+), w0, #?5 +** csinv w0, \1, wzr, lt +** ret +*/ + +#ifndef TYPE +#define TYPE int32_t +#define TYPE_MIN INT32_MIN +#define TYPE_MAX INT32_MAX +#define VALUE 4 +#endif + +#include + +TYPE __attribute__((noipa)) +f1 (TYPE x) +{ + return (x < VALUE ? x - VALUE : 0); +} + +TYPE __attribute__((noipa)) +f2 (TYPE x) +{ + return (x < VALUE ? x : VALUE) - VALUE; +} + +TYPE __attribute__((noipa)) +f3 (TYPE x) +{ + return (x < VALUE ? x : VALUE) - (VALUE - 1); +} + +TYPE __attribute__((noipa)) +f4 (TYPE x) +{ + return (x < VALUE ? x : VALUE) - (VALUE + 1); +} + +TYPE __attribute__((noipa)) +f5 (TYPE x) +{ + return (x < VALUE ? x : VALUE) - (VALUE + 2); +} + +TYPE __attribute__((noipa)) +f6 (TYPE x) +{ + return (x < VALUE ? x : VALUE) - (VALUE - 2); +} + +int +main (void) +{ + TYPE min_test = TYPE_MIN; + if (TYPE_MIN < 0 && VALUE > 0) + min_test += VALUE; + + if (f1 (min_test) != min_test - VALUE) + __builtin_abort (); + if (f1 (VALUE - 1) != -1) + __builtin_abort (); + if (f1 (VALUE) != 0) + __builtin_abort (); + if (f1 (VALUE + 1) != 0) + __builtin_abort (); + if (f1 (TYPE_MAX) != 0) + __builtin_abort (); + + if (f2 (min_test) != min_test - VALUE) + __builtin_abort (); + if (f2 (VALUE - 1) != -1) + __builtin_abort (); + if (f2 (VALUE) != 0) + __builtin_abort (); + if (f2 (VALUE + 1) != 0) + __builtin_abort (); + if (f2 (TYPE_MAX) != 0) + __builtin_abort (); + + if (f3 (min_test) != min_test - VALUE + 1) + __builtin_abort (); + if (f3 (VALUE - 1) != 0) + __builtin_abort (); + if (f3 (VALUE) != 1) + __builtin_abort (); + if (f3 (VALUE + 1) != 1) + __builtin_abort (); + if (f3 (TYPE_MAX) != 1) + __builtin_abort (); + + if (f4 (min_test + 1) != min_test - VALUE) + __builtin_abort (); + if (f4 (VALUE - 1) != -2) + __builtin_abort (); + if (f4 (VALUE) != -1) + __builtin_abort (); + if (f4 (VALUE + 1) != -1) + __builtin_abort (); + if (f4 (TYPE_MAX) != -1) + __builtin_abort (); + + if (VALUE >= min_test + 2 && f5 (min_test + 2) != min_test - VALUE) + __builtin_abort (); + if (f5 (VALUE - 1) != -3) + __builtin_abort (); + if (f5 (VALUE) != -2) + __builtin_abort (); + if (f5 (VALUE + 1) != -2) + __builtin_abort (); + if (f5 (TYPE_MAX) != -2) + __builtin_abort (); + + if (f6 (min_test) != min_test - VALUE + 2) + __builtin_abort (); + if (f6 (VALUE - 1) != 1) + __builtin_abort (); + if (f6 (VALUE) != 2) + __builtin_abort (); + if (f6 (VALUE + 1) != 2) + __builtin_abort (); + if (f6 (TYPE_MAX) != 2) + __builtin_abort (); + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_2.c new file mode 100644 index 0000000000000000000000000000000000000000..bc0141b726448ec245775a0555813c380053ebbe --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_2.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** subs (x[0-9]+), x0, #?4094 +** csel x0, \1, xzr, l[te] +** ret +*/ +/* +** f2: +** subs (x[0-9]+), x0, #?4094 +** csel x0, \1, xzr, l[te] +** ret +*/ +/* +** f3: +** subs (x[0-9]+), x0, #?4093 +** csinc x0, \1, xzr, le +** ret +*/ +/* +** f4: +** subs (x[0-9]+), x0, #?4095 +** csinv x0, \1, xzr, lt +** ret +*/ + +#define TYPE int64_t +#define TYPE_MIN INT64_MIN +#define TYPE_MAX INT64_MAX +#define VALUE 4094 + +#include "min_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_3.c new file mode 100644 index 0000000000000000000000000000000000000000..1808e4b0cbf372c40f0354cd5bf9bb4d9fadbfc3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_3.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** subs (w[0-9]+), w0, #?4095 +** csel w0, \1, wzr, l[te] +** ret +*/ +/* +** f2: +** subs (w[0-9]+), w0, #?4095 +** csel w0, \1, wzr, l[te] +** ret +*/ +/* +** f3: +** subs (w[0-9]+), w0, #?4094 +** csinc w0, \1, wzr, le +** ret +*/ +/* +** f4: +** subs (w[0-9]+), w0, #?4096 +** csinv w0, \1, wzr, lt +** ret +*/ + +#define TYPE int32_t +#define TYPE_MIN INT32_MIN +#define TYPE_MAX INT32_MAX +#define VALUE 4095 + +#include "min_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_4.c new file mode 100644 index 0000000000000000000000000000000000000000..6c581fed61d7a67b72dde12609304f5b01c03f31 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_4.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** subs (x[0-9]+), x0, #?4096 +** csel x0, \1, xzr, l[te] +** ret +*/ +/* +** f2: +** subs (x[0-9]+), x0, #?4096 +** csel x0, \1, xzr, l[te] +** ret +*/ +/* +** f3: +** subs (x[0-9]+), x0, #?4095 +** csinc x0, \1, xzr, le +** ret +*/ +/* f4 out of range */ + +#define TYPE int64_t +#define TYPE_MIN INT64_MIN +#define TYPE_MAX INT64_MAX +#define VALUE 4096 + +#include "min_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_5.c new file mode 100644 index 0000000000000000000000000000000000000000..97542d507658e0aaa885ba8e583eb049c358c4eb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_5.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** subs (w[0-9]+), w0, #?4095 +** csel w0, \1, wzr, (cc|ls) +** ret +*/ +/* +** f2: +** subs (w[0-9]+), w0, #?4095 +** csel w0, \1, wzr, (cc|ls) +** ret +*/ +/* +** f3: +** subs (w[0-9]+), w0, #?4094 +** csinc w0, \1, wzr, ls +** ret +*/ +/* +** f4: +** subs (w[0-9]+), w0, #?4096 +** csinv w0, \1, wzr, cc +** ret +*/ + +#define TYPE uint32_t +#define TYPE_MIN 0 +#define TYPE_MAX UINT32_MAX +#define VALUE 4095 + +#include "min_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_6.c new file mode 100644 index 0000000000000000000000000000000000000000..176533cb2e1f2bdff6d29eafa5cda0456964e381 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_6.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ + +#define TYPE uint64_t +#define TYPE_MIN 0 +#define TYPE_MAX UINT64_MAX +#define VALUE 1 + +#include "min_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_7.c new file mode 100644 index 0000000000000000000000000000000000000000..d6a217a51680bee88fb2902786b606d2b9af9dbb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/min_plus_7.c @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* +** f1: +** subs (x[0-9]+), x0, #?2 +** csel x0, \1, xzr, (cc|ls) +** ret +*/ +/* +** f2: +** subs (x[0-9]+), x0, #?2 +** csel x0, \1, xzr, (cc|ls) +** ret +*/ +/* +** f3: +** subs (x[0-9]+), x0, #?1 +** csinc x0, \1, xzr, ls +** ret +*/ +/* +** f4: +** subs (x[0-9]+), x0, #?3 +** csinv x0, \1, xzr, cc +** ret +*/ + +#define TYPE uint64_t +#define TYPE_MIN 0 +#define TYPE_MAX UINT64_MAX +#define VALUE 2 + +#include "min_plus_1.c" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/pr95254.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/pr95254.c new file mode 100644 index 0000000000000000000000000000000000000000..10bfc868197a11e249713e7fb9e8e3ff33f411bb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/pr95254.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-slp-vectorize -march=armv8.2-a+sve -msve-vector-bits=256" } */ + +typedef short __attribute__((vector_size (8))) v4hi; + +typedef union U4HI { v4hi v; short a[4]; } u4hi; + +short b[4]; + +void pass_v4hi (v4hi v) +{ + int i; + u4hi u; + u.v = v; + for (i = 0; i < 4; i++) + b[i] = u.a[i]; +}; + +/* { dg-final { scan-assembler-not "ptrue" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/pr96757.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/pr96757.c new file mode 100644 index 0000000000000000000000000000000000000000..122e39dca0e410d5ec82bbe8fb8bdb9918196162 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/pr96757.c @@ -0,0 +1,23 @@ +/* PR target/96757 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +short +fun1(short i, short j) +{ + return i * j; +} + +int +fun(int a, int b, int c) +{ + int *v, z, k, m; + short f, d; + for (int i=0; i m; + z = f > k; + *v += fun1(z,b); + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/sve/aarch64-sve.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/sve/aarch64-sve.exp new file mode 100644 index 0000000000000000000000000000000000000000..77b84eed707fcb33f74084f82080e0d19f78f9c5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/sve/aarch64-sve.exp @@ -0,0 +1,64 @@ +# Specific regression driver for AArch64 SVE. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. +# Contributed by ARM Ltd. +# +# This file is part of GCC. +# +# GCC 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, or (at your option) +# any later version. +# +# GCC 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 +# . */ + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an AArch64 target. +if {![istarget aarch64*-*-*] } then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Force SVE if we're not testing it already. +if { [check_effective_target_aarch64_sve] } { + set sve_flags "" +} else { + set sve_flags "-march=armv8.2-a+sve" +} + +# Turn off any codegen tweaks by default that may affect expected assembly. +# Tests relying on those should turn them on explicitly. +set sve_flags "$sve_flags -moverride=tune=none" + +# Most of the code-quality tests are written for LP64. Just do the +# correctness tests for ILP32. +if { [check_effective_target_ilp32] } { + set pattern "*_run" +} else { + set pattern "*" +} + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/$pattern.\[cCS\]]] \ + $sve_flags $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/sve/var_stride_flexible_segment_len_1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/sve/var_stride_flexible_segment_len_1.c new file mode 100644 index 0000000000000000000000000000000000000000..894f075f3310f78d077368b325ee8d63d26b42e4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/aarch64/sve/var_stride_flexible_segment_len_1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize --param=vect-alias-flexible-segment-len=1" } */ + +#define TYPE int +#define SIZE 257 + +void __attribute__ ((weak)) +f (TYPE *x, TYPE *y, unsigned short n, long m __attribute__((unused))) +{ + for (int i = 0; i < SIZE; ++i) + x[i * n] += y[i * n]; +} + +/* { dg-final { scan-assembler {\tld1w\tz[0-9]+} } } */ +/* { dg-final { scan-assembler {\tst1w\tz[0-9]+} } } */ +/* { dg-final { scan-assembler {\tldr\tw[0-9]+} } } */ +/* { dg-final { scan-assembler {\tstr\tw[0-9]+} } } */ +/* Should use a WAR check that multiplies by (VF-2)*4 rather than + an overlap check that multiplies by (257-1)*4. */ +/* { dg-final { scan-assembler {\tcntb\t(x[0-9]+)\n.*\tsub\tx[0-9]+, \1, #8\n.*\tmul\tx[0-9]+,[^\n]*\1} } } */ +/* One range check and a check for n being zero. */ +/* { dg-final { scan-assembler-times {\t(?:cmp|tst)\t} 2 } } */ +/* { dg-final { scan-assembler-times {\tccmp\t} 1 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512f-vcvtps2ph-pr95254.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512f-vcvtps2ph-pr95254.c new file mode 100644 index 0000000000000000000000000000000000000000..9e0da9473684da9dc60c0599af45c110462decc3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512f-vcvtps2ph-pr95254.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512f" } */ + +#include +extern __m256i res; +void +foo (__m512 a, __mmask16 m) +{ + res = _mm512_maskz_cvtps_ph (m, a, 10); +} + +/* { dg-final { scan-assembler-not "vcvtps2ph\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]\[^\n\]*res\[^\n\]*\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-1.c new file mode 100644 index 0000000000000000000000000000000000000000..5b79d4d36f912927ad87a8e2e63a755b5ad11fa1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-1.c @@ -0,0 +1,112 @@ +/* PR target/88547 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512bw -mavx512vl -mno-avx512dq -mno-xop" } */ +/* { dg-final { scan-assembler-times "vpcmp\[bwdq\]\[\t ]" 8 } } */ +/* { dg-final { scan-assembler-times "vpcmpu\[bwdq\]\[\t ]" 8 } } */ +/* { dg-final { scan-assembler-times "vpmovm2\[bw\]\[\t ]" 8 } } */ +/* { dg-final { scan-assembler-times "vpternlog\[dq\]\[\t ]" 8 } } */ + +typedef signed char v32qi __attribute__((vector_size(32))); +typedef unsigned char v32uqi __attribute__((vector_size(32))); +typedef short v16hi __attribute__((vector_size(32))); +typedef unsigned short v16uhi __attribute__((vector_size(32))); +typedef int v8si __attribute__((vector_size(32))); +typedef unsigned v8usi __attribute__((vector_size(32))); +typedef long long v4di __attribute__((vector_size(32))); +typedef unsigned long long v4udi __attribute__((vector_size(32))); + +__attribute__((noipa)) v32qi +f1 (v32qi x, v32qi y) +{ + return x >= y; +} + +__attribute__((noipa)) v32uqi +f2 (v32uqi x, v32uqi y) +{ + return x >= y; +} + +__attribute__((noipa)) v32qi +f3 (v32qi x, v32qi y) +{ + return x <= y; +} + +__attribute__((noipa)) v32uqi +f4 (v32uqi x, v32uqi y) +{ + return x <= y; +} + +__attribute__((noipa)) v16hi +f5 (v16hi x, v16hi y) +{ + return x >= y; +} + +__attribute__((noipa)) v16uhi +f6 (v16uhi x, v16uhi y) +{ + return x >= y; +} + +__attribute__((noipa)) v16hi +f7 (v16hi x, v16hi y) +{ + return x <= y; +} + +__attribute__((noipa)) v16uhi +f8 (v16uhi x, v16uhi y) +{ + return x <= y; +} + +__attribute__((noipa)) v8si +f9 (v8si x, v8si y) +{ + return x >= y; +} + +__attribute__((noipa)) v8usi +f10 (v8usi x, v8usi y) +{ + return x >= y; +} + +__attribute__((noipa)) v8si +f11 (v8si x, v8si y) +{ + return x <= y; +} + +__attribute__((noipa)) v8usi +f12 (v8usi x, v8usi y) +{ + return x <= y; +} + +__attribute__((noipa)) v4di +f13 (v4di x, v4di y) +{ + return x >= y; +} + +__attribute__((noipa)) v4udi +f14 (v4udi x, v4udi y) +{ + return x >= y; +} + +__attribute__((noipa)) v4di +f15 (v4di x, v4di y) +{ + return x <= y; +} + +__attribute__((noipa)) v4udi +f16 (v4udi x, v4udi y) +{ + return x <= y; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-2.c new file mode 100644 index 0000000000000000000000000000000000000000..6be24ff30f401d86b7f8e291b3c01ef7f08ba006 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-2.c @@ -0,0 +1,91 @@ +/* { dg-do run } */ +/* { dg-require-effective-target avx512bw } */ +/* { dg-require-effective-target avx512vl } */ +/* { dg-options "-O2 -mavx512bw -mavx512vl" } */ + +#ifndef CHECK +#define CHECK "avx512f-helper.h" +#endif + +#include CHECK + +#ifndef TEST +#define TEST avx512vl_test +#endif + +#include "avx512vl-pr92686-vpcmp-1.c" + +#define NUM 256 + +#define TEST_SIGNED(vtype, type, N, fn, op) \ +do \ + { \ + union { vtype x[NUM / N]; type i[NUM]; } dst, src1, src2; \ + int i, sign = 1; \ + type res; \ + for (i = 0; i < NUM; i++) \ + { \ + src1.i[i] = i * i * sign; \ + src2.i[i] = (i + 20) * sign; \ + sign = -sign; \ + } \ + for (i = 0; i < NUM; i += N) \ + dst.x[i / N] = fn (src1.x[i / N], src2.x[i / N]); \ + \ + for (i = 0; i < NUM; i++) \ + { \ + res = src1.i[i] op src2.i[i] ? -1 : 0; \ + if (res != dst.i[i]) \ + abort (); \ + } \ + } \ +while (0) + +#define TEST_UNSIGNED(vtype, type, N, fn, op) \ +do \ + { \ + union { vtype x[NUM / N]; type i[NUM]; } dst, src1, src2; \ + int i; \ + type res; \ + \ + for (i = 0; i < NUM; i++) \ + { \ + src1.i[i] = i * i; \ + src2.i[i] = i + 20; \ + if ((i % 4)) \ + src2.i[i] |= (1ULL << (sizeof (type) \ + * __CHAR_BIT__ - 1)); \ + } \ + \ + for (i = 0; i < NUM; i += N) \ + dst.x[i / N] = fn (src1.x[i / N], src2.x[i / N]); \ + \ + for (i = 0; i < NUM; i++) \ + { \ + res = src1.i[i] op src2.i[i] ? -1 : 0; \ + if (res != dst.i[i]) \ + abort (); \ + } \ + } \ +while (0) + +static void +TEST (void) +{ + TEST_SIGNED (v32qi, signed char, 32, f1, >=); + TEST_UNSIGNED (v32uqi, unsigned char, 32, f2, >=); + TEST_SIGNED (v32qi, signed char, 32, f3, <=); + TEST_UNSIGNED (v32uqi, unsigned char, 32, f4, <=); + TEST_SIGNED (v16hi, short int, 16, f5, >=); + TEST_UNSIGNED (v16uhi, unsigned short int, 16, f6, >=); + TEST_SIGNED (v16hi, short int, 16, f7, <=); + TEST_UNSIGNED (v16uhi, unsigned short int, 16, f8, <=); + TEST_SIGNED (v8si, int, 8, f9, >=); + TEST_UNSIGNED (v8usi, unsigned int, 8, f10, >=); + TEST_SIGNED (v8si, int, 8, f11, <=); + TEST_UNSIGNED (v8usi, unsigned int, 8, f12, <=); + TEST_SIGNED (v4di, long long int, 4, f13, >=); + TEST_UNSIGNED (v4udi, unsigned long long int, 4, f14, >=); + TEST_SIGNED (v4di, long long int, 4, f15, <=); + TEST_UNSIGNED (v4udi, unsigned long long int, 4, f16, <=); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-intelasm-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-intelasm-1.c new file mode 100644 index 0000000000000000000000000000000000000000..907386db08b20fe0fd9b9b0317cfdfd6ad1aebd0 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-pr92686-vpcmp-intelasm-1.c @@ -0,0 +1,111 @@ +/* PR target/88547 */ +/* { dg-do assemble } */ +/* { dg-require-effective-target masm_intel } */ +/* { dg-options "-O2 -mavx512bw -mavx512vl -mno-avx512dq -mno-xop -masm=intel" } */ +/* { dg-require-effective-target avx512bw } */ +/* { dg-require-effective-target avx512vl } */ + +typedef signed char v32qi __attribute__((vector_size(32))); +typedef unsigned char v32uqi __attribute__((vector_size(32))); +typedef short v16hi __attribute__((vector_size(32))); +typedef unsigned short v16uhi __attribute__((vector_size(32))); +typedef int v8si __attribute__((vector_size(32))); +typedef unsigned v8usi __attribute__((vector_size(32))); +typedef long long v4di __attribute__((vector_size(32))); +typedef unsigned long long v4udi __attribute__((vector_size(32))); + +__attribute__((noipa)) v32qi +f1 (v32qi x, v32qi y) +{ + return x >= y; +} + +__attribute__((noipa)) v32uqi +f2 (v32uqi x, v32uqi y) +{ + return x >= y; +} + +__attribute__((noipa)) v32qi +f3 (v32qi x, v32qi y) +{ + return x <= y; +} + +__attribute__((noipa)) v32uqi +f4 (v32uqi x, v32uqi y) +{ + return x <= y; +} + +__attribute__((noipa)) v16hi +f5 (v16hi x, v16hi y) +{ + return x >= y; +} + +__attribute__((noipa)) v16uhi +f6 (v16uhi x, v16uhi y) +{ + return x >= y; +} + +__attribute__((noipa)) v16hi +f7 (v16hi x, v16hi y) +{ + return x <= y; +} + +__attribute__((noipa)) v16uhi +f8 (v16uhi x, v16uhi y) +{ + return x <= y; +} + +__attribute__((noipa)) v8si +f9 (v8si x, v8si y) +{ + return x >= y; +} + +__attribute__((noipa)) v8usi +f10 (v8usi x, v8usi y) +{ + return x >= y; +} + +__attribute__((noipa)) v8si +f11 (v8si x, v8si y) +{ + return x <= y; +} + +__attribute__((noipa)) v8usi +f12 (v8usi x, v8usi y) +{ + return x <= y; +} + +__attribute__((noipa)) v4di +f13 (v4di x, v4di y) +{ + return x >= y; +} + +__attribute__((noipa)) v4udi +f14 (v4udi x, v4udi y) +{ + return x >= y; +} + +__attribute__((noipa)) v4di +f15 (v4di x, v4di y) +{ + return x <= y; +} + +__attribute__((noipa)) v4udi +f16 (v4udi x, v4udi y) +{ + return x <= y; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-vcvtps2ph-pr95254.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-vcvtps2ph-pr95254.c new file mode 100644 index 0000000000000000000000000000000000000000..0c685ea66fdae85ab21ce2d58d4bd03301640c15 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/avx512vl-vcvtps2ph-pr95254.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mavx512vl -mavx512f" } */ + +#include +extern __m128i res; +void +foo (__m256 a, __mmask8 m) +{ + res = _mm256_maskz_cvtps_ph (m, a, 10); +} + +void +foo1 (__m128 a, __mmask8 m) +{ + res = _mm_maskz_cvtps_ph (m, a, 10); +} + +/* { dg-final { scan-assembler-not "vcvtps2ph\[ \\t\]+\[^\{\n\]*%\[xy\]mm\[0-9\]\[^\n\]*res\[^\n\]*\{%k\[1-7\]\}\{z\}(?:\n|\[ \\t\]+#)"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/i386.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/i386.exp new file mode 100644 index 0000000000000000000000000000000000000000..fd11ff5f89eecc14f3c1de8d39333a4f6fb2cc26 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/i386.exp @@ -0,0 +1,60 @@ +# Copyright (C) 1997-2020 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a x86 target. +if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { + return +} + +# Load support procs. +load_lib gcc-dg.exp +load_lib clearcap.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init +clearcap-init + +global runtests +# Special case compilation of vect-args.c so we don't have to +# replicate it 16 times. +if [runtest_file_p $runtests $srcdir/$subdir/vect-args.c] { + foreach type { "" -mmmx -m3dnow -msse -msse2 -mavx -mavx2 -mavx512f } { + foreach level { "" -O } { + set flags "$type $level" + verbose -log "Testing vect-args, $flags" 1 + dg-test $srcdir/$subdir/vect-args.c $flags "" + } + } +} + +# Everything else. +set tests [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] +set tests [prune $tests $srcdir/$subdir/vect-args.c] + +# Main loop. +dg-runtest $tests "" $DEFAULT_CFLAGS + +# All done. +clearcap-finish +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/pr70314.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/pr70314.c new file mode 100644 index 0000000000000000000000000000000000000000..aad8dd9b57e97559f87ea41327997e24b52ea304 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/pr70314.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=skylake-avx512 -O2" } */ +/* { dg-final { scan-assembler-times "cmp" 2 } } */ +/* { dg-final { scan-assembler-not "and" } } */ + +typedef long vec __attribute__((vector_size(16))); +vec f(vec x, vec y){ + return (x < 5) & (y < 8); +} + +/* On x86_64, currently + vpcmpq $2, .LC1(%rip), %xmm1, %k1 + vpcmpq $2, .LC0(%rip), %xmm0, %k0{%k1} + vpmovm2q %k0, %xmm0 +*/ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/pr94980.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/pr94980.c new file mode 100644 index 0000000000000000000000000000000000000000..488f94abec9473aa0e094dab2948971fecf9b2bd --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/i386/pr94980.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx512vl" } */ + +int __attribute__((__vector_size__(16))) v; + +void +foo(void) +{ + 0 <= (0 != v) >= 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-1.c new file mode 100644 index 0000000000000000000000000000000000000000..5c5623d9b2f75a9f54e9502125119de2092a2e58 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-mno-inline-atomics" } */ +/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ +/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_add_1" } } */ +/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_nand_1" } } */ +/* { dg-final { scan-assembler "\tcall\t__sync_bool_compare_and_swap_1" } } */ + +char foo; +char bar; +char baz; + +int +main () +{ + __sync_fetch_and_add(&foo, 1); + __sync_fetch_and_nand(&bar, 1); + __sync_bool_compare_and_swap (&baz, 1, 2); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-2.c new file mode 100644 index 0000000000000000000000000000000000000000..01b439086924243fc5892d1833a2093615e3049a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* Verify that subword atomics do not generate calls. */ +/* { dg-options "-minline-atomics" } */ +/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ +/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */ +/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */ +/* { dg-final { scan-assembler-not "\tcall\t__sync_bool_compare_and_swap_1" } } */ + +#include "inline-atomics-1.c" \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-3.c new file mode 100644 index 0000000000000000000000000000000000000000..709f3734377b5a630f29a6c49a7c4d0efcc27f25 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-3.c @@ -0,0 +1,569 @@ +/* Check all char alignments. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ + +/* Test the execution of the __atomic_*OP builtin routines for a char. */ + +extern void abort(void); + +char count, res; +const char init = ~0; + +struct A +{ + char a; + char b; + char c; + char d; +} __attribute__ ((packed)) A; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub (char* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and (char* v) +{ + *v = init; + + if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand (char* v) +{ + *v = init; + + if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor (char* v) +{ + *v = init; + count = 0; + + if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch (char* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch (char* v) +{ + *v = init; + + if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + *v = init; + if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch (char* v) +{ + *v = init; + + if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch (char* v) +{ + *v = init; + count = 0; + + if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add (char* v) +{ + *v = 0; + count = 1; + + __atomic_add_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_CONSUME); + if (*v != 2) + abort (); + + __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); + if (*v != 3) + abort (); + + __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); + if (*v != 4) + abort (); + + __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 5) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); + if (*v != 6) + abort (); +} + + +void +test_sub (char* v) +{ + *v = res = 20; + count = 0; + + __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); + if (*v != --res) + abort (); +} + +void +test_and (char* v) +{ + *v = init; + + __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); + if (*v != 0) + abort (); + + *v = init; + __atomic_fetch_and (v, init, __ATOMIC_CONSUME); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, init, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_nand (char* v) +{ + *v = init; + + __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); + if (*v != 0) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); + if (*v != init) + abort (); +} + + + +void +test_xor (char* v) +{ + *v = init; + count = 0; + + __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_or (char* v) +{ + *v = 0; + count = 1; + + __atomic_or_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_CONSUME); + if (*v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); + if (*v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); + if (*v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); + if (*v != 63) + abort (); +} + +int +main () +{ + char* V[] = {&A.a, &A.b, &A.c, &A.d}; + + for (int i = 0; i < 4; i++) { + test_fetch_add (V[i]); + test_fetch_sub (V[i]); + test_fetch_and (V[i]); + test_fetch_nand (V[i]); + test_fetch_xor (V[i]); + test_fetch_or (V[i]); + + test_add_fetch (V[i]); + test_sub_fetch (V[i]); + test_and_fetch (V[i]); + test_nand_fetch (V[i]); + test_xor_fetch (V[i]); + test_or_fetch (V[i]); + + test_add (V[i]); + test_sub (V[i]); + test_and (V[i]); + test_nand (V[i]); + test_xor (V[i]); + test_or (V[i]); + } + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-4.c new file mode 100644 index 0000000000000000000000000000000000000000..eecfaae5cc6530871cd1bf6769467057af2b9e7c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-4.c @@ -0,0 +1,566 @@ +/* Check all short alignments. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-2.c */ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ + +/* Test the execution of the __atomic_*OP builtin routines for a short. */ + +extern void abort(void); + +short count, res; +const short init = ~0; + +struct A +{ + short a; + short b; +} __attribute__ ((packed)) A; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub (short* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and (short* v) +{ + *v = init; + + if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand (short* v) +{ + *v = init; + + if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor (short* v) +{ + *v = init; + count = 0; + + if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch (short* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch (short* v) +{ + *v = init; + + if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + *v = init; + if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch (short* v) +{ + *v = init; + + if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch (short* v) +{ + *v = init; + count = 0; + + if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add (short* v) +{ + *v = 0; + count = 1; + + __atomic_add_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_CONSUME); + if (*v != 2) + abort (); + + __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); + if (*v != 3) + abort (); + + __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); + if (*v != 4) + abort (); + + __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 5) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); + if (*v != 6) + abort (); +} + + +void +test_sub (short* v) +{ + *v = res = 20; + count = 0; + + __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); + if (*v != --res) + abort (); +} + +void +test_and (short* v) +{ + *v = init; + + __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); + if (*v != 0) + abort (); + + *v = init; + __atomic_fetch_and (v, init, __ATOMIC_CONSUME); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, init, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_nand (short* v) +{ + *v = init; + + __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); + if (*v != 0) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); + if (*v != init) + abort (); +} + + + +void +test_xor (short* v) +{ + *v = init; + count = 0; + + __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_or (short* v) +{ + *v = 0; + count = 1; + + __atomic_or_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_CONSUME); + if (*v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); + if (*v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); + if (*v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); + if (*v != 63) + abort (); +} + +int +main () { + short* V[] = {&A.a, &A.b}; + + for (int i = 0; i < 2; i++) { + test_fetch_add (V[i]); + test_fetch_sub (V[i]); + test_fetch_and (V[i]); + test_fetch_nand (V[i]); + test_fetch_xor (V[i]); + test_fetch_or (V[i]); + + test_add_fetch (V[i]); + test_sub_fetch (V[i]); + test_and_fetch (V[i]); + test_nand_fetch (V[i]); + test_xor_fetch (V[i]); + test_or_fetch (V[i]); + + test_add (V[i]); + test_sub (V[i]); + test_and (V[i]); + test_nand (V[i]); + test_xor (V[i]); + test_or (V[i]); + } + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-5.c new file mode 100644 index 0000000000000000000000000000000000000000..52093894a79760fd806d7651e648b7a46e88460d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-5.c @@ -0,0 +1,87 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-1.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */ + +extern void abort(void); + +char v = 0; +char expected = 0; +char max = ~0; +char desired = ~0; +char zero = 0; + +#define STRONG 0 +#define WEAK 1 + +int +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-6.c new file mode 100644 index 0000000000000000000000000000000000000000..8fee8c4481190d5307e8d990628084e367c52e0d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-6.c @@ -0,0 +1,87 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-2.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */ + +extern void abort(void); + +short v = 0; +short expected = 0; +short max = ~0; +short desired = ~0; +short zero = 0; + +#define STRONG 0 +#define WEAK 1 + +int +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-7.c new file mode 100644 index 0000000000000000000000000000000000000000..24c344c0ce3d6929d6c7b66ef55048f3e7203626 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-7.c @@ -0,0 +1,69 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-1.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_exchange_n builtin for a char. */ + +extern void abort(void); + +char v, count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) + abort (); + count++; + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-8.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-8.c new file mode 100644 index 0000000000000000000000000000000000000000..edc212df04e21a110340dcf9a3bd8fbfaacd1560 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/inline-atomics-8.c @@ -0,0 +1,69 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-2.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_X builtin for a short. */ + +extern void abort(void); + +short v, count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) + abort (); + count++; + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/riscv.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/riscv.exp new file mode 100644 index 0000000000000000000000000000000000000000..483fe91898cf2a23889a30760fc62626f8abd6d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gcc.target/riscv/riscv.exp @@ -0,0 +1,41 @@ +# Copyright (C) 2017-2020 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a RISC-V target. +if ![istarget riscv*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..89a4da5baf19cf0513c04d08d14100ff48bccf26 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/dg.exp @@ -0,0 +1,65 @@ +# Copyright (C) 2004-2020 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gfortran-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_FFLAGS +if ![info exists DEFAULT_FFLAGS] then { + set DEFAULT_FFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +global gfortran_test_path +global gfortran_aux_module_flags +set gfortran_test_path $srcdir/$subdir +set gfortran_aux_module_flags $DEFAULT_FFLAGS +proc dg-compile-aux-modules { args } { + global gfortran_test_path + global gfortran_aux_module_flags + if { [llength $args] != 2 } { + error "dg-compile-aux-modules: needs one argument" + return + } + + set level [info level] + if { [info procs dg-save-unknown] != [list] } { + rename dg-save-unknown dg-save-unknown-level-$level + } + + dg-test $gfortran_test_path/[lindex $args 1] "" $gfortran_aux_module_flags + # cleanup-modules is intentionally not invoked here. + + if { [info procs dg-save-unknown-level-$level] != [list] } { + rename dg-save-unknown-level-$level dg-save-unknown + } +} + +# Main loop. +gfortran-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $DEFAULT_FFLAGS + +gfortran-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/g77/*.\[fF\] ] ] "" $DEFAULT_FFLAGS + + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-3.f90 b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-3.f90 new file mode 100644 index 0000000000000000000000000000000000000000..e1df4ef7cd1e548d270d8af78c8571eac9cc1e57 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-3.f90 @@ -0,0 +1,213 @@ +! { dg-do compile { target { aarch64*-*-linux* } } } +! { dg-options "-O3 -march=armv8.2-a+sve -funroll-loops -ffast-math -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param branch-prob-threshold=50 --param filter-mode=0" } + +program main + + IMPLICIT NONE + INTEGER :: ids,ide, jds,jde, kds,kde + INTEGER,parameter :: ims=-4,kms=1,jms=-4 + INTEGER,parameter :: ime=210,kme=36,jme=192 + INTEGER :: its,ite, jts,jte, kts,kte + INTEGER :: number_of_small_timesteps,rk_step, rk_order, step + + REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: t_1, t_2, c2a, p, ph, pm1, al, alt + + + REAL, DIMENSION(ims:ime, jms:jme) :: mu, muts + + REAL, DIMENSION(kms:kme) :: dnw, rdnw, znu + + REAL :: rdx,rdy + REAL :: dts, t0, smdiv + REAL :: random1,time_begin,time_end,total_time + + INTEGER :: i, j, k + INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end + INTEGER :: i_endu, j_endv + INTEGER :: interval=1 + INTEGER :: epoch,iter + + LOGICAL :: non_hydrostatic + + data ids, jds, kds, its, jts, kts /6*1/ + data ide, ite /2*205/ + data jde, jte /2*187/ + data kde, kte /2*36/ + + number_of_small_timesteps = 1 + rk_step = 3 + rk_order = 1 + dts = 1. + + rdx = 1. + rdy = 1. + + t0 = 0. + smdiv = 1. + step = 1 + non_hydrostatic = .true. + + call random_number(random1) + interval = random1*100 + interval=1 + + call random_seed(put=(/(i,i=1,10000,interval)/)) + + call random_number(alt) + call random_number(c2a) + call random_number(ph) + call random_number(pm1) + call random_number(mu) + call random_number(muts) + call random_number(dnw) + call random_number(rdnw) + call random_number(znu) + + do iter=1,2 + call calc_p_rho( al, p, ph, & + alt, t_2, t_1, c2a, pm1, & + mu, muts, znu, t0, & + rdnw, dnw, smdiv, & + non_hydrostatic, step, & + ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme, & + its,ite, jts,jte, kts,kte ) + + enddo + +end program + + +SUBROUTINE calc_p_rho( al, p, ph, & + alt, t_2, t_1, c2a, pm1, & + mu, muts, znu, t0, & + rdnw, dnw, smdiv, & + non_hydrostatic, step, & + ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme, & + its,ite, jts,jte, kts,kte ) + + IMPLICIT NONE ! religion first + !asb +! declarations for the stuff coming in + + INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde + INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme + INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte + + INTEGER, INTENT(IN ) :: step + + REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: al, & + p + + REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: alt, & + t_2, & + t_1, & + c2a + + REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph, pm1 + + REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: mu, & + muts + + REAL, DIMENSION(kms:kme) , INTENT(IN ) :: dnw, & + rdnw, & + znu + + REAL, INTENT(IN ) :: t0, smdiv + + LOGICAL, INTENT(IN ) :: non_hydrostatic + +! local variables + + INTEGER :: i, j, k + INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end + REAL :: ptmp + + i_start = its + i_end = min(ite,ide-1) + j_start = jts + j_end = min(jte,jde-1) + k_start = kts + k_end = min(kte,kde-1) + + IF (non_hydrostatic) THEN + DO j=j_start, j_end + DO k=k_start, k_end + DO i=i_start, i_end + +! al computation is all dry, so ok with moisture + + al(i,k,j)=-1./muts(i,j)*(alt(i,k,j)*mu(i,j) & + +rdnw(k)*(ph(i,k+1,j)-ph(i,k,j))) + +! this is temporally linearized p, no moisture correction needed + + p(i,k,j)=c2a(i,k,j)*(alt(i,k,j)*(t_2(i,k,j)-mu(i,j)*t_1(i,k,j)) & + /(muts(i,j)*(t0+t_1(i,k,j)))-al (i,k,j)) + + ENDDO + ENDDO + ENDDO + + ELSE ! hydrostatic calculation + + DO j=j_start, j_end + DO k=k_start, k_end + DO i=i_start, i_end + p(i,k,j)=mu(i,j)*znu(k) + al(i,k,j)=alt(i,k,j)*(t_2(i,k,j)-mu(i,j)*t_1(i,k,j)) & + /(muts(i,j)*(t0+t_1(i,k,j)))-p(i,k,j)/c2a(i,k,j) + ph(i,k+1,j)=ph(i,k,j)-dnw(k)*(muts(i,j)*al (i,k,j) & + +mu(i,j)*alt(i,k,j)) + ENDDO + ENDDO + ENDDO + + END IF + +! divergence damping setup + + IF (step == 0) then ! we're initializing small timesteps + DO j=j_start, j_end + DO k=k_start, k_end + DO i=i_start, i_end + pm1(i,k,j)=p(i,k,j) + ENDDO + ENDDO + ENDDO + ELSE ! we're in the small timesteps + DO j=j_start, j_end ! and adding div damping component + DO k=k_start, k_end + DO i=i_start, i_end + ptmp = p(i,k,j) + p(i,k,j) = p(i,k,j) + smdiv*(p(i,k,j)-pm1(i,k,j)) + pm1(i,k,j) = ptmp + ENDDO + ENDDO + ENDDO + END IF + +END SUBROUTINE calc_p_rho + +! { dg-final { scan-tree-dump-times "ref_count = (?:\[3-9\]|\[1-9\]\\d{1,}), ninsns = \[1-9\]\\d*, mem_to_insn_ratio = 0.\[2-9\]\\d*" 6 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "Tracing succeeded" 48 "llc_allocate" } } +! { dg-final { scan-tree-dump-not "Tracing failed" "llc_allocate" } } +! { dg-final { scan-tree-dump-not "static_data_size:" "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\{ (?:\\d+\\(\\d+\\) ){2}\}" 3 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\{ (?:\\d+\\(\\d+\\) ){4}\}" 1 "llc_allocate" } } +! { dg-final { scan-tree-dump-not ", size: (?!(0\.000000))" "llc_allocate" } } +! { dg-final { scan-tree-dump-times ", size: 0\.000000" 28 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tp\\t\\(0.000000, 3, 3, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tpm1\\t\\(0.000000, 3, 2, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tph\\t\\(0.000000, 3, 2, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tal\\t\\(0.000000, 3, 1, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\talt\\t\\(0.000000, 3, 1, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tt_1\\t\\(0.000000, 3, 1, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tt_2\\t\\(0.000000, 3, 1, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tc2a\\t\\(0.000000, 3, 1, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tmu\\t\\(0.000000, 2, 1, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "\\d\\tmuts\\t\\(0.000000, 2, 1, 0\\)" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "runtime issue" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "static issue" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "insert svprfd" 2 "llc_allocate" } } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-allocate.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-allocate.exp new file mode 100644 index 0000000000000000000000000000000000000000..0683417849332f7624d66cc745ca2927ad1f99ff --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-allocate.exp @@ -0,0 +1,29 @@ +# Copyright (C) 2022-2023 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +load_lib gfortran-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +gfortran-dg-runtest [lsort \ + [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" "" + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-trace-multiple-base-var.f90 b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-trace-multiple-base-var.f90 new file mode 100644 index 0000000000000000000000000000000000000000..5e9a4cf7e81dc695a3a89ec0abda77e8e01ec560 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-trace-multiple-base-var.f90 @@ -0,0 +1,63 @@ +! { dg-do compile { target { aarch64*-*-linux* } } } +! { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno" } + +MODULE INPUT + IMPLICIT NONE + + INTEGER, PARAMETER :: wp = 8, jpi = 25, jpj = 39, jpk = 31, kjpt = 2 + + INTEGER :: kt = 1, jpkm1 = 30, jpjm1 = 38, fs_jpim1 = 24, fs_2 = 2 + REAL(wp), DIMENSION(jpi, jpj) :: e12t + REAL(wp), DIMENSION(jpi, jpj, jpk) :: fse3t_n + REAL(wp), DIMENSION(jpi, jpj, jpk, kjpt) :: pta + +END MODULE INPUT + +PROGRAM MAIN + USE INPUT + + IMPLICIT NONE + + INTEGER :: EPOCH + +! Initialize arrays + + e12t = 1 + fse3t_n = 1 + pta = 1 +! + + DO EPOCH=1,2 + CALL tra_ldf_iso + ENDDO + +END PROGRAM MAIN + +SUBROUTINE tra_ldf_iso + USE INPUT + + IMPLICIT NONE + ! + INTEGER :: ji, jj, jk, jn ! dummy loop indices + REAL(wp) :: zbtr, ztra ! - - + REAL(wp), DIMENSION(jpi, jpj, jpk) :: ztfw + + DO jn = 1, kjpt + ztfw(:, :, 1) = 0.e0; ztfw(:, :, jpk) = 0.e0 + + DO jk = 1, jpkm1 + DO jj = 2, jpjm1 + DO ji = fs_2, fs_jpim1 ! vector opt. + zbtr = 1.0/(e12t(ji, jj)*fse3t_n(ji, jj, jk)) + ztra = (ztfw(ji, jj, jk) - ztfw(ji, jj, jk + 1))*zbtr + pta(ji, jj, jk, jn) = pta(ji, jj, jk, jn) + ztra + END DO + END DO + END DO + ! + END DO + ! +END SUBROUTINE tra_ldf_iso + +! { dg-final { scan-tree-dump-times "Traced variables at vectp_ztfw" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "Tracing unusual number or occurrences of base variables. Choose ztfw." 2 "llc_allocate" } } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-unknown-type-size-unit.f90 b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-unknown-type-size-unit.f90 new file mode 100644 index 0000000000000000000000000000000000000000..d76c75b5b6dce01be86bd4b1c0fe914fd521d3eb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-unknown-type-size-unit.f90 @@ -0,0 +1,58 @@ +! { dg-do compile { target { aarch64*-*-linux* } } } +! { dg-options "-c -O3 -march=armv8.2-a+sve -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param filter-kernels=0 --param issue-topn=1 --param mem-access-ratio=5 --param mem-access-num=1" } + +Module module_domain + IMPLICIT NONE + + REAL, PARAMETER :: g = 9.8 + TYPE :: grid_type + REAL, POINTER :: phb(:,:,:), ph_2(:,:,:), p(:,:,:), pb(:,:,:) + REAL, POINTER :: fnm(:), fnp(:) + END TYPE +END Module + +SUBROUTINE calc_p8w(p8w, ix, iy, k_start, k_end) + + USE module_domain + !USE module_model_constants + + IMPLICIT NONE + + + !TYPE (domain), INTENT(IN) :: grid + INTEGER, INTENT(IN) :: k_start, k_end, ix, iy + REAL, DIMENSION(k_start:k_end), INTENT(OUT) :: p8w + + + INTEGER :: k + REAL :: z0, z1, z2, w1, w2 + REAL, DIMENSION(k_start:k_end) :: z_at_w + REAL, DIMENSION(k_start:k_end-1) :: z + TYPE (grid_type), POINTER :: grid + + + DO k = k_start, k_end + z_at_w(k) = (grid%phb(ix,k,iy)+grid%ph_2(ix,k,iy))/g + END DO + + DO k = k_start, k_end-1 + z(k) = 0.5*(z_at_w(k) + z_at_w(k+1)) + END DO + + DO k = k_start+1, k_end-1 + p8w(k) = grid%fnm(k)*(grid%p(ix,k,iy)+grid%pb(ix,k,iy)) + & + grid%fnp(k)*(grid%p(ix,k-1,iy)+grid%pb(ix,k-1,iy)) + END DO + + z0 = z_at_w(k_start) + z1 = z(k_start) + z2 = z(k_start+1) + w1 = (z0 - z2)/(z1 - z2) + w2 = 1. - w1 + p8w(k_start) = w1*(grid%p(ix,k_start,iy)+grid%pb(ix,k_start,iy)) + & + w2*(grid%p(ix,k_start+1,iy)+grid%pb(ix,k_start+1,iy)) + +END SUBROUTINE calc_p8w + +! { dg-final { scan-tree-dump-times "runtime issue" 1 "llc_allocate" } } +! { dg-final { scan-tree-dump-times "static issue" 1 "llc_allocate" } } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-wrf-4-outer-loop-num.f90 b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-wrf-4-outer-loop-num.f90 new file mode 100644 index 0000000000000000000000000000000000000000..728b61ea3dbf34151b8d863a5e167e4eaa03425f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/gfortran.dg/llc-allocate/llc-wrf-4-outer-loop-num.f90 @@ -0,0 +1,320 @@ +! { dg-do compile { target { aarch64*-*-linux* } } } +! { dg-options "-O3 -march=armv8.2-a+sve -static -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param=branch-prob-threshold=50 --param=filter-kernels=0 --param=mem-access-num=2 --param=issue-topn=2 --param=force-issue=1 --param=outer-loop-nums=3" } +!include "module_small_step_em.F90" + +Module add_type + IMPLICIT NONE + + TYPE :: grid_config_rec_type + LOGICAL :: open_xs + LOGICAL :: open_ys + LOGICAL :: open_xe + LOGICAL :: open_ye + LOGICAL :: symmetric_xs + LOGICAL :: symmetric_xe + LOGICAL :: symmetric_ys + LOGICAL :: symmetric_ye + LOGICAL :: polar + LOGICAL :: nested + LOGICAL :: periodic_x + LOGICAL :: specified + END TYPE +END Module + +program main + + +! include "module_small_step_em_modify.F90" + +! use module_small_step_em +! use module_small_step_em_modify + + use add_type + + IMPLICIT NONE + INTEGER :: ids,ide, jds,jde, kds,kde + INTEGER,parameter :: ims=-4,kms=1,jms=-4 + INTEGER,parameter :: ime=210,kme=36,jme=192 + INTEGER :: its,ite, jts,jte, kts,kte + INTEGER :: number_of_small_timesteps,rk_step, rk_order, step, spec_zone + + REAL, DIMENSION(ims:ime, kms:kme, jms:jme, 1:8) :: llcRefresh + REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: u, v, u_1, v_1, t_1, ww_1, ft!u, v, u_1, v_1, w_1, t_1, ww1, ww_1,ph_1, ft + REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: u_save, v_save, w_save, t_save, ph_save,h_diabatic + ! REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: u_2, v_2, w_2, t_2, ph_2 + ! REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: c2a, ww_save, cqw, cqu, cqv, alpha, gamma, a + REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: ww!pb, p, ph, php, pm1, al, alt, ww, random_array + ! REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: ru_tend, rv_tend + REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: t, t_ave, uam, vam, wwam + + REAL, DIMENSION(ims:ime, jms:jme) :: mu_1,mu_2, mu + REAL, DIMENSION(ims:ime, jms:jme) :: mub, muu, muv, mut, & + msfux, msfuy, & + msfvx, msfvx_inv, msfvy, & + msftx, msfty + + REAL, DIMENSION(ims:ime, jms:jme) :: muus, muvs, muts, mudf, muave + REAL, DIMENSION(ims:ime, jms:jme) :: mu_save, mu_tend + + REAL, DIMENSION(kms:kme) :: rdn, rdnw,dnw, fnm, fnp, znu + + REAL :: rdx,rdy + REAL :: dts, cf1, cf2, cf3, t0, emdiv, smdiv, epssm, g + REAL :: random1,time_begin,time_end,total_time + + INTEGER :: i, j, k + INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end + INTEGER :: i_endu, j_endv + INTEGER :: interval=1 + INTEGER :: epoch + + LOGICAL :: non_hydrostatic, top_lid + + + TYPE (grid_config_rec_type) :: config_flags + config_flags%open_xs = .true. + config_flags%open_ys = .true. + config_flags%open_xe = .true. + config_flags%open_ye = .true. + config_flags%symmetric_xs = .true. + config_flags%symmetric_xe = .true. + config_flags%symmetric_ys = .true. + config_flags%symmetric_ye = .true. + config_flags%polar = .true. + config_flags%nested = .true. + config_flags%periodic_x = .true. + config_flags%specified = .true. + + data ids, jds, kds, its, jts, kts /6*1/ + data ide, ite /2*205/ + data jde, jte /2*187/ + data kde, kte /2*98/ + + number_of_small_timesteps = 1 + rk_step = 1 + rk_order = 1 + dts = 1. + epssm = 1. + g = 1. + + rdx = 1. + rdy = 1. + dts = 1. + cf1 = 1. + cf2 = 1. + cf3 = 1. + + t0 = 0. + smdiv = 1. + emdiv = 1. + step = 1 + spec_zone = 1 + + non_hydrostatic = .true. + top_lid = .true. + + interval=1 + + + total_time=0 + + call random_seed(put=(/(i,i=1,10000,interval)/)) + + call random_number(u) + call random_number(v) + call random_number(u_1) + call random_number(v_1) + call random_number(t_1) + call random_number(ft) + + call random_number(ww) + call random_number(ww_1) + call random_number(t) + call random_number(t_ave) + call random_number(uam) + call random_number(vam) + call random_number(wwam) + + call random_number(muu) + call random_number(muv) + call random_number(mut) + call random_number(msfux) + call random_number(msfuy) + call random_number(msfvx) + call random_number(msfvx_inv) + call random_number(msfvy) + call random_number(msftx) + call random_number(msfty) + call random_number(mu_tend) + + call random_number(muave) + call random_number(muts) + call random_number(mudf) + call random_number(mu) + + call random_number(fnm) + call random_number(fnp) + call random_number(dnw) + call random_number(rdnw) + + DO j=jms, jme + DO k=kms, kme + DO i=ims, ime + + llcRefresh(i,k,j,1)=i+k+j+7 + + ENDDO + ENDDO + ENDDO + + do epoch = 1,2 + call advance_mu_t_fortran_plu( ww, ww_1, u, u_1, v, v_1, & + mu, mut, muave, muts, muu, muv, & + mudf, uam, vam, wwam, t, t_1, & + t_ave, ft, mu_tend, & + rdx, rdy, dts, epssm, & + dnw, fnm, fnp, rdnw, & + msfux, msfuy, msfvx, msfvx_inv, & + msfvy, msftx, msfty, & + step, config_flags, & + ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme, & + its, ite, jts, jte, kts, kte ) + enddo +end program + + + +SUBROUTINE advance_mu_t_fortran_plu( ww, ww_1, u, u_1, v, v_1, & + mu, mut, muave, muts, muu, muv, & + mudf, uam, vam, wwam, t, t_1, & + t_ave, ft, mu_tend, & + rdx, rdy, dts, epssm, & + dnw, fnm, fnp, rdnw, & + msfux, msfuy, msfvx, msfvx_inv, & + msfvy, msftx, msfty, & + step, config_flags, & + ids, ide, jds, jde, kds, kde, & + ims, ime, jms, jme, kms, kme, & + its, ite, jts, jte, kts, kte ) + use add_type + + IMPLICIT NONE ! religion first + + ! stuff coming in + + TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags + INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde + INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme + INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte + + INTEGER, INTENT(IN ) :: step + + REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), & + INTENT(IN ) :: & + u, & + v, & + u_1, & + v_1, & + t_1, & + ft + + REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), & + INTENT(INOUT) :: & + ww, & + ww_1, & + t, & + t_ave, & + uam, & + vam, & + wwam + + REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, & + muv, & + mut, & + msfux,& + msfuy,& + msfvx,& + msfvx_inv,& + msfvy,& + msftx,& + msfty,& + mu_tend + + REAL, DIMENSION( ims:ime , jms:jme ), INTENT( INOUT) :: muave, & + muts, & + mudf + + REAL, DIMENSION( ims:ime , jms:jme ), INTENT(INOUT) :: mu + + REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnm, & + fnp, & + dnw, & + rdnw + + + REAL, INTENT(IN ) :: rdx, & + rdy, & + dts, & + epssm + + REAL, DIMENSION (its:ite, kts:kte) :: wdtn, dvdxi + REAL, DIMENSION (its:ite) :: dmdt + + INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end + INTEGER :: i_endu, j_endv + REAL :: acc + + INTEGER :: ubv, lbv, t1, t2, t3, t4, ceild, floord + + ceild(t1, t2) = ceiling(REAL(t1)/REAL(t2)) + floord(t1, t2) = floor(REAL(t1)/REAL(t2)) + i_start = its + i_end = min(ite,ide-1) + j_start = jts + j_end = min(jte,jde-1) + k_start = kts + k_end = kte-1 + IF ( .NOT. config_flags%periodic_x )THEN + IF ( config_flags%specified .or. config_flags%nested ) then + i_start = max(its,ids+1) + i_end = min(ite,ide-2) + ENDIF + ENDIF + IF ( config_flags%specified .or. config_flags%nested ) then + j_start = max(jts,jds+1) + j_end = min(jte,jde-2) + ENDIF + + i_endu = ite + j_endv = jte + + DO j = j_start, j_end + + DO i=i_start, i_end + dmdt(i) = 0. + ENDDO + + DO k=k_start, k_end + DO i=i_start, i_end + dvdxi(i,k) = msftx(i,j)*msfty(i,j)*( & + rdy*((v(i,k,j+1)+muv(i,j+1)*v_1(i,k,j+1)*msfvx_inv(i,j+1)) & + -(v(i,k,j )+muv(i,j )*v_1(i,k,j)*msfvx_inv(i,j ))) & + +rdx*((u(i+1,k,j)+muu(i+1,j)*u_1(i+1,k,j)/msfuy(i+1,j)) & + -(u(i,k,j )+muu(i ,j)*u_1(i,k,j )/msfuy(i,j)) )) + dmdt(i) = dmdt(i) + dnw(k)*dvdxi(i,k) + ENDDO + ENDDO + DO i=i_start, i_end + muave(i,j) = mu(i,j) + mu(i,j) = mu(i,j)+dts*(dmdt(i)+mu_tend(i,j)) + mudf(i,j) = (dmdt(i)+mu_tend(i,j)) ! save tendency for div dampfilter + muts(i,j) = mut(i,j)+mu(i,j) + muave(i,j) =.5*((1.+epssm)*mu(i,j)+(1.-epssm)*muave(i,j)) + ENDDO + ENDDO +END SUBROUTINE advance_mu_t_fortran_plu + +! { dg-final { scan-tree-dump "issue_llc_hint" "llc_allocate" } } +! { dg-final { scan-tree-dump-times "analyze_nested_kernels" 2 "llc_allocate" } } +! { dg-final { scan-tree-dump "Stop tracing the outer loop depth" "llc_allocate" } } diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/asan-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/asan-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..2124607245ef1068e5ddf234cf45f1c8b70ddf18 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/asan-dg.exp @@ -0,0 +1,352 @@ +# Copyright (C) 2012-2020 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 +# . + +# Return 1 if compilation with -fsanitize=address is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fsanitize_address {} { + if ![check_no_compiler_messages fsanitize_address executable { + int main (void) { return 0; } + }] { + return 0; + } + + # asan doesn't work if there's a ulimit on virtual memory. + if ![is_remote target] { + if [catch {exec sh -c "ulimit -v"} ulimit_v] { + # failed to get ulimit + } elseif [regexp {^[0-9]+$} $ulimit_v] { + # ulimit -v gave a numeric limit + warning "skipping asan tests due to ulimit -v" + return 0; + } + } + + return 1; +} + +proc asan_include_flags {} { + global srcdir + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set flags "-I$srcdir/../../libsanitizer/include" + + return "$flags" +} + +# +# asan_link_flags -- compute library path and flags to find libasan. +# (originally from g++.exp) +# + +proc asan_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + global asan_saved_library_path + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + set asan_saved_library_path $ld_library_path + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"] + || [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/ " + append flags " -B${gccpath}/libsanitizer/asan/ " + append flags " -L${gccpath}/libsanitizer/asan/.libs " + append ld_library_path ":${gccpath}/libsanitizer/asan/.libs" + } + } else { + global tool_root_dir + + set libasan [lookfor_file ${tool_root_dir} libasan] + if { $libasan != "" } { + append flags "-L${libasan} " + append ld_library_path ":${libasan}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# asan_init -- called at the start of each subdir of tests +# + +proc asan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global asan_saved_TEST_ALWAYS_FLAGS + global asan_saved_ALWAYS_CXXFLAGS + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[asan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[asan_link_flags [get_multilibs]]" + } + } + + set include_flags "[asan_include_flags]" + + if [info exists TEST_ALWAYS_FLAGS] { + set asan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set asan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=address -g $include_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $include_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $include_flags" + } + } +} + +# +# asan_finish -- called at the start of each subdir of tests +# + +proc asan_finish { args } { + global TEST_ALWAYS_FLAGS + global asan_saved_TEST_ALWAYS_FLAGS + global asan_saved_ALWAYS_CXXFLAGS + global asan_saved_library_path + global ld_library_path + + if [info exists asan_saved_ALWAYS_CXXFLAGS ] { + set ALWAYS_CXXFLAGS $asan_saved_ALWAYS_CXXFLAGS + } else { + if [info exists asan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $asan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + set ld_library_path $asan_saved_library_path + set_ld_library_path_env_vars + clear_effective_target_cache +} + +# Symbolize lines like +# #2 0xdeadbeef (/some/path/libsanitizer.so.0.0.0+0xbeef) +# in $output using addr2line to +# #2 0xdeadbeef in foobar file:123 +proc asan_symbolize { output } { + set addresses [regexp -inline -all -line "^ *#\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+)\[+\](0x\[0-9a-f\]+)\[)\]$" "$output"] + if { [llength $addresses] > 0 } { + set addr2line_name [find_binutils_prog addr2line] + set idx 1 + while { $idx < [llength $addresses] } { + set key [regsub -all "\[\]\[\]" [lindex $addresses $idx] "\\\\&"] + set val [lindex $addresses [expr $idx + 1]] + lappend arr($key) $val + set idx [expr $idx + 3] + } + foreach key [array names arr] { + set args "-f -e $key $arr($key)" + set status [remote_exec host "$addr2line_name" "$args"] + if { [lindex $status 0] > 0 } continue + regsub -all "\r\n" [lindex $status 1] "\n" addr2line_output + regsub -all "\[\n\r\]BFD: \[^\n\r\]*" $addr2line_output "" addr2line_output + regsub -all "^BFD: \[^\n\r\]*\[\n\r\]" $addr2line_output "" addr2line_output + set addr2line_output [regexp -inline -all -line "^\[^\n\r]*" $addr2line_output] + set idx 0 + foreach val $arr($key) { + if { [expr $idx + 1] < [llength $addr2line_output] } { + set fnname [lindex $addr2line_output $idx] + set fileline [lindex $addr2line_output [expr $idx + 1]] + if { "$fnname" != "??" } { + set newkey "$key+$val" + set repl($newkey) "$fnname $fileline" + } + set idx [expr $idx + 2] + } + } + } + set idx 0 + set new_output "" + while {[regexp -start $idx -indices " #\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+\[+\]0x\[0-9a-f\]+)\[)\]" "$output" -> addr] > 0} { + set low [lindex $addr 0] + set high [lindex $addr 1] + set val [string range "$output" $low $high] + append new_output [string range "$output" $idx [expr $low - 2]] + if [info exists repl($val)] { + append new_output "in $repl($val)" + } else { + append new_output "($val)" + } + set idx [expr $high + 2] + } + append new_output [string range "$output" $idx [string length "$output"]] + return "$new_output" + } + return "$output" +} + +# Return a list of gtest tests, printed in the form +# DEJAGNU_GTEST_TEST AddressSanitizer_SimpleDeathTest +# DEJAGNU_GTEST_TEST AddressSanitizer_VariousMallocsTest +proc asan_get_gtest_test_list { output } { + set idx 0 + set ret "" + while {[regexp -start $idx -indices "DEJAGNU_GTEST_TEST (\[^\n\r\]*)(\r\n|\n|\r)" "$output" -> testname] > 0} { + set low [lindex $testname 0] + set high [lindex $testname 1] + set val [string range "$output" $low $high] + lappend ret $val + set idx [expr $high + 1] + } + return $ret +} + +# Return a list of gtest EXPECT_DEATH tests, printed in the form +# DEJAGNU_GTEST_EXPECT_DEATH1 statement DEJAGNU_GTEST_EXPECT_DEATH1 regexp DEJAGNU_GTEST_EXPECT_DEATH1 +# DEJAGNU_GTEST_EXPECT_DEATH2 other statement DEJAGNU_GTEST_EXPECT_DEATH2 other regexp DEJAGNU_GTEST_EXPECT_DEATH2 +proc asan_get_gtest_expect_death_list { output } { + set idx 0 + set ret "" + while {[regexp -start $idx -indices "DEJAGNU_GTEST_EXPECT_DEATH(\[0-9\]*)" "$output" -> id ] > 0} { + set low [lindex $id 0] + set high [lindex $id 1] + set val_id [string range "$output" $low $high] + if {[regexp -start $low -indices "$val_id (.*) DEJAGNU_GTEST_EXPECT_DEATH$val_id (.*) DEJAGNU_GTEST_EXPECT_DEATH$val_id\[\n\r\]" "$output" whole statement regexpr ] == 0} { break } + set low [lindex $statement 0] + set high [lindex $statement 1] + set val_statement [string range "$output" $low $high] + set low [lindex $regexpr 0] + set high [lindex $regexpr 1] + set val_regexpr [string range "$output" $low $high] + lappend ret [list "$val_id" "$val_statement" "$val_regexpr"] + set idx [lindex $whole 1] + } + return $ret +} + +# Replace ${tool}_load with a wrapper so that we can symbolize the output. +if { [info procs ${tool}_load] != [list] \ + && [info procs saved_asan_${tool}_load] == [list] } { + rename ${tool}_load saved_asan_${tool}_load + + proc ${tool}_load { program args } { + global tool + global asan_last_gtest_test_list + global asan_last_gtest_expect_death_list + set result [eval [list saved_asan_${tool}_load $program] $args] + set output [lindex $result 1] + set symbolized_output [asan_symbolize "$output"] + set asan_last_gtest_test_list [asan_get_gtest_test_list "$output"] + set asan_last_gtest_expect_death_list [asan_get_gtest_expect_death_list "$output"] + set result [list [lindex $result 0] $symbolized_output] + return $result + } +} + +# Utility for running gtest asan emulation under dejagnu, invoked via dg-final. +# Call pass if variable has the desired value, otherwise fail. +# +# Argument 0 handles expected failures and the like +proc asan-gtest { args } { + global tool + global asan_last_gtest_test_list + global asan_last_gtest_expect_death_list + + if { ![info exists asan_last_gtest_test_list] } { return } + if { [llength $asan_last_gtest_test_list] == 0 } { return } + if { ![isnative] || [is_remote target] } { return } + + set gtest_test_list $asan_last_gtest_test_list + unset asan_last_gtest_test_list + + if { [llength $args] >= 1 } { + switch [dg-process-target [lindex $args 0]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # This assumes that we are three frames down from dg-test, and that + # it still stores the filename of the testcase in a local variable "name". + # A cleaner solution would require a new DejaGnu release. + upvar 2 name testcase + upvar 2 prog prog + + set output_file "[file rootname [file tail $prog]].exe" + + foreach gtest $gtest_test_list { + set testname "$testcase $gtest" + set status -1 + + setenv DEJAGNU_GTEST_ARG "$gtest" + set result [${tool}_load ./$output_file $gtest] + unsetenv DEJAGNU_GTEST_ARG + set status [lindex $result 0] + set output [lindex $result 1] + if { "$status" == "pass" } { + pass "$testname execution test" + if { [info exists asan_last_gtest_expect_death_list] } { + set gtest_expect_death_list $asan_last_gtest_expect_death_list + foreach gtest_death $gtest_expect_death_list { + set id [lindex $gtest_death 0] + set testname "$testcase $gtest [lindex $gtest_death 1]" + set regexpr [lindex $gtest_death 2] + set status -1 + + setenv DEJAGNU_GTEST_ARG "$gtest:$id" + set result [${tool}_load ./$output_file "$gtest:$id"] + unsetenv DEJAGNU_GTEST_ARG + set status [lindex $result 0] + set output [lindex $result 1] + if { "$status" == "fail" } { + pass "$testname execution test" + if { ![regexp $regexpr ${output}] } { + fail "$testname output pattern test" + send_log "Output should match: $regexpr\n" + } else { + pass "$testname output pattern test" + } + } elseif { "$status" == "pass" } { + fail "$testname execution test" + } else { + $status "$testname execution test" + } + } + } + } else { + $status "$testname execution test" + } + unset asan_last_gtest_expect_death_list + } + + return +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/atomic-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/atomic-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..e9a30aff56bca9fa12933b6b7925c3117c341366 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/atomic-dg.exp @@ -0,0 +1,113 @@ +# Copyright (C) 2013-2020 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 +# . + +# +# atomic_link_flags -- compute library path and flags to find libatomic. +# (originally from g++.exp) +# + +proc atomic_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libatomic/.libs/libatomic.a"] + || [file exists "${gccpath}/libatomic/.libs/libatomic.${shlib_ext}"] } { + append flags " -B${gccpath}/libatomic/ " + append flags " -L${gccpath}/libatomic/.libs" + append ld_library_path ":${gccpath}/libatomic/.libs" + } + } else { + global tool_root_dir + + set libatomic [lookfor_file ${tool_root_dir} libatomic] + if { $libatomic != "" } { + append flags "-L${libatomic} " + append ld_library_path ":${libatomic}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# atomic_init -- called at the start of each subdir of tests +# + +proc atomic_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global atomic_saved_TEST_ALWAYS_FLAGS + global atomic_saved_ALWAYS_CXXFLAGS + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[atomic_link_flags [get_multilibs]]" + } + } + + append link_flags " -latomic " + + if [info exists TEST_ALWAYS_FLAGS] { + set atomic_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set atomic_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags" + } + } + return [check_no_compiler_messages_nocache libatomic_available executable { + int main (void) { return 0; } + }] +} + +# +# atomic_finish -- called at the end of each subdir of tests +# + +proc atomic_finish { args } { + global TEST_ALWAYS_FLAGS + global atomic_saved_TEST_ALWAYS_FLAGS + global atomic_saved_ALWAYS_CXXFLAGS + + if [info exists atomic_saved_ALWAYS_CXXFLAGS] { + set ALWAYS_CXXFLAGS $atomic_saved_ALWAYS_CXXFLAGS + } else { + if [info exists atomic_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $atomic_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/brig-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/brig-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..0be3289d1b96d85525e2aaf5d40cba4241ba9d17 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/brig-dg.exp @@ -0,0 +1,29 @@ +# Copyright (C) 2009-2020 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 +# . + +load_lib gcc-dg.exp + +# Define brig callbacks for dg.exp. + +proc brig-dg-test { prog do_what extra_tool_flags } { + set result \ + [gcc-dg-test-1 brig_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + return [list $comp_output $output_file] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/brig.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/brig.exp new file mode 100644 index 0000000000000000000000000000000000000000..fbfb1da947a5827d544db0a598b6f013a7c07553 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/brig.exp @@ -0,0 +1,40 @@ +# Copyright (C) 2009-2020 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 +# . + +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp +# +# brig_target_compile -- compile a HSAIL input to BRIG using HSAILasm and then +# compile the BRIG to target ISA using gcc + +proc brig_target_compile { source dest type options } { + global tmpdir + global testname_with_flags + if { [file extension $source] == ".hsail" } { + # We cannot assume all inputs are .hsail as the dg machinery + # calls this for a some c files to check linker plugin support or + # similar. + set brig_source ${tmpdir}/[file tail ${source}].brig + exec HSAILasm $source -o ${brig_source} + set source ${brig_source} + # Change the testname the .brig. + set testname_with_flags [file tail $source] + } + return [target_compile $source $dest $type $options] +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/c-compat.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/c-compat.exp new file mode 100644 index 0000000000000000000000000000000000000000..9493c214aea9d6733f90fa80f8093eaa6dd7ae52 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/c-compat.exp @@ -0,0 +1,150 @@ +# Copyright (C) 2002-2020 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 +# . + +# Please email any bugs, comments, and/or additions to this file to: +# gcc-patches@gcc.gnu.org + +# Globals. + +global compat_use_alt +global compat_same_alt +global compat_have_dfp +global compat_skip_list + +# This file defines procs for determining features supported by both C +# compilers for compatibility tests. + +load_lib target-supports.exp +load_lib target-libpath.exp + +# +# compat-use-alt-compiler -- make the alternate compiler the default +# +proc compat-use-alt-compiler { } { + global GCC_UNDER_TEST ALT_CC_UNDER_TEST + global compat_same_alt compat_alt_caret compat_alt_color compat_no_line_no + global compat_alt_urls + global TEST_ALWAYS_FLAGS + + # We don't need to do this if the alternate compiler is actually + # the same as the compiler under test. + if { $compat_same_alt == 0 } then { + set GCC_UNDER_TEST $ALT_CC_UNDER_TEST + if { $compat_alt_caret == 0 } then { + regsub -- "-fno-diagnostics-show-caret" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + if { $compat_alt_color == 0 } then { + regsub -- "-fdiagnostics-color=never" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + if { $compat_alt_urls == 0 } then { + regsub -- "-fdiagnostics-urls=never" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + if { $compat_no_line_no == 0 } then { + regsub -- "-fno-diagnostics-show-line-numbers" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + restore_gcc_exec_prefix_env_var + } +} + +# +# compat-use-tst-compiler -- make compiler under test the default +# +proc compat-use-tst-compiler { } { + global GCC_UNDER_TEST compat_save_gcc_under_test + global compat_same_alt + global TEST_ALWAYS_FLAGS compat_save_TEST_ALWAYS_FLAGS + + # We don't need to do this if the alternate compiler is actually + # the same as the compiler under test. + + if { $compat_same_alt == 0 } then { + set GCC_UNDER_TEST $compat_save_gcc_under_test + set TEST_ALWAYS_FLAGS $compat_save_TEST_ALWAYS_FLAGS + set_gcc_exec_prefix_env_var + } +} + +# Find out whether both compilers support decimal float types. +proc compat_setup_dfp { } { + global compat_use_alt + global compat_same_alt + global compat_have_dfp + global compat_alt_caret + global compat_alt_color + global compat_alt_urls + global compat_no_line_no + global TEST_ALWAYS_FLAGS compat_save_TEST_ALWAYS_FLAGS + + set compat_alt_caret 0 + set compat_alt_color 0 + set compat_alt_urls 0 + set compat_no_line_no 0 + set compat_save_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + + verbose "compat_setup_dfp: $compat_use_alt $compat_same_alt" 2 + + # Does the compiler under test support decimal float types? + compat-use-tst-compiler + set compat_have_dfp [check_effective_target_dfprt_nocache] + verbose "compat_have_dfp for tst compiler: $compat_have_dfp" 2 + + if { $compat_use_alt == 1 && $compat_same_alt == 0 } { + compat-use-alt-compiler + if { [check_no_compiler_messages_nocache compat_alt_has_caret object { + int dummy; } "-fno-diagnostics-show-caret"] != 0 } { + set compat_alt_caret 1 + } + if { [check_no_compiler_messages_nocache compat_alt_has_color object { + int dummy; } "-fdiagnostics-color=never"] != 0 } { + set compat_alt_color 1 + } + if { [check_no_compiler_messages_nocache compat_alt_has_urls object { + int dummy; } "-fdiagnostics-urls=never"] != 0 } { + set compat_alt_urls 1 + } + if { [check_no_compiler_messages_nocache compat_alt_has_no_line_no object { + int dummy; } "-fno-diagnostics-show-line-numbers"] != 0 } { + set compat_no_line_no 1 + } + + compat-use-tst-compiler + } + + # If there is an alternate compiler, does it support decimal float types? + if { $compat_have_dfp == 1 && $compat_use_alt == 1 && $compat_same_alt == 0 } { + compat-use-alt-compiler + set compat_have_dfp [check_effective_target_dfprt_nocache] + compat-use-tst-compiler + verbose "compat_have_dfp for alt compiler: $compat_have_dfp" 2 + } + + # If decimal float is not supported, add it to the skip list, which + # affects code in the header files. + if { $compat_have_dfp == 0 } { + global compat_skip_list + lappend compat_skip_list "DECIMAL_FLOAT" + } +} + +# If either compiler does not support decimal float types, skip this test. + +proc dg-require-compat-dfp { args } { + global compat_have_dfp + if { $compat_have_dfp == 0 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/c-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/c-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..c6aafa63b4113ba810969425b30dc92de4c69a34 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/c-torture.exp @@ -0,0 +1,333 @@ +# Copyright (C) 1992-2020 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 +# . + +# This file was written by Rob Savoye. (rob@cygnus.com) + +load_lib target-supports.exp +load_lib file-format.exp +load_lib target-libpath.exp +load_lib target-utils.exp + +global GCC_UNDER_TEST +if ![info exists GCC_UNDER_TEST] { + set GCC_UNDER_TEST "[find_gcc]" +} + +global orig_environment_saved + +# This file may be sourced, so don't override environment settings +# that have been previously setup. +if { $orig_environment_saved == 0 } { + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars +} + +# The default option list can be overridden by +# TORTURE_OPTIONS="{ list1 } ... { listN }" + +set LTO_TORTURE_OPTIONS "" +if [info exists TORTURE_OPTIONS] { + set C_TORTURE_OPTIONS $TORTURE_OPTIONS +} else { + # It is theoretically beneficial to group all of the O2/O3 options together, + # as in many cases the compiler will generate identical executables for + # all of them--and the c-torture testsuite will skip testing identical + # executables multiple times. + # Also note that -finline-functions is explicitly included in one of the + # items below, even though -O3 is also specified, because some ports may + # choose to disable inlining functions by default, even when optimizing. + set C_TORTURE_OPTIONS [list \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions } \ + { -O3 -g } \ + { -Os } \ + { -Og -g } ] + + if [check_effective_target_lto] { + # When having plugin test both slim and fat LTO and plugin/nonplugin + # path. + if [check_linker_plugin_available] { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -fno-use-linker-plugin -flto-partition=none } \ + { -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects } + ] + } else { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -flto-partition=none } \ + { -O2 -flto } + ] + } + } +} + +if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set C_TORTURE_OPTIONS \ + [concat $C_TORTURE_OPTIONS $ADDITIONAL_TORTURE_OPTIONS] +} + +# +# c-torture-compile -- runs the Tege C-torture test +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc c-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and analyze the results. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [gcc_target_compile "$src" "$output" object $options] + gcc_check_compile $testcase $option $output $comp_output + file_on_host delete $output +} + +# +# c-torture-execute -- utility to compile and execute a testcase +# +# SOURCES is a list of full pathnames to the test source files. +# The first filename in this list forms the "testcase". +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc c-torture-execute { sources args } { + global tmpdir tool srcdir output compiler_conditional_xfail_data + + # Use the first source filename given as the filename under test. + set src [lindex $sources 0] + + if { [llength $args] > 0 } { + set additional_flags [lindex $args 0] + } else { + set additional_flags "" + } + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set executable $tmpdir/[file tail [file rootname $src].x] + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + set count 0 + set oldstatus "foo" + foreach option $option_list { + if { $count > 0 } { + set oldexec $execname + } + set execname "${executable}${count}" + incr count + + # torture_{compile,execute}_xfail are set by the .x script + # (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_{compile,execute} can be set by the .x script + # (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + file_on_host delete $execname + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + set comp_output [gcc_target_compile "$sources" "${execname}" executable $options] + + if ![gcc_check_compile "$testcase compilation" $option $execname $comp_output] { + unresolved "$testcase execution, $option" + file_on_host delete $execname + continue + } + + # See if this source file uses "long long" types, if it does, and + # no_long_long is set, skip execution of the test. + if [target_info exists no_long_long] then { + if [expr [search_for $src "long long"]] then { + unsupported "$testcase execution, $option" + continue + } + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + + # Sometimes we end up creating identical executables for two + # consecutive sets of different of compiler options. + # + # In such cases we know the result of this test will be identical + # to the result of the last test. + # + # So in cases where the time to load and run/simulate the test + # is relatively high, compare the two binaries and avoid rerunning + # tests if the executables are identical. + # + # Do not do this for native testing since the cost to load/execute + # the test is fairly small and the comparison step actually slows + # the entire process down because it usually does not "hit". + set skip 0 + if { ![isnative] && [info exists oldexec] } { + if { [file_on_host cmp $oldexec $execname] == 0 } { + set skip 1 + } + } + if { $skip == 0 } { + set result [gcc_load "$execname" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + } + if { $oldstatus == "pass" } { + file_on_host delete $oldexec + } + $status "$testcase execution, $option" + set oldstatus $status + } + if [info exists status] { + if { $status == "pass" } { + file_on_host delete $execname + } + } +} + +# +# search_for -- looks for a string match in a file +# +proc search_for { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + +# +# c-torture -- the c-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# SRC is the full pathname of the testcase, or just a file name in which case +# we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc c-torture { args } { + global srcdir subdir compiler_conditional_xfail_data + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + # loop through all the options + foreach option $option_list { + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + c-torture-compile $src "$option $options" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/clearcap.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/clearcap.exp new file mode 100644 index 0000000000000000000000000000000000000000..e3fc46d449a89f945aeaddfbffaa46085b11427b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/clearcap.exp @@ -0,0 +1,59 @@ +# Copyright (C) 2014-2020 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 +# . + +# Clear hardware capabilities on Solaris. +if [istarget *-*-solaris2*] { + set clearcap_ldflags "-mclear-hwcap" +} + +# +# clearcap-init -- called at the start of each subdir of tests +# + +proc clearcap-init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global clearcap_saved_TEST_ALWAYS_FLAGS + global clearcap_ldflags + + if [info exists TEST_ALWAYS_FLAGS] { + set clearcap_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists clearcap_ldflags] { + if [info exists ALWAYS_CXXFLAGS] { + set ALWAYS_CXXFLAGS [concat "{ldflags=$clearcap_ldflags}" $ALWAYS_CXXFLAGS] + } else { + append TEST_ALWAYS_FLAGS " $clearcap_ldflags" + } + } + return 0 +} + +# +# clearcap-finish -- called at the start of each subdir of tests +# + +proc clearcap-finish { args } { + global TEST_ALWAYS_FLAGS + global clearcap_saved_TEST_ALWAYS_FLAGS + + if [info exists clearcap_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $clearcap_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/compat.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/compat.exp new file mode 100644 index 0000000000000000000000000000000000000000..5cb4ff8973a07be92ea5f09a45bacd8f9646f907 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/compat.exp @@ -0,0 +1,390 @@ +# Copyright (C) 2002-2020 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 +# . + +# This file was written by Janis Johnson, + + +# Test interoperability of two compilers that follow the same ABI, or +# compatibility of two versions of GCC. +# +# Each test has a main program that does nothing but call a function, +# plus two additional source files that contain parts of a program that +# rely on the ABI. those source files are compiled into relocatable +# object files with both compilers. Executables are built using various +# combinations of those object files, with the main program compiled +# with the compiler under test and using that compiler's runtime support. + +# The including .exp file must define these callback procedures. +if [string match "" [info procs "compat-use-alt-compiler"]] then { + error "Proc compat-use-alt-compiler is not defined." +} +if [string match "" [info procs "compat-use-tst-compiler"]] then { + error "Proc compat-use-tst-compiler is not defined." +} + +# Each test is run with each pair of compiler options from this list. +# The first set of options in each pair is used by the compiler under +# test, and the second set is used by the alternate compiler. +# The default option lists can be overridden by +# COMPAT_OPTIONS="[list [list {tst_1} {alt_1}]...[list {tst_n} {alt_n}]]" +# where tst_i and alt_i are lists of options. You can put this in the +# environment before site.exp is written or add it to site.exp directly. +if ![info exists COMPAT_OPTIONS] { + set COMPAT_OPTIONS [list \ + [list {} {}]] +} + +set compat_option_list $COMPAT_OPTIONS + +# Subsets of tests can be selectively disabled by members of this list: +# - ATTRIBUTE: disable all tests using the __attribute__ extension, +# - COMPLEX: disable all tests using the complex types feature, +# - COMPLEX_INT: disable all tests using the complex integral types extension, +# - VA: disable all tests using the variable number of arguments feature, +# - VLA_IN_STRUCT: disable all tests using the variable-length arrays as +# structure members extension, +# - ZERO_ARRAY: disable all tests using the zero-sized arrays extension. +# The default skip lists can be overriden by +# COMPAT_SKIPS="[list {skip_1}...{skip_n}]" +# where skip_i are skip identifiers. You can put this in the environment +# before site.exp is written or add it to site.exp directly. +if ![info exists COMPAT_SKIPS] { + set COMPAT_SKIPS [list {}] +} + +global compat_skip_list +set compat_skip_list $COMPAT_SKIPS + +load_lib dg.exp +load_lib gcc-dg.exp + +# +# compat-obj -- compile to an object file +# +# SOURCE is the source file +# DEST is the object file +# OPTALL is the list of compiler options to use with all tests +# OPTFILE is the list of compiler options to use with this file +# OPTSTR is the options to print with test messages +# XFAILDATA is the xfail data to be passed to the compiler +# +proc compat-obj { source dest optall optfile optstr xfaildata } { + global testcase + global tool + global compiler_conditional_xfail_data + global compat_skip_list + + # Add the skip specifiers. + foreach skip $compat_skip_list { + if { ![string match $skip ""] } { + lappend optall "-DSKIP_$skip" + } + } + + # Set up the options for compiling this file. + set options "" + lappend options "additional_flags=$optfile $optall" + + set compiler_conditional_xfail_data $xfaildata + set comp_output [${tool}_target_compile "$source" "$dest" object $options] + ${tool}_check_compile "$testcase $dest compile" $optstr $dest $comp_output +} + +# compat-run -- link and run an executable +# +# TESTNAME is the mixture of object files to link +# OBJLIST is the list of object files to link +# DEST is the name of the executable +# OPTALL is a list of compiler and linker options to use for all tests +# OPTFILE is a list of compiler and linker options to use for this test +# OPTSTR is the list of options to list in messages +# +proc compat-run { testname objlist dest optall optfile optstr } { + global testcase + global tool + + # Check that all of the objects were built successfully. + foreach obj [split $objlist] { + if ![file_on_host exists $obj] then { + unresolved "$testcase $testname link $optstr" + unresolved "$testcase $testname execute $optstr" + return + } + } + + # Set up the options for linking this test. + set options "" + lappend options "additional_flags=$optfile $optall" + + # Link the objects into an executable. + set comp_output [${tool}_target_compile "$objlist" $dest executable \ + "$options"] + if ![${tool}_check_compile "$testcase $testname link" "" \ + $dest $comp_output] then { + return + } + + # Run the self-checking executable. + if ![string match "*/*" $dest] then { + set dest "./$dest" + } + set result [${tool}_load $dest "" ""] + set status [lindex $result 0] + if { $status == "pass" } then { + file_on_host delete $dest + } + $status "$testcase $testname execute $optstr" +} + +# +# compat-get-options-main -- get target requirements for a test and +# options for the primary source file and the test as a whole +# +# SRC is the full pathname of the primary source file. +# +proc compat-get-options-main { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + # dg-options sets a variable called tool_flags. + set tool_flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || [string match "dg-prune-output" $cmd] \ + || [string match "dg-skip-if" $cmd] \ + || [string match "dg-require-*" $cmd] \ + || [string match "dg-timeout-factor" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { ![string compare "dg-xfail-if" $cmd] } { + warning "compat.exp does not support $cmd in primary source file" + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "compat.exp does not support $cmd" + } + } + + # Return flags to use for compiling the primary source file and for + # linking. + return ${dg-extra-tool-flags} +} + +# +# compat-get-options -- get special tool flags to use for a secondary +# source file +# +# SRC is the full pathname of the source file. +# The result is a list of options to use. +# +# This code is copied from proc dg-test in dg.exp from DejaGNU. +# +proc compat-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-xfail-if sets compiler_conditional_xfail_data. + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data "" + + # dg-xfail-if needs access to dg-do-what. + upvar dg-do-what dg-do-what + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || ![string compare "dg-prune-output" $cmd] \ + || ![string compare "dg-xfail-if" $cmd] \ + || ![string compare "dg-timeout-factor" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { [string match "dg-require-*" $cmd] } { + warning "compat.exp does not support $cmd in secondary source files" + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "compat.exp does not support $cmd" + } + } + + return ${dg-extra-tool-flags} +} + +# +# compat-execute -- compile with compatible compilers +# +# SRC1 is the full pathname of the main file of the testcase. +# SID identifies a test suite in the names of temporary files. +# USE_ALT is nonzero if we're using an alternate compiler as well as +# the compiler under test. +# +proc compat-execute { src1 sid use_alt } { + global srcdir tmpdir + global compat_option_list + global tool + global verbose + global testcase + global gluefile + global compiler_conditional_xfail_data + global dg-do-what-default + + # Get extra flags for this test from the primary source file, and + # process other dg-* options that this suite supports. Warn about + # unsupported flags. + verbose "compat-execute: $src1" 1 + set dg-do-what [list ${dg-do-what-default} "" P] + set extra_flags_1 [compat-get-options-main $src1] + + # Set up the names of the other source files. + set dir [file dirname $src1] + set ext [file extension $src1] + set base [file rootname $src1] + set base [string range $base [string length $dir] end] + regsub "_main" $base "" base + set src2 "${dir}/${base}_x${ext}" + set src3 "${dir}/${base}_y${ext}" + + # Use the dg-options mechanism to specify extra flags for this test. + # The extra flags in each file are used to compile that file, and the + # extra flags in *_main.* are also used for linking. + set extra_flags_2 [compat-get-options $src2] + set compile_xfail_2 $compiler_conditional_xfail_data + set extra_flags_3 [compat-get-options $src3] + set compile_xfail_3 $compiler_conditional_xfail_data + + # Define the names of the object files. + regsub "sid" "sid_main_tst.o" $sid obj1 + regsub "sid" "sid_x_tst.o" $sid obj2_tst + regsub "sid" "sid_x_alt.o" $sid obj2_alt + regsub "sid" "sid_y_tst.o" $sid obj3_tst + regsub "sid" "sid_y_alt.o" $sid obj3_alt + + # Get the base name of this test, for use in messages. + set testcase "$src1" + # Remove the $srcdir and $tmpdir prefixes from $src1. (It would + # be possible to use "regsub" here, if we were careful to escape + # all regular expression characters in $srcdir and $tmpdir, but + # that would be more complicated that this approach.) + if {[string first "$srcdir/" "$src1"] == 0} { + set testcase [string range "$src1" [string length "$srcdir/"] end] + } + if {[string first "$tmpdir/" "$testcase"] == 0} { + set testcase [string range "$testcase" [string length "$tmpdir/"] end] + set testcase "tmpdir-$testcase" + } + # If we couldn't rip $srcdir out of `src1' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] then { + set testcase "[file tail [file dirname $src1]]/[file tail $src1]" + } + + # Check whether this test is supported for this target. + if { [lindex ${dg-do-what} 1 ] == "N" } { + unsupported "$testcase" + verbose "$testcase not supported on this target, skipping it" 3 + return + } + + regsub "_main.*" $testcase "" testcase + # Set up the base name of executable files so they'll be unique. + regsub -all "\[./\]" $testcase "-" execbase + + # Loop through all of the option lists used for this test. + + set count 0 + foreach option_pair $compat_option_list { + + # Pick out each set of options. + set tst_option [lindex $option_pair 0] + set alt_option [lindex $option_pair 1] + set optstr "" + if { ![string match $tst_option ""] \ + || ![string match $alt_option ""] } then { + set optstr "\"$tst_option\",\"$alt_option\"" + } + verbose "Testing $testcase, $optstr" 1 + + # There's a unique name for each executable we generate, based on + # the set of options and how the pieces of the tests are compiled. + set execname1 "${execbase}-${count}1.exe" + set execname2 "${execbase}-${count}2.exe" + set execname3 "${execbase}-${count}3.exe" + set execname4 "${execbase}-${count}4.exe" + incr count + + file_on_host delete $execname1 + file_on_host delete $execname2 + file_on_host delete $execname3 + file_on_host delete $execname4 + + # Compile pieces with the alternate compiler; we'll catch problems + # later. Skip this if we don't have an alternate compiler. + if { $use_alt != 0 } then { + compat-use-alt-compiler + compat-obj "$src2" "$obj2_alt" $alt_option $extra_flags_2 \ + $optstr $compile_xfail_2 + compat-obj "$src3" "$obj3_alt" $alt_option $extra_flags_3 \ + $optstr $compile_xfail_3 + } + + # Compile pieces with the compiler under test. + compat-use-tst-compiler + compat-obj "$src1" "$obj1" $tst_option $extra_flags_1 $optstr "" + compat-obj "$src2" "$obj2_tst" $tst_option $extra_flags_2 \ + $optstr $compile_xfail_2 + compat-obj "$src3" "$obj3_tst" $tst_option $extra_flags_3 \ + $optstr $compile_xfail_3 + + # Link (using the compiler under test), run, and clean up tests. + compat-run "${obj2_tst}-${obj3_tst}" \ + "$obj1 $obj2_tst $obj3_tst" $execname1 \ + $tst_option $extra_flags_1 $optstr + + # If we've got an alternate compiler try some combinations. + if { $use_alt != 0 } then { + compat-run "${obj2_tst}-${obj3_alt}" "$obj1 $obj2_tst $obj3_alt" \ + $execname2 $tst_option $extra_flags_1 $optstr + compat-run "${obj2_alt}-${obj3_tst}" "$obj1 $obj2_alt $obj3_tst" \ + $execname3 $tst_option $extra_flags_1 $optstr + compat-run "${obj2_alt}-${obj3_alt}" "$obj1 $obj2_alt $obj3_alt" \ + $execname4 $tst_option $extra_flags_1 $optstr + } + + # Clean up object files. + set files [glob -nocomplain ${sid}_*.o] + if { $files != "" } { + foreach objfile $files { + if { ![info exists gluefile] || $objfile != $gluefile } { + eval "file_on_host delete $objfile" + } + } + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/copy-file.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/copy-file.exp new file mode 100644 index 0000000000000000000000000000000000000000..4e2a2fc3adf39f7c7867a34fc68bc1f40fa23955 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/copy-file.exp @@ -0,0 +1,35 @@ +# Copyright (C) 2003-2020 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 +# . + +# This file defines a proc for copying regular files as well as +# symlinks. + +proc gcc_copy_files {srcfiles dstdir} { + foreach f $srcfiles { + if { [is_remote host] } { + remote_download host $f $dstdir + } elseif { [catch { set symlink [file readlink $f] } x] } then { + file copy -force $f $dstdir + } else { + if { [regexp "^/" "$symlink"] } then { + file copy -force $symlink $dstdir + } else { + set dirname [file dirname $f] + file copy -force $dirname/$symlink $dstdir + } + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/dejapatches.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/dejapatches.exp new file mode 100644 index 0000000000000000000000000000000000000000..f19c6974bc298e75a982dd9b359904fd442f2b14 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/dejapatches.exp @@ -0,0 +1,35 @@ +# Copyright (C) 2008-2020 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 +# . + +# Necessary procs and fallbacks for functionality not present in +# pristine dejagnu-1.4.4. Make sure overrides here work with updated +# dejagnu too. + +# The absence of sim_download will cause e.g. the libstdc++ testsuite +# to expose about 59 more FAILs on simulator targets supporting +# fileio. + +if { [info procs sim_download] == "" } { + proc sim_download { dest file args } { + return [remote_download host $file $args] + } +} + +if { [info procs sim_upload] == "" } { + proc sim_upload { dest srcfile args } { + return [remote_upload host $srcfile $args] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/dg-pch.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/dg-pch.exp new file mode 100644 index 0000000000000000000000000000000000000000..732771fb90e11c13c14553f2953d922b1025b99b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/dg-pch.exp @@ -0,0 +1,151 @@ +# Copyright (C) 2003-2020 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 +# . + +load_lib copy-file.exp + +proc pch-init { args } { + global pch_unsupported_debug pch_unsupported + + if [info exists pch_unsupported_debug] { + error "pch-init: pch_unsupported_debug is not empty as expected" + } + if [info exists pch_unsupported] { + error "pch-init: pch_unsupported is not empty as expected" + } + + set result [check_compile pchtest object "int i;" "-g -x c-header"] + set pch_unsupported_debug \ + [regexp "debug format cannot be used with pre-compiled headers" \ + [lindex $result 0]] + remote_file build delete [lindex $result 1] + + set pch_unsupported 0 + if { $pch_unsupported_debug } { + verbose -log "pch is unsupported with the debug info format" + + set result [check_compile pchtest object "int i;" "-x c-header"] + set pch_unsupported \ + [regexp "debug format cannot be used with pre-compiled headers" \ + [lindex $result 0]] + remote_file build delete [lindex $result 1] + } +} + +proc pch-finish { args } { + global pch_unsupported_debug pch_unsupported + unset pch_unsupported_debug + unset pch_unsupported +} + +proc check_effective_target_pch_supported_debug { } { + global pch_unsupported_debug + if { $pch_unsupported_debug } { + return 0 + } + return 1 +} + +proc dg-flags-pch { subdir test otherflags options suffix } { + global runtests dg-do-what-default + global pch_unsupported_debug pch_unsupported + + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $test] { + return + } + + if { [istarget "powerpc-ibm-aix*"] } { + set torture_execute_xfail "powerpc-ibm-aix*" + return + } + + set nshort "$subdir/[file tail $test]" + set bname "[file rootname [file tail $nshort]]" + + catch { file_on_host delete "$bname$suffix.gch" } + catch { file_on_host delete "$bname.s" } + catch { file_on_host delete "$bname.s-gch" } + + # We don't try to use the loop-optimizing options, since they are highly + # unlikely to make any difference to PCH. + foreach flags $options { + verbose "Testing $nshort, $otherflags $flags" 1 + + if { $pch_unsupported != 0 \ + || ( $pch_unsupported_debug != 0 && [regexp " -g" " $flags"] ) } { + verbose -log "$nshort unsupported because debug format conflicts with PCH" + unsupported "$nshort $flags" + continue + } + + # For the header files, the default is to precompile. + set dg-do-what-default precompile + catch { file_on_host delete "$bname$suffix" } + gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" + dg-test -keep-output "./$bname$suffix" "$otherflags $flags" "" + + # For the rest, the default is to compile to .s. + set dg-do-what-default compile + + set have_errs [llength [grep $test "{\[ \t\]\+dg-error\[ \t\]\+.*\[ \t\]\+}"]] + + if { [ file_on_host exists "$bname$suffix.gch" ] } { + # Ensure that the PCH file is used, not the original header. + file_on_host delete "$bname$suffix" + + # The flags "-Dwith_PCH" and "-Dwithout_PCH" are to distinguish the + # two compiles in test summary lines. + dg-test -keep-output $test "$otherflags $flags -I. -Dwith_PCH" "" + file_on_host delete "$bname$suffix.gch" + if { !$have_errs } { + if { [ file_on_host exists "$bname.s" ] } { + remote_upload host "$bname.s" "$bname.s-gch" + remote_download host "$bname.s-gch" + gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" + dg-test -keep-output $test "$otherflags $flags -I. -Dwithout_PCH" "" + remote_upload host "$bname.s" + set tmp [ diff "$bname.s" "$bname.s-gch" ] + if { $tmp == 0 } { + verbose -log "assembly file '$bname.s', '$bname.s-gch' comparison error" + fail "$nshort $otherflags $flags assembly comparison" + } elseif { $tmp == 1 } { + pass "$nshort $otherflags $flags assembly comparison" + } else { + fail "$nshort $otherflags $flags assembly comparison" + } + file_on_host delete "$bname$suffix" + file_on_host delete "$bname.s" + file_on_host delete "$bname.s-gch" + } else { + verbose -log "assembly file '$bname.s' missing" + fail "$nshort $flags assembly comparison" + } + } + } elseif { $pch_unsupported_debug == 0 \ + || [llength [grep $test "{\[ \t\]\+dg-require-effective-target\[ \t\]\+pch_supported_debug\[ \t\]\+.*\[ \t\]\+}"]] > 0 } { + verbose -log "pch file '$bname$suffix.gch' missing" + fail "$nshort $flags" + if { !$have_errs } { + verbose -log "assembly file '$bname.s' missing" 1 + fail "$nshort $flags assembly comparison" + } + } + } +} + +proc dg-pch { subdir test options suffix } { + return [dg-flags-pch $subdir $test "" $options $suffix] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/file-format.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/file-format.exp new file mode 100644 index 0000000000000000000000000000000000000000..fdb17e70e1df579216c04f866e05d644304c5f2a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/file-format.exp @@ -0,0 +1,95 @@ +# Copyright (C) 1999-2020 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 +# . + +# Please email any bugs, comments, and/or additions to this file to: +# gcc-bugs@gcc.gnu.org + +# This file defines a proc for determining the file format in use by the +# target. This is useful for tests that are only supported by certain file +# formats. This procedure is defined in a separate file so that it can be +# included by other expect library files. + +proc gcc_target_object_format { } { + global gcc_target_object_format_saved + global tool + + if [info exists gcc_target_object_format_saved] { + verbose "gcc_target_object_format returning saved $gcc_target_object_format_saved" 2 + } elseif { [istarget *-*-darwin*] } { + # Darwin doesn't necessarily have objdump, so hand-code it. + set gcc_target_object_format_saved mach-o + } elseif { [istarget hppa*-*-hpux*] } { + # HP-UX doesn't necessarily have objdump, so hand-code it. + if { [istarget hppa*64*-*-hpux*] } { + set gcc_target_object_format_saved elf + } else { + set gcc_target_object_format_saved som + } + } elseif { [istarget *-*-aix*] } { + # AIX doesn't necessarily have objdump, so hand-code it. + set gcc_target_object_format_saved coff + } elseif { [istarget *-*-amdhsa*] } { + # AMD GCN uses LLVM objdump which is not CLI-compatible + set gcc_target_object_format_saved elf + } else { + set objdump_name [find_binutils_prog objdump] + set open_file [open objfmtst.c w] + puts $open_file "void foo(void) { }" + close $open_file + + ${tool}_target_compile objfmtst.c objfmtst.o object "" + file delete objfmtst.c + + set output [remote_exec host "$objdump_name" "--file-headers objfmtst.o"] + set output [lindex $output 1] + + file delete objfmtst.o + + if ![ regexp "file format (.*)arch" $output dummy objformat ] { + verbose "Could not parse objdump output" 2 + set gcc_target_object_format_saved unknown + } else { + switch -regexp $objformat { + elf { + set gcc_target_object_format_saved elf + } + ecoff { + set gcc_target_object_format_saved ecoff + } + coff { + set gcc_target_object_format_saved coff + } + a\.out { + set gcc_target_object_format_saved a.out + } + pe { + set gcc_target_object_format_saved pe + } + som { + set gcc_target_object_format_saved som + } + default { + verbose "Unknown file format: $objformat" 3 + set gcc_target_object_format_saved unknown + } + } + + verbose "gcc_target_object_format returning $gcc_target_object_format_saved" 2 + } + } + + return $gcc_target_object_format_saved +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/fortran-modules.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/fortran-modules.exp new file mode 100644 index 0000000000000000000000000000000000000000..a54debb054d45be1c0ce373d20aaacfd152f1ba2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/fortran-modules.exp @@ -0,0 +1,174 @@ +# Copyright (C) 2012-2020 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 +# . + +# helper to deal with fortran modules + +# Remove files for specified Fortran modules. +# This includes both .mod and .smod files. +proc cleanup-modules { modlist } { + global clean + foreach mod [concat $modlist $clean] { + set m [string tolower $mod].mod + verbose "cleanup-module `$m'" 2 + if [is_remote host] { + remote_file host delete $m + } + remote_file build delete $m + } + cleanup-submodules $modlist +} + +# Remove files for specified Fortran submodules. +proc cleanup-submodules { modlist } { + global clean + foreach mod [concat $modlist $clean] { + set m [string tolower $mod].smod + verbose "cleanup-submodule `$m'" 2 + if [is_remote host] { + remote_file host delete $m + } + remote_file build delete $m + } +} + +proc keep-modules { modlist } { + global clean + # if the modlist is empty, keep everything + if {[llength $modlist] < 1} { + set clean {} + } else { + set cleansed {} + foreach cl $clean { + if {[lsearch $cl $modlist] < 0} { + lappend cleansed $cl + } + } + if {[llength $clean] == [llength $cleansed]} { + warning "keep-modules had no effect?! Possible typo in module name." + } + set clean $cleansed + } +} + +# collect all module names from a source-file +proc list-module-names { files } { + global clean + set clean {} + foreach file $files { + foreach mod [list-module-names-1 $file] { + if {[lsearch $clean $mod] < 0} { + lappend clean $mod + } + } + } + return [join $clean " "] +} + +proc list-module-names-1 { file } { + set result {} + if {[file isdirectory $file]} {return} + # Find lines containing INCLUDE, MODULE, and SUBMODULE, excluding the lines containing + # MODULE [PURE|(IMPURE\s+)?ELEMENTAL|RECURSIVE] (PROCEDURE|FUNCTION|SUBROUTINE) + set pat {^\s*((#)?\s*include|(sub)?module(?!\s+((pure|(impure\s+)?elemental|recursive)\s+)?(procedure|function|subroutine)[:\s]+))\s*.*} + set tmp [igrep $file $pat line] + if {![string match "" $tmp]} { + foreach i $tmp { + regexp -nocase {(\d+)\s+#?\s*include\s+["']([^"']*)["']} $i dummy lineno include_file + if {[info exists include_file]} { + set dir [file dirname $file] + set inc "$dir/$include_file" + unset include_file + if {![file readable $inc]} { + # We do not currently use include path search logic, punt + continue + } + verbose "Line $lineno includes `$inc'" 3 + foreach mod [list-module-names-1 $inc] { + if {[lsearch $result $mod] < 0} { + lappend result $mod + } + } + continue + } + regexp -nocase {(\d+)\s+(module|submodule)\s*([^;]*)} $i i lineno keyword mod + if {![info exists mod]} { + continue + } + # Generates the file name mod_name@submod_name from + # (\s*mod_name[:submod_name]\s*)\s*submod_name\s*[! comment] + regsub {\s*!.*} $mod "" mod + regsub {:[^)]*} $mod "" mod + regsub {\(\s*} $mod "" mod + regsub {\s*\)\s*} $mod "@" mod + verbose "Line $lineno mentions module `$mod'" 3 + if {[lsearch $result $mod] < 0} { + lappend result $mod + } + } + } + return $result +} + +# Looks for case insensitive occurrences of a string in a file. +# return:list of lines that matched or NULL if none match. +# args: first arg is the filename, +# second is the pattern, +# third are any options. +# Options: line - puts line numbers of match in list +# +proc igrep { args } { + + set file [lindex $args 0] + set pattern [lindex $args 1] + + verbose "Grepping $file for the pattern \"$pattern\"" 3 + + set argc [llength $args] + if { $argc > 2 } { + for { set i 2 } { $i < $argc } { incr i } { + append options [lindex $args $i] + append options " " + } + } else { + set options "" + } + + set i 0 + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + incr i + if {[regexp -nocase -- "$pattern" $cur_line match]} { + if {![string match "" $options]} { + foreach opt $options { + switch $opt { + "line" { + lappend grep_out [concat $i $match] + } + } + } + } else { + lappend grep_out $match + } + } + } + close $fd + unset fd + unset i + if {![info exists grep_out]} { + set grep_out "" + } + return $grep_out +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/fortran-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/fortran-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..6bff13bac8e1a66b464a95816a8f7e20257c399a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/fortran-torture.exp @@ -0,0 +1,431 @@ +# Copyright (C) 2003-2020 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 +# . + +# Please email any bugs, comments, and/or additions to this file to +# the author. + +# This file was written by Steven Bosscher (s.bosscher@student.tudelft.nl) +# based on f-torture.exp, which was written by Rob Savoye. + +load_lib target-supports.exp +load_lib fortran-modules.exp +load_lib target-utils.exp + +# Return the list of options to use for fortran torture tests. +# The default option list can be overridden by +# TORTURE_OPTIONS="{ { list1 } ... { listN } }" +proc get-fortran-torture-options { } { + global TORTURE_OPTIONS + + if [info exists TORTURE_OPTIONS] { + return $TORTURE_OPTIONS + } + + # determine if host supports vectorization, and the necessary set + # of options, based on code from testsuite/vect/vect.exp + + set vectorizer_options [list "-O2" "-ftree-vectorize"] + + if { [istarget powerpc*-*-*] + && [is-effective-target powerpc_altivec_ok] + && [check_vmx_hw_available] } { + lappend vectorizer_options "-maltivec" + set test_tree_vectorize 1 + } elseif { ( [istarget i?86-*-*] || [istarget x86_64-*-*] ) + && [check_effective_target_sse2] + && [check_sse2_hw_available] + && [check_sse_os_support_available] } { + lappend vectorizer_options "-msse2" + set test_tree_vectorize 1 + } elseif { [istarget mips*-*-*] + && [check_effective_target_mpaired_single] + && [check_effective_target_nomips16] } { + lappend vectorizer_options "-mpaired-single" + set test_tree_vectorize 1 + } elseif { [istarget sparc*-*-*] + && [check_effective_target_ultrasparc_hw] } { + lappend vectorizer_options "-mcpu=ultrasparc" "-mvis" + set test_tree_vectorize 1 + } elseif { [istarget alpha*-*-*] + && [check_alpha_max_hw_available] } { + lappend vectorizer_options "-mmax" + set test_tree_vectorize 1 + } elseif [istarget ia64-*-*] { + set test_tree_vectorize 1 + } else { + set test_tree_vectorize 0 + } + + set options {} + + lappend options \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O2 -fomit-frame-pointer -finline-functions } \ + { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \ + { -O2 -fbounds-check } \ + { -O3 -g } \ + { -Os } + if { $test_tree_vectorize } { + lappend options $vectorizer_options + } + + if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set options [concat $options $ADDITIONAL_TORTURE_OPTIONS] + } + + return $options +} + + +# +# fortran-torture-compile -- compile a gfortran.fortran-torture testcase. +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc fortran-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and get results in comp_output. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [gfortran_target_compile "$src" "$output" object $options] + + # See if we got something bad. + set fatal_signal "*95*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + gfortran_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $output } + return + } + + if [string match "$fatal_signal 11" $comp_output] then { + gfortran_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $output } + return + } + + if [string match "*internal compiler error*" $comp_output] then { + gfortran_fail $testcase "$option (internal compiler error)" + catch { remote_file build delete $output } + return + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*95*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $output } + return + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [gfortran_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + catch { remote_file build delete $output } + return + } + + # remove any leftover LF/CR to make sure any output is legit + regsub -all -- "\[\r\n\]*" $comp_output "" comp_output + + # If any message remains, we fail. + if ![string match "" $comp_output] then { + gfortran_fail $testcase $option + catch { remote_file build delete $output } + return + } + + gfortran_pass $testcase $option + catch { remote_file build delete $output } +} + + +# +# fortran-torture-execute -- compile and execute a testcase. +# +# SRC is the full pathname of the testcase. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc fortran-torture-execute { src } { + global output + global srcdir tmpdir + global tool + global compiler_conditional_xfail_data + global torture_with_loops + + # Check for alternate driver. + set additional_flags "" + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Setup the options for the testcase run. + set option_list $torture_with_loops + set executable $tmpdir/[file tail [file rootname $src].x] + regsub "(?q)$srcdir/" $src "" testcase + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + list-module-names $src + + # Walk the list of options and copmile and run the testcase for all + # options that are not explicitly disabled by the .x script (if present). + foreach option $option_list { + + # Torture_{compile,execute}_xfail are set by the .x script. + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # Torture_execute_before_{compile,execute} can be set by the .x script. + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + # FIXME: We should make sure that the modules required by this testcase + # exist. If not, the testcase should XFAIL. + + # Compile the testcase. + catch { remote_file build delete $executable } + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + set comp_output [gfortran_target_compile "$src" "$executable" executable $options] + + # See if we got something bad. + set fatal_signal "*95*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + gfortran_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $executable } + continue + } + + if [string match "$fatal_signal 11" $comp_output] then { + gfortran_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $executable } + continue + } + + if [string match "*internal compiler error*" $comp_output] then { + gfortran_fail $testcase "$option (internal compiler error)" + catch { remote_file build delete $executable } + continue + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*95*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $executable } + continue + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [gfortran_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + continue + } elseif ![file exists $executable] { + if ![is3way] { + fail "$testcase compilation, $option" + untested "$testcase execution, $option" + continue + } else { + # FIXME: since we can't test for the existence of a remote + # file without short of doing an remote file list, we assume + # that since we got no output, it must have compiled. + pass "$testcase compilation, $option" + } + } else { + pass "$testcase compilation, $option" + } + + # See if this source file uses INTEGER(KIND=8) types, if it does, and + # no_long_long is set, skip execution of the test. + # FIXME: We should also look for F95 style "_8" or select_int_kind() + # integers, but that is obviously much harder than just regexping this. + # So maybe we should just avoid those in testcases. + if [target_info exists no_long_long] then { + if [expr [search_for_re $src "integer\*8"] \ + +[search_for_re $src "integer *( *8 *)"] \ + +[search_for_re $src "integer *( *kind *= *8 *)"]] \ + then { + untested "$testcase execution, $option" + continue + } + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + # Run the testcase, and analyse the output. + set result [gfortran_load "$executable" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + if { $status == "pass" } { + catch { remote_file build delete $executable } + } + $status "$testcase execution, $option" + } + cleanup-modules "" +} + + +# +# search_for_re -- looks for a string match in a file +# +proc search_for_re { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + set lower [string tolower $cur_line] + if [regexp "$pattern" $lower] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + + +# +# fortran-torture -- the fortran-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# +# SRC is the full pathname of the testcase, or just a file name in which +# case we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc fortran-torture { args } { + global srcdir subdir + global compiler_conditional_xfail_data + global torture_with_loops + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + list-module-names $src + + # loop through all the options + set option_list $torture_with_loops + foreach option $option_list { + + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + fortran-torture-compile $src "$option $options" + cleanup-modules "" + } +} + +# +# add-ieee-options -- add options necessary for 100% ieee conformance. +# +proc add-ieee-options { } { + # Ensure that excess precision does not cause problems. + if { [istarget i?86-*-*] + || [istarget m68k-*-*] } then { + uplevel 1 lappend additional_flags "-ffloat-store" + } + + # Enable full IEEE compliance mode. + if { [istarget alpha*-*-*] + || [istarget sh*-*-*] } then { + uplevel 1 lappend additional_flags "-mieee" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/g++-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/g++-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..115c3944cd90f9cbdb6c3b980ce561ba2937d080 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/g++-dg.exp @@ -0,0 +1,74 @@ +# Copyright (C) 1997-2020 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 +# . + +# Define g++ callbacks for dg.exp. + +load_lib gcc-dg.exp + +proc g++-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 g++_target_compile $prog $do_what $extra_tool_flags] +} + + +proc g++-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Modified dg-runtest that runs tests in both C++98 and C++11 modes +# unless they specifically specify one or the other. +proc g++-dg-runtest { testcases flags default-extra-flags } { + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # If the testcase specifies a standard, use that one. + # If not, run it under both standards, allowing GNU extensions + # if there's a dg-options line. + if ![search_for $test "-std=*++"] { + if [search_for $test "dg-options"] { + set std_prefix "-std=gnu++" + } else { + set std_prefix "-std=c++" + } + + global gpp_std_list + if { [llength $gpp_std_list] > 0 } { + set std_list $gpp_std_list + } else { + set std_list { 98 14 17 2a } + } + set option_list { } + foreach x $std_list { + # Handle "concepts" as C++17 plus Concepts TS. + if { $x eq "concepts" } then { set x "17 -fconcepts" } + lappend option_list "${std_prefix}$x" + } + } else { + set option_list { "" } + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/g++.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/g++.exp new file mode 100644 index 0000000000000000000000000000000000000000..0e10176d67739f58c4ce2a30b33815ef05a8a6e8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/g++.exp @@ -0,0 +1,379 @@ +# Copyright (C) 1992-2020 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Many modifications by Jeffrey Wheat (cassidy@cygnus.com) +# With modifications by Mike Stump . + +# +# g++ support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# GXX_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" +set gpp_std_list { } +if [info exists env(GXX_TESTSUITE_STDS)] { + set gpp_std_list [split $env(GXX_TESTSUITE_STDS) ","] +} + +# +# g++_version -- extract and print the version number of the compiler +# + +proc g++_version { } { + global GXX_UNDER_TEST + + g++_init + + # ignore any arguments after the command + set compiler [lindex $GXX_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# g++_include_flags -- provide new version of g++_include_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# +proc g++_include_flags { paths } { + global srcdir + global HAVE_LIBSTDCXX_V3 + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set gccpath ${paths} + + set odir [lookfor_file ${gccpath} libstdc++-v3] + if { ${odir} != "" } { + append flags [exec sh ${odir}/scripts/testsuite_flags --build-includes] + } + + return "$flags" +} + +# +# g++_link_flags -- provide new version of g++_link_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# + +proc g++_link_flags { paths } { + global srcdir + global ld_library_path + global GXX_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/lib/libstdc++.a"] { + append ld_library_path ":${gccpath}/lib" + } + if [file exists "${gccpath}/libg++/libg++.a"] { + append flags "-L${gccpath}/libg++ " + append ld_library_path ":${gccpath}/libg++" + } + if [file exists "${gccpath}/libstdc++/libstdc++.a"] { + append flags "-L${gccpath}/libstdc++ " + append ld_library_path ":${gccpath}/libstdc++" + } + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] { + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + # Some targets use libstdc++.a%s in their specs, so they need a + # -B option for uninstalled testing. + append flags " -B${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + # Look for libstdc++.${shlib_ext}. + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] { + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + if [file exists "${gccpath}/librx/librx.a"] { + append flags "-L${gccpath}/librx " + } + if [file exists "${gccpath}/libitm/libitm.spec"] { + append flags "-B${gccpath}/libitm/ -L${gccpath}/libitm/.libs" + append ld_library_path ":${gccpath}/libitm/.libs" + } + append ld_library_path [gcc-set-multilib-library-path $GXX_UNDER_TEST] + } else { + global tool_root_dir + + set libgpp [lookfor_file ${tool_root_dir} libg++] + if { $libgpp != "" } { + append flags "-L${libgpp} " + append ld_library_path ":${libgpp}" + } + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++] + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} " + append ld_library_path ":${libstdcpp}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty] + if { $libiberty != "" } { + append flags "-L${libiberty} " + } + set librx [lookfor_file ${tool_root_dir} librx] + if { $librx != "" } { + append flags "-L${librx} " + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# g++_init -- called at the start of each subdir of tests +# + +proc g++_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global objdir srcdir + global ALWAYS_CXXFLAGS + global CXXFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GXX_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + global TEST_ALWAYS_FLAGS + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + # Many hosts now default to a non-ASCII C locale, however, so + # they can set a charset encoding here if they need. + if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII + } + + if ![info exists GXX_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GXX_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GXX_UNDER_TEST [transform c++] + } else { + set GXX_UNDER_TEST [findfile $base_dir/../../xg++ "$base_dir/../../xg++ -B$base_dir/../../" [findfile $base_dir/xg++ "$base_dir/xg++ -B$base_dir/" [transform c++]]] + } + } + } + + # Bleah, nasty. Bad taste. + if [ishost "*-dos-*" ] { + regsub "c\\+\\+" "$GXX_UNDER_TEST" "gcc" GXX_UNDER_TEST + } + + if ![is_remote host] { + if { [which $GXX_UNDER_TEST] == 0 } then { + perror "GXX_UNDER_TEST ($GXX_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + g++_maybe_build_wrapper "${tmpdir}/g++-testglue.o" "-fexceptions" + + if {![info exists CXXFLAGS]} { + set CXXFLAGS "" + } + + set ALWAYS_CXXFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation command. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_CXXFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_CXXFLAGS "additional_flags=[g++_include_flags [get_multilibs ${TOOL_OPTIONS}] ]" + lappend ALWAYS_CXXFLAGS "ldflags=[g++_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend ALWAYS_CXXFLAGS "additional_flags=[g++_include_flags [get_multilibs] ]" + lappend ALWAYS_CXXFLAGS "ldflags=[g++_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_CXXFLAGS "additional_flags=$TOOL_OPTIONS" + } + + # Make sure that lines are not wrapped. That can confuse the + # error-message parsing machinery. + lappend ALWAYS_CXXFLAGS "additional_flags=-fmessage-length=0" + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + if { [istarget *-*-darwin*] } { + lappend ALWAYS_CXXFLAGS "ldflags=-multiply_defined suppress" + } + + verbose -log "ALWAYS_CXXFLAGS set to $ALWAYS_CXXFLAGS" + + verbose "g++ is initialized" 3 +} + +# +# g++_target_compile -- compile a source file +# + +proc g++_target_compile { source dest type options } { + global tmpdir + global gpp_compile_options + global gluefile wrap_flags + global ALWAYS_CXXFLAGS + global GXX_UNDER_TEST + global flags_to_postpone + global board_info + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + global TEST_EXTRA_LIBS + if [info exists TEST_EXTRA_LIBS] { + lappend options "ldflags=$TEST_EXTRA_LIBS" + } + + lappend options "additional_flags=[libio_include_flags]" + lappend options "compiler=$GXX_UNDER_TEST" + lappend options "timeout=[timeout_value]" + + set options [concat $gpp_compile_options $options] + + set options [concat "$ALWAYS_CXXFLAGS" $options] + + # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is + # appended here to multilib_flags as it can be overridden by the latter + # if it was added earlier. After the target_compile, multilib_flags is + # restored to its orignal content. + set tboard [target_info name] + if {[board_info $tboard exists multilib_flags]} { + set orig_multilib_flags "[board_info [target_info name] multilib_flags]" + append board_info($tboard,multilib_flags) " $flags_to_postpone" + } + + set options [dg-additional-files-options $options $source] + + set result [target_compile $source $dest $type $options] + + if {[board_info $tboard exists multilib_flags]} { + set board_info($tboard,multilib_flags) $orig_multilib_flags + set flags_to_postpone "" + } + + return $result +} + +# +# ${tool}_option_help +# +# Changed "additional" to "extra" because runtest.exp treats --a* as --all. +# +# This shouldn't be necessary at all; it should be entirely redundant with +# --tool_opts, except that --tool_opts currently breaks multilib: see +# http://lists.gnu.org/archive/html/dejagnu/2002-10/msg00007.html + +proc ${tool}_option_help { } { + send_user " --extra_opts,OPTIONS\t\tUse OPTIONS to compile the testcase files. OPTIONS should be comma-separated.\n" +} + +# +# ${tool}_option_proc +# + +proc ${tool}_option_proc { option } { + if [regexp "^--extra_opts," $option] { + global gpp_compile_options + regsub "^--extra_opts," $option "" option + foreach x [split $option ","] { + lappend gpp_compile_options "additional_flags=$x" + } + verbose -log "gpp_compile_options set to $gpp_compile_options" + return 1 + } elseif [regexp "^--stds=" $option] { + global gpp_std_list + regsub "^--stds=" $option "" option + foreach x [split $option ","] { + lappend gpp_std_list "$x" + } + verbose -log "gpp_std_list set to $gpp_std_list" + return 1 + } else { + return 0 + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-defs.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-defs.exp new file mode 100644 index 0000000000000000000000000000000000000000..180a9ab3a52554bd8977df5e008b1b043ea45d69 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-defs.exp @@ -0,0 +1,441 @@ +# Copyright (C) 2001-2020 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 +# . + +load_lib target-libpath.exp + +load_lib wrapper.exp + +load_lib target-utils.exp + +# +# ${tool}_check_compile -- Reports and returns pass/fail for a compilation +# + +proc ${tool}_check_compile {testcase option objname gcc_output} { + global tool + set fatal_signal "*cc: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $gcc_output] then { + ${tool}_fail $testcase "Got Signal 6, $option" + return 0 + } + + if [string match "$fatal_signal 11" $gcc_output] then { + ${tool}_fail $testcase "Got Signal 11, $option" + return 0 + } + + if [string match "*internal compiler error*" $gcc_output] then { + ${tool}_fail $testcase "$option (internal compiler error)" + return 0 + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*cc:*warning:*" $gcc_output] then { + warning "$testcase: (with warnings) $option" + send_log "$gcc_output\n" + unresolved "$testcase, $option" + return 0 + } + + set gcc_output [prune_warnings $gcc_output] + + if { [info proc ${tool}-dg-prune] != "" } { + global target_triplet + set gcc_output [${tool}-dg-prune $target_triplet $gcc_output] + if [string match "*::unsupported::*" $gcc_output] then { + regsub -- "::unsupported::" $gcc_output "" gcc_output + unsupported "$testcase: $gcc_output" + return 0 + } + } else { + set unsupported_message [${tool}_check_unsupported_p $gcc_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + return 0 + } + } + + # remove any leftover LF/CR to make sure any output is legit + regsub -all -- "\[\r\n\]*" $gcc_output "" gcc_output + + # If any message remains, we fail. + if ![string match "" $gcc_output] then { + ${tool}_fail $testcase $option + return 0 + } + + # fail if the desired object file doesn't exist. + # FIXME: there's no way of checking for existence on a remote host. + if {$objname != "" && ![is3way] && ![file exists $objname]} { + ${tool}_fail $testcase $option + return 0 + } + + ${tool}_pass $testcase $option + return 1 +} + +# +# ${tool}_pass -- utility to record a testcase passed +# + +proc ${tool}_pass { testcase cflags } { + if { "$cflags" == "" } { + pass "$testcase" + } else { + pass "$testcase, $cflags" + } +} + +# +# ${tool}_fail -- utility to record a testcase failed +# + +proc ${tool}_fail { testcase cflags } { + if { "$cflags" == "" } { + fail "$testcase" + } else { + fail "$testcase, $cflags" + } +} + +# +# ${tool}_finish -- called at the end of every script that calls ${tool}_init +# +# Hide all quirks of the testing environment from the testsuites. Also +# undo anything that ${tool}_init did that needs undoing. +# + +proc ${tool}_finish { } { + # The testing harness apparently requires this. + global errorInfo + + if [info exists errorInfo] then { + unset errorInfo + } + + # Might as well reset these (keeps our caller from wondering whether + # s/he has to or not). + global prms_id bug_id + set prms_id 0 + set bug_id 0 +} + +# +# ${tool}_exit -- Does final cleanup when testing is complete +# + +proc ${tool}_exit { } { + global gluefile + + if [info exists gluefile] { + file_on_build delete $gluefile + unset gluefile + } +} + +# +# runtest_file_p -- Provide a definition for older dejagnu releases +# and assume the old syntax: foo1.exp bar1.c foo2.exp bar2.c. +# (delete after next dejagnu release). +# + +if { [info procs runtest_file_p] == "" } then { + proc runtest_file_p { runtests testcase } { + if { $runtests != "" && [regexp "\[.\]\[cC\]" $runtests] } then { + if { [lsearch $runtests [file tail $testcase]] >= 0 } then { + return 1 + } else { + return 0 + } + } + return 1 + } +} + +if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \ + && [info procs runtest_file_p] != [list] \ + && [info procs gcc_parallelize_saved_runtest_file_p] == [list] } then { + global gcc_runtest_parallelize_counter + global gcc_runtest_parallelize_counter_minor + global gcc_runtest_parallelize_enable + global gcc_runtest_parallelize_dir + global gcc_runtest_parallelize_last + + set gcc_runtest_parallelize_counter 0 + set gcc_runtest_parallelize_counter_minor 0 + set gcc_runtest_parallelize_enable 1 + set gcc_runtest_parallelize_dir [getenv GCC_RUNTEST_PARALLELIZE_DIR] + set gcc_runtest_parallelize_last 0 + + proc gcc_parallel_test_run_p { testcase } { + global gcc_runtest_parallelize_counter + global gcc_runtest_parallelize_counter_minor + global gcc_runtest_parallelize_enable + global gcc_runtest_parallelize_dir + global gcc_runtest_parallelize_last + + if { $gcc_runtest_parallelize_enable == 0 } { + return 1 + } + + # Only test the filesystem every 10th iteration + incr gcc_runtest_parallelize_counter_minor + if { $gcc_runtest_parallelize_counter_minor == 10 } { + set gcc_runtest_parallelize_counter_minor 0 + } + if { $gcc_runtest_parallelize_counter_minor != 1 } { + #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter $gcc_runtest_parallelize_last" + return $gcc_runtest_parallelize_last + } + + set path $gcc_runtest_parallelize_dir/$gcc_runtest_parallelize_counter + + if {![catch {open $path {RDWR CREAT EXCL} 0600} fd]} { + close $fd + set gcc_runtest_parallelize_last 1 + #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 1" + incr gcc_runtest_parallelize_counter + return 1 + } + set gcc_runtest_parallelize_last 0 + #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 0" + incr gcc_runtest_parallelize_counter + return 0 + } + + proc gcc_parallel_test_enable { val } { + global gcc_runtest_parallelize_enable + set gcc_runtest_parallelize_enable $val + } + + rename runtest_file_p gcc_parallelize_saved_runtest_file_p + proc runtest_file_p { runtests testcase } { + if ![gcc_parallelize_saved_runtest_file_p $runtests $testcase] { + return 0 + } + return [gcc_parallel_test_run_p $testcase] + } + +} else { + + proc gcc_parallel_test_run_p { testcase } { + return 1 + } + + proc gcc_parallel_test_enable { val } { + } + +} + +# Like dg-options, but adds to the default options rather than replacing them. + +proc dg-additional-options { args } { + upvar dg-extra-tool-flags extra-tool-flags + + if { [llength $args] > 3 } { + error "[lindex $args 0]: too many arguments" + return + } + + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "S" { eval lappend extra-tool-flags [lindex $args 1] } + "N" { } + "F" { error "[lindex $args 0]: `xfail' not allowed here" } + "P" { error "[lindex $args 0]: `xfail' not allowed here" } + } + } else { + eval lappend extra-tool-flags [lindex $args 1] + } +} + +# Record additional sources files that must be compiled along with the +# main source file. + +set additional_sources "" +set additional_sources_used "" + +proc dg-additional-sources { args } { + global additional_sources + set additional_sources [lindex $args 1] +} + +# Record additional files -- other than source files -- that must be +# present on the system where the compiler runs. + +set additional_files "" + +proc dg-additional-files { args } { + global additional_files + set additional_files [lindex $args 1] +} + +# Return an updated version of OPTIONS that mentions any additional +# source files registered with dg-additional-sources. SOURCE is the +# name of the test case. + +proc dg-additional-files-options { options source } { + global additional_sources + global additional_sources_used + global additional_files + set to_download [list] + if { $additional_sources != "" } then { + if [is_remote host] { + lappend options "additional_flags=$additional_sources" + } + regsub -all "^| " $additional_sources " [file dirname $source]/" additional_sources + if ![is_remote host] { + lappend options "additional_flags=$additional_sources" + } + set to_download [concat $to_download $additional_sources] + set additional_sources_used "$additional_sources" + set additional_sources "" + } + if { $additional_files != "" } then { + regsub -all "^| " $additional_files " [file dirname $source]/" additional_files + set to_download [concat $to_download $additional_files] + set additional_files "" + } + if [is_remote host] { + foreach file $to_download { + remote_download host $file + } + } + + return $options +} + +# Return a colon-separate list of directories to search for libraries +# for COMPILER, including multilib directories. + +proc gcc-set-multilib-library-path { compiler } { + set shlib_ext [get_shlib_extension] + set options [lrange $compiler 1 end] + set compiler [lindex $compiler 0] + + set libgcc_s_x [remote_exec host "$compiler" \ + "$options -print-file-name=libgcc_s.${shlib_ext}"] + if { [lindex $libgcc_s_x 0] == 0 \ + && [set libgcc_s_dir [file dirname [lindex $libgcc_s_x 1]]] != "" } { + set libpath ":${libgcc_s_dir}" + } else { + return "" + } + + set multi_dir_x [remote_exec host "$compiler" \ + "$options -print-multi-directory"] + set multi_lib_x [remote_exec host "$compiler" \ + "$options -print-multi-lib"] + if { [lindex $multi_dir_x 0] == 0 && [lindex $multi_lib_x 0] == 0 } { + set multi_dir [string trim [lindex $multi_dir_x 1]] + set multi_lib [string trim [lindex $multi_lib_x 1]] + if { "$multi_dir" == "." } { + set multi_root "$libgcc_s_dir" + } else { + set multi_match [string last "/$multi_dir" "$libgcc_s_dir"] + if { "$multi_match" < 0 } { + return $libpath + } + set multi_root [string range "$libgcc_s_dir" \ + 0 [expr $multi_match - 1]] + } + foreach i "$multi_lib" { + set mldir "" + regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir + set mldir [string trimright $mldir "\;@"] + if { "$mldir" == "$multi_dir" } { + continue + } + append libpath ":${multi_root}/${mldir}" + } + } + + return $libpath +} + +# A list of all uses of dg-regexp, each entry of the form: +# line-number regexp +# This is cleared at the end of each test by gcc-dg.exp's wrapper for dg-test. +set freeform_regexps [] + +# Directive for looking for a regexp, without any line numbers or other +# prefixes. + +proc dg-regexp { args } { + verbose "dg-regexp: args: $args" 2 + + global freeform_regexps + lappend freeform_regexps $args +} + +# Hook to be called by prune.exp's prune_gcc_output to +# look for the expected dg-regexp expressions, pruning them, +# reporting PASS for those that are found, and FAIL for +# those that weren't found. +# +# It returns a pruned version of its output. + +proc handle-dg-regexps { text } { + global freeform_regexps + global testname_with_flags + + foreach entry $freeform_regexps { + verbose " entry: $entry" 3 + + set linenum [lindex $entry 0] + set rexp [lindex $entry 1] + + # Escape newlines in $rexp so that we can print them in + # pass/fail results. + set escaped_regex [string map {"\n" "\\n"} $rexp] + verbose "escaped_regex: ${escaped_regex}" 4 + + set title "$testname_with_flags dg-regexp $linenum" + + # Use "regsub" to attempt to prune the pattern from $text + if {[regsub -line $rexp $text "" text]} { + # Success; the multiline pattern was pruned. + pass "$title was found: \"$escaped_regex\"" + } else { + fail "$title not found: \"$escaped_regex\"" + } + } + + return $text +} + +# Verify that the initial arg is a valid .dot file +# (by running dot -Tpng on it, and verifying the exit code is 0). + +proc dg-check-dot { args } { + verbose "dg-check-dot: args: $args" 2 + + set testcase [testname-for-summary] + + set dotfile [lindex $args 0] + verbose " dotfile: $dotfile" 2 + + set status [remote_exec host "dot" "-O -Tpng $dotfile"] + verbose " status: $status" 2 + if { [lindex $status 0] != 0 } { + fail "$testcase dg-check-dot $dotfile" + return 0 + } + + pass "$testcase dg-check-dot $dotfile" +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..58519b0421bd3f3c2fd5cd39766142c3323fca98 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-dg.exp @@ -0,0 +1,1331 @@ +# Copyright (C) 1997-2020 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 +# . + +load_lib dg.exp +load_lib file-format.exp +load_lib target-supports.exp +load_lib target-supports-dg.exp +load_lib scanasm.exp +load_lib scanrtl.exp +load_lib scantree.exp +load_lib scanltranstree.exp +load_lib scanipa.exp +load_lib scanwpaipa.exp +load_lib scanlang.exp +load_lib timeout.exp +load_lib timeout-dg.exp +load_lib prune.exp +load_lib libgloss.exp +load_lib target-libpath.exp +load_lib torture-options.exp +load_lib fortran-modules.exp +load_lib multiline.exp + +# We set LC_ALL and LANG to C so that we get the same error messages as expected. +setenv LC_ALL C +setenv LANG C + +# Many hosts now default to a non-ASCII C locale, however, so +# they can set a charset encoding here if they need. +if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII +} + +# Avoid sporadic data-losses with expect +match_max -d 10000 + +# Ensure GCC_COLORS is unset, for the rare testcases that verify +# how output is colorized. +if [info exists ::env(GCC_COLORS) ] { + unsetenv GCC_COLORS +} + +global GCC_UNDER_TEST +if ![info exists GCC_UNDER_TEST] { + set GCC_UNDER_TEST "[find_gcc]" +} + +# This file may be sourced, so don't override environment settings +# that have been previously setup. +if { $orig_environment_saved == 0 } { + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars +} + +# Some torture-options cause intermediate code output, unusable for +# testing using e.g. scan-assembler. In this variable are the options +# how to force it, when needed. +global gcc_force_conventional_output +set gcc_force_conventional_output "" + +set LTO_TORTURE_OPTIONS "" +if [info exists TORTURE_OPTIONS] { + set DG_TORTURE_OPTIONS $TORTURE_OPTIONS +} else { + # It is theoretically beneficial to group all of the O2/O3 options together, + # as in many cases the compiler will generate identical executables for + # all of them--and the c-torture testsuite will skip testing identical + # executables multiple times. + # Also note that -finline-functions is explicitly included in one of the + # items below, even though -O3 is also specified, because some ports may + # choose to disable inlining functions by default, even when optimizing. + set DG_TORTURE_OPTIONS [list \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions } \ + { -O3 -g } \ + { -Os } ] + + if [check_effective_target_lto] { + # When having plugin test both slim and fat LTO and plugin/nonplugin + # path. + if [check_linker_plugin_available] { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -fno-use-linker-plugin -flto-partition=none } \ + { -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects } + ] + } else { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -flto-partition=none } \ + { -O2 -flto } + ] + } + set gcc_force_conventional_output "-ffat-lto-objects" + } +} + +if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set DG_TORTURE_OPTIONS \ + [concat $DG_TORTURE_OPTIONS $ADDITIONAL_TORTURE_OPTIONS] +} + +proc dg-final { args } { + upvar dg-final-code final-code + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + } + set line [lindex $args 0] + set code [lindex $args 1] + set directive [lindex $code 0] + switch $directive { + gdb-test { + set code [linsert $code 1 $line] + } + } + append final-code "$code\n" +} + +global orig_environment_saved + +# Deduce generated files from tool flags, return finalcode string +proc schedule-cleanups { opts } { + global additional_sources + set finalcode "" + set testcases {} + lappend testcases [lindex [testname-for-summary] 0] + verbose "Cleanup testcases: $testcases" 4 + if { [info exists additional_sources] && $additional_sources != "" } { + lappend testcases $additional_sources + verbose "Cleanup testcases, additional: $additional_sources" 4 + } + verbose "Cleanup all options: $opts" 4 + + # First some fixups to transform stuff to something manageable .. + # --dump= should translate to -d with joined operand. + if [regexp -- {(^|\s+)--dump=[^\s]+(\s+|$)} $opts] { + regsub -all -- {--dump=} $opts {-d} opts + } + # -da and -dx are treated as shorthand for -fdump-rtl-all here + if [regexp -- {(^|\s+)-d[ax](\s+|$)} $opts] { + verbose "Cleanup -d seen" 4 + lappend opts "-fdump-rtl-all" + } + # .. and don't question why there is --dump=? and -d? + + # Then handle options that generate non-dump files + # TODO + # -fprofile-generate -> cleanup-coverage-files() + # -fstack-usage -> cleanup-stack-usage() + if [regexp -- {(^|\s+)-fstack-usage(\s+|$)} $opts] { + verbose "Cleanup -fstack-usage seen" 4 +# append finalcode "cleanup-stack-usage\n" + } + global keep_saved_temps_suffixes + if [info exists keep_saved_temps_suffixes ] { + verbose "dg-keep-saved-temps ${keep_saved_temps_suffixes}" 2 + } + # -save-temps -> cleanup-saved-temps() + if [regexp -- {(^|\s+)-?-save-temps(\s+|$)} $opts] { + verbose "Cleanup -save-temps seen" 4 + if [info exists keep_saved_temps_suffixes] { + append finalcode "cleanup-saved-temps ${keep_saved_temps_suffixes}\n" + } else { + append finalcode "cleanup-saved-temps\n" + } + } else { + if [info exists keep_saved_temps_suffixes ] { + error "dg-keep-saved-temps specified but testcase does not -save-temps" + return + } + } + # Finally see if there are any dumps in opts, otherwise we are done + if [regexp -- {(?=(?:^|[ \t]+)?)-fdump-[^ \t]+(?=(?:$|[ \t]+)?)} $opts] { + # Lang, Ipa, Rtl, Tree for simplicity + set ptn "{l,i,r,t}" + } else { + return $finalcode + } + # stem.ext.. + # (tree)passes can have multiple instances, thus optional trailing * + set ptn "\[0-9\]\[0-9\]\[0-9\]$ptn.*" + # Handle ltrans files around -flto + if [regexp -- {(^|\s+)-flto(\s+|$)} $opts] { + verbose "Cleanup -flto seen" 4 + set ltrans "{ltrans\[0-9\]*.,}" + } else { + set ltrans "" + } + set ptn "$ltrans$ptn" + verbose "Cleanup final ptn: $ptn" 4 + set tfiles {} + foreach src $testcases { + set basename [file tail $src] + if { $ltrans != "" } { + # ??? should we use upvar 1 output_file instead of this (dup ?) + set stem [file rootname $basename] + set basename_ext [file extension $basename] + if {$basename_ext != ""} { + regsub -- {^.*\.} $basename_ext {} basename_ext + } + lappend tfiles "$stem.{$basename_ext,exe}" + unset basename_ext + } else { + lappend tfiles $basename + } + } + if { [llength $tfiles] > 1 } { + set tfiles [join $tfiles ","] + set tfiles "{$tfiles}" + } + verbose "Cleanup final testcases: $tfiles" 4 + # We have to quote the regex + regsub -all {([][$^?+*()|\\{}])} "$tfiles.$ptn" {\\\1} ptn + set final "" + append final {remove-build-file } + append final "\"$ptn\"" + verbose "Cleanup final: $final" 4 + append finalcode "$final\n" + + return $finalcode +} + +# Define gcc callbacks for dg.exp. + +proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { + # Set up the compiler flags, based on what we're going to do. + + set options [list] + + switch $do_what { + "preprocess" { + set compile_type "preprocess" + set output_file "[file rootname [file tail $prog]].i" + } + "compile" { + set compile_type "assembly" + set output_file "[file rootname [file tail $prog]].s" + } + "assemble" { + set compile_type "object" + set output_file "[file rootname [file tail $prog]].o" + } + "precompile" { + set compile_type "precompiled_header" + set output_file "[file tail $prog].gch" + } + "link" { + set compile_type "executable" + set output_file "[file rootname [file tail $prog]].exe" + # The following line is needed for targets like the i960 where + # the default output file is b.out. Sigh. + } + "repo" { + set compile_type "object" + set output_file "[file rootname [file tail $prog]].o" + } + "run" { + set compile_type "executable" + # FIXME: "./" is to cope with "." not being in $PATH. + # Should this be handled elsewhere? + # YES. + set output_file "./[file rootname [file tail $prog]].exe" + # This is the only place where we care if an executable was + # created or not. If it was, dg.exp will try to run it. + catch { remote_file build delete $output_file } + } + default { + perror "$do_what: not a valid dg-do keyword" + return "" + } + } + + # Let { dg-final { action } } force options as returned by an + # optional proc ${action}_required_options. + upvar 2 dg-final-code finalcode + foreach x [split $finalcode "\n"] { + set finalcmd [lindex $x 0] + if { [info procs ${finalcmd}_required_options] != "" } { + foreach req [${finalcmd}_required_options] { + if { $req != "" + && [lsearch -exact $extra_tool_flags $req] == -1 } { + lappend extra_tool_flags $req + } + } + } + } + + append finalcode [schedule-cleanups "$options $extra_tool_flags"] + if { $extra_tool_flags != "" } { + lappend options "additional_flags=$extra_tool_flags" + } + + verbose "$target_compile $prog $output_file $compile_type $options" 4 + set comp_output [$target_compile "$prog" "$output_file" "$compile_type" $options] + + # Look for an internal compiler error, which sometimes masks the fact + # that we didn't get an expected error message. XFAIL an ICE via + # dg-xfail-if and use { dg-prune-output ".*internal compiler error.*" } + # to avoid a second failure for excess errors. + if [string match "*internal compiler error*" $comp_output] { + upvar 2 name name + fail "$name (internal compiler error)" + } + + if { $do_what == "repo" } { + set object_file "$output_file" + set output_file "[file rootname [file tail $prog]].exe" + set comp_output \ + [ concat $comp_output \ + [$target_compile "$object_file" "$output_file" \ + "executable" $options] ] + } + + return [list $comp_output $output_file] +} + +proc gcc-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 gcc_target_compile $prog $do_what $extra_tool_flags] +} + +# Global: should blank lines be allowed in the output? +# By default, they should not be. (PR other/69006) +# However, there are some ways for them to validly occur. +# If this variable is 0, blank lines are not allowed in output, +# if it is 1, they are allowed for a single testcase only and gcc-dg-prune +# will clear it again after checking it, if it is 2, they are disabled +# for all tests. +set allow_blank_lines 0 + +if { [check_effective_target_llvm_binutils] } { + set allow_blank_lines 2 +} + +# A command for use by testcases to mark themselves as expecting +# blank lines in the output. + +proc dg-allow-blank-lines-in-output { args } { + global allow_blank_lines + if { !$allow_blank_lines } { + set allow_blank_lines 1 + } +} + +proc gcc-dg-prune { system text } { + global additional_prunes + + # Extra prune rules that will apply to tests defined in a .exp file. + # Always remember to clear it in .exp file after executed all tests. + global dg_runtest_extra_prunes + + # Complain about blank lines in the output (PR other/69006) + global allow_blank_lines + if { !$allow_blank_lines } { + set num_blank_lines [llength [regexp -all -inline "\n\n" $text]] + if { $num_blank_lines } { + global testname_with_flags + fail "$testname_with_flags $num_blank_lines blank line(s) in output" + } + } + if { $allow_blank_lines == 1 } { + set allow_blank_lines 0 + } + + set text [prune_gcc_output $text] + + foreach p "$additional_prunes $dg_runtest_extra_prunes" { + if { [string length $p] > 0 } { + # Following regexp matches a complete line containing $p. + regsub -all "(^|\n)\[^\n\]*$p\[^\n\]*" $text "" text + } + } + + # If we see "region xxx is full" then the testcase is too big for ram. + # This is tricky to deal with in a large testsuite like c-torture so + # deal with it here. Just mark the testcase as unsupported. + if [regexp "(^|\n)\[^\n\]*: region \[^\n\]* is full" $text] { + # The format here is important. See dg.exp. + return "::unsupported::memory full" + } + + if { [regexp "(^|\n)\[^\n\]*: relocation truncated to fit" $text] + && [check_effective_target_tiny] } { + return "::unsupported::memory full" + } + + if [regexp "(^|\n)\[^\n\]* section.*will not fit in region" $text] { + return "::unsupported::memory full" + } + + if [regexp "(^|\n)\[^\n\]* region.*overflowed by" $text] { + return "::unsupported::memory full" + } + + if { [string match "*error: function pointers not supported*" $text] + && ![check_effective_target_function_pointers] } { + # The format here is important. See dg.exp. + return "::unsupported::funcptr" + } + if { [string match "*error: large return values not supported*" $text] + && ![check_effective_target_large_return_values] } { + # The format here is important. See dg.exp. + return "::unsupported::large return values" + } + + # If exceptions are disabled, mark tests expecting exceptions to be enabled + # as unsupported. + if { ![check_effective_target_exceptions_enabled] } { + if [regexp "(^|\n)\[^\n\]*: error: exception handling disabled" $text] { + return "::unsupported::exception handling disabled" + } + + if [regexp "(^|\n)\[^\n\]*: error: #error .__cpp_exceptions." $text] { + return "::unsupported::exception handling disabled" + } + } + + return $text +} + +# Replace ${tool}_load with a wrapper to provide for an expected nonzero +# exit status. Multiple languages include this file so this handles them +# all, not just gcc. +if { [info procs ${tool}_load] != [list] \ + && [info procs saved_${tool}_load] == [list] } { + rename ${tool}_load saved_${tool}_load + + proc ${tool}_load { program args } { + global tool + global shouldfail + global set_target_env_var + + set saved_target_env_var [list] + if { [info exists set_target_env_var] \ + && [llength $set_target_env_var] != 0 } { + if { [is_remote target] } { + return [list "unsupported" ""] + } + set-target-env-var + } + set result [eval [list saved_${tool}_load $program] $args] + if { [info exists set_target_env_var] \ + && [llength $set_target_env_var] != 0 } { + restore-target-env-var + } + if { $shouldfail != 0 } { + switch [lindex $result 0] { + "pass" { set status "fail" } + "fail" { set status "pass" } + default { set status [lindex $result 0] } + } + set result [list $status [lindex $result 1]] + } + + set result [list [lindex $result 0] [prune_file_path [lindex $result 1]]] + return $result + } +} + +proc dg-set-target-env-var { args } { + global set_target_env_var + if { [llength $args] != 3 } { + error "dg-set-target-env-var: need two arguments" + return + } + set var [lindex $args 1] + set value [lindex $args 2] + verbose "dg-set-target-env-var $var $value" 2 + lappend set_target_env_var [list $var $value] +} + +proc set-target-env-var { } { + global set_target_env_var + upvar 1 saved_target_env_var saved_target_env_var + foreach env_var $set_target_env_var { + set var [lindex $env_var 0] + set value [lindex $env_var 1] + if [info exists ::env($var)] { + lappend saved_target_env_var [list $var 1 $::env($var)] + } else { + lappend saved_target_env_var [list $var 0] + } + setenv $var $value + } +} + +proc restore-target-env-var { } { + upvar 1 saved_target_env_var saved_target_env_var + for { set env_vari [llength $saved_target_env_var] } { + [incr env_vari -1] >= 0 } {} { + set env_var [lindex $saved_target_env_var $env_vari] + set var [lindex $env_var 0] + if [lindex $env_var 1] { + setenv $var [lindex $env_var 2] + } else { + unsetenv $var + } + } +} + +proc dg-set-compiler-env-var { args } { + global set_compiler_env_var + global saved_compiler_env_var + if { [llength $args] != 3 } { + error "dg-set-compiler-env-var: need two arguments" + return + } + set var [lindex $args 1] + set value [lindex $args 2] + verbose "dg-set-compiler-env-var $var $value" 2 + if [info exists ::env($var)] { + lappend saved_compiler_env_var [list $var 1 $::env($var)] + } else { + lappend saved_compiler_env_var [list $var 0] + } + setenv $var $value + lappend set_compiler_env_var [list $var $value] +} + +proc restore-compiler-env-var { } { + global saved_compiler_env_var + for { set env_vari [llength $saved_compiler_env_var] } { + [incr env_vari -1] >= 0 } {} { + set env_var [lindex $saved_compiler_env_var $env_vari] + set var [lindex $env_var 0] + if [lindex $env_var 1] { + setenv $var [lindex $env_var 2] + } else { + unsetenv $var + } + } +} + +# Utility routines. + +# +# search_for -- looks for a string match in a file +# +proc search_for { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc gcc-dg-runtest { testcases flags default-extra-flags } { + global runtests + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS LTO_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS [list {}] $LTO_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + global torture_with_loops torture_without_loops + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + global torture_current_flags + set torture_current_flags "$flags_t" + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} + +proc gcc-dg-debug-runtest { target_compile trivial opt_opts testcases } { + global srcdir subdir + + if ![info exists DEBUG_TORTURE_OPTIONS] { + set DEBUG_TORTURE_OPTIONS "" + foreach type {-gdwarf-2 -gstabs -gstabs+ -gxcoff -gxcoff+} { + set comp_output [$target_compile \ + "$srcdir/$subdir/$trivial" "trivial.S" assembly \ + "additional_flags=$type"] + if { ! [string match "*: target system does not support the * debug format*" \ + $comp_output] } { + remove-build-file "trivial.S" + foreach level {1 "" 3} { + if { ($type == "-gdwarf-2") && ($level != "") } { + lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}" "-g${level}" "$opt" ] + } + } else { + lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}${level}" "$opt" ] + } + } + } + } + } + } + + verbose -log "Using options $DEBUG_TORTURE_OPTIONS" + + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags $DEBUG_TORTURE_OPTIONS { + set doit 1 + + # These tests check for information which may be deliberately + # suppressed at -g1. + if { ([string match {*/debug-[126].c} "$nshort"] \ + || [string match {*/enum-1.c} "$nshort"] \ + || [string match {*/enum-[12].C} "$nshort"]) \ + && ([string match "*1" [lindex "$flags" 0] ] + || [lindex "$flags" 1] == "-g1") } { + set doit 0 + } + + # High optimization can remove the variable whose existence is tested. + # Dwarf debugging with commentary (-dA) preserves the symbol name in the + # assembler output, but stabs debugging does not. + # http://gcc.gnu.org/ml/gcc-regression/2003-04/msg00095.html + if { [string match {*/debug-[12].c} "$nshort"] \ + && [string match "*O*" "$flags"] \ + && ( [string match "*coff*" "$flags"] \ + || [string match "*stabs*" "$flags"] ) } { + set doit 0 + } + + if { $doit } { + verbose -log "Testing $nshort, $flags" 1 + dg-test $test $flags "" + } + } + } +} + +# Prune any messages matching ARGS[1] (a regexp) from test output. +proc dg-prune-output { args } { + global additional_prunes + + if { [llength $args] != 2 } { + error "[lindex $args 1]: need one argument" + return + } + + lappend additional_prunes [lindex $args 1] +} + +# Remove files matching the pattern from the build machine. +proc remove-build-file { pat } { + verbose "remove-build-file `$pat'" 2 + set file_list "[glob -nocomplain $pat]" + verbose "remove-build-file `$file_list'" 2 + foreach output_file $file_list { + if [is_remote host] { + # Ensure the host knows the file is gone by deleting there + # first. + remote_file host delete $output_file + } + remote_file build delete $output_file + } +} + +# Remove runtime-generated profile file for the current test. +proc cleanup-profile-file { } { + remove-build-file "mon.out" + remove-build-file "gmon.out" +} + +# Remove compiler-generated coverage files for the current test. +proc cleanup-coverage-files { } { + global additional_sources_used + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + remove-build-file "[file rootname [file tail $testcase]].gc??" + + # Clean up coverage files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[file rootname [file tail $srcfile]].gc??" + } + } +} + +# Remove a final insns dump file for the current test. +proc cleanup-final-insns-dump { } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + remove-build-file "[file rootname [file tail $testcase]].s.gkd" + + # Clean up files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[file rootname [file tail $srcfile]].s.gkd" + } + } +} + +# Remove a stack usage file for the current test. +proc cleanup-stack-usage { } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + remove-build-file "[file rootname [file tail $testcase]].su" + + # Clean up files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[file rootname [file tail $srcfile]].su" + } + } +} + +# Remove an Ada spec file for the current test. +proc cleanup-ada-spec { } { + global additional_sources_used + set testcase [testname-for-summary] + remove-build-file "[get_ada_spec_filename $testcase]" + + # Clean up files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[get_ada_spec_filename $srcfile]" + } + } +} + +# Remove files kept by --save-temps for the current test. +# +# Currently this is only .i, .ii, .s and .o files, but more can be added +# if there are tests generating them. +# ARGS is a list of suffixes to NOT delete. +proc cleanup-saved-temps { args } { + global additional_sources_used + set suffixes {} + + # add the to-be-kept suffixes + foreach suffix {".mii" ".ii" ".i" ".s" ".o" ".gkd" ".res" ".ltrans.out"} { + if {[lsearch $args $suffix] < 0} { + lappend suffixes $suffix + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + foreach suffix $suffixes { + remove-build-file "[file rootname [file tail $testcase]]$suffix" + remove-build-file "[file rootname [file tail $testcase]].exe$suffix" + remove-build-file "[file rootname [file tail $testcase]].exe.ltrans\[0-9\]*$suffix" + # -fcompare-debug dumps + remove-build-file "[file rootname [file tail $testcase]].gk$suffix" + } + + # Clean up saved temp files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + foreach suffix $suffixes { + remove-build-file "[file rootname [file tail $srcfile]]$suffix" + remove-build-file "[file rootname [file tail $srcfile]].exe$suffix" + remove-build-file "[file rootname [file tail $srcfile]].exe.ltrans\[0-9\]*$suffix" + + # -fcompare-debug dumps + remove-build-file "[file rootname [file tail $srcfile]].gk$suffix" + } + } + } +} + + +# Files to be kept after cleanup of --save-temps for the current test. +# ARGS is a list of suffixes to NOT delete. +proc dg-keep-saved-temps { args } { + global keep_saved_temps_suffixes + set keep_saved_temps_suffixes {} + + # add the to-be-kept suffixes + foreach suffix {".mii" ".ii" ".i" ".s" ".o" ".gkd" ".res" ".ltrans.out"} { + if {[lsearch $args $suffix] >= 0} { + lappend keep_saved_temps_suffixes $suffix + } + } + if { [llength keep_saved_temps_suffixes] < 1 } { + error "dg-keep-saved-temps ${args} did not match any known suffix" + } +} + +# Scan Fortran modules for a given regexp. +# +# Argument 0 is the module name +# Argument 1 is the regexp to match +proc scan-module { args } { + set modfilename [string tolower [lindex $args 0]].mod + set fd [open [list | gzip -dc $modfilename] r] + set text [read $fd] + close $fd + + set testcase [testname-for-summary] + if [regexp -- [lindex $args 1] $text] { + pass "$testcase scan-module [lindex $args 1]" + } else { + fail "$testcase scan-module [lindex $args 1]" + } +} + +# Scan Fortran modules for absence of a given regexp. +# +# Argument 0 is the module name +# Argument 1 is the regexp to match +proc scan-module-absence { args } { + set modfilename [string tolower [lindex $args 0]].mod + set fd [open [list | gzip -dc $modfilename] r] + set text [read $fd] + close $fd + + set testcase [testname-for-summary] + if [regexp -- [lindex $args 1] $text] { + fail "$testcase scan-module [lindex $args 1]" + } else { + pass "$testcase scan-module [lindex $args 1]" + } +} + +# Verify that the compiler output file exists, invoked via dg-final. +proc output-exists { args } { + # Process an optional target or xfail list. + if { [llength $args] >= 1 } { + switch [dg-process-target [lindex $args 0]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # Access variable from gcc-dg-test-1. + upvar 2 output_file output_file + + if [file exists $output_file] { + pass "$testcase output-exists $output_file" + } else { + fail "$testcase output-exists $output_file" + } +} + +# Verify that the compiler output file does not exist, invoked via dg-final. +proc output-exists-not { args } { + # Process an optional target or xfail list. + if { [llength $args] >= 1 } { + switch [dg-process-target [lindex $args 0]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # Access variable from gcc-dg-test-1. + upvar 2 output_file output_file + + if [file exists $output_file] { + fail "$testcase output-exists-not $output_file" + } else { + pass "$testcase output-exists-not $output_file" + } +} + +# We need to make sure that additional_* are cleared out after every +# test. It is not enough to clear them out *before* the next test run +# because gcc-target-compile gets run directly from some .exp files +# (outside of any test). (Those uses should eventually be eliminated.) + +# Because the DG framework doesn't provide a hook that is run at the +# end of a test, we must replace dg-test with a wrapper. + +if { [info procs saved-dg-test] == [list] } { + rename dg-test saved-dg-test + + # Helper function for cleanups that should happen after the call + # to the real dg-test, whether or not it returns normally, or + # fails with an error. + proc cleanup-after-saved-dg-test { } { + global additional_files + global additional_sources + global additional_sources_used + global additional_prunes + global compiler_conditional_xfail_data + global shouldfail + global testname_with_flags + global set_target_env_var + global set_compiler_env_var + global saved_compiler_env_var + global keep_saved_temps_suffixes + global nn_line_numbers_enabled + global multiline_expected_outputs + global freeform_regexps + global save_linenr_varnames + + set additional_files "" + set additional_sources "" + set additional_sources_used "" + set additional_prunes "" + set shouldfail 0 + if [info exists set_target_env_var] { + unset set_target_env_var + } + if [info exists set_compiler_env_var] { + restore-compiler-env-var + unset set_compiler_env_var + unset saved_compiler_env_var + } + if [info exists keep_saved_temps_suffixes] { + unset keep_saved_temps_suffixes + } + unset_timeout_vars + if [info exists compiler_conditional_xfail_data] { + unset compiler_conditional_xfail_data + } + if [info exists testname_with_flags] { + unset testname_with_flags + } + set nn_line_numbers_enabled 0 + set multiline_expected_outputs [] + set freeform_regexps [] + + if { [info exists save_linenr_varnames] } { + foreach varname $save_linenr_varnames { + # Cleanup varname + eval global $varname + eval unset $varname + + # Cleanup varname_used, or generate defined-but-not-used + # warning. + set varname_used used_$varname + eval global $varname_used + eval set used [info exists $varname_used] + if { $used } { + eval unset $varname_used + } else { + regsub {^saved_linenr_} $varname "" org_varname + warning "dg-line var $org_varname defined, but not used" + } + } + unset save_linenr_varnames + } + } + + proc dg-test { args } { + global errorInfo + + if { [ catch { eval saved-dg-test $args } errmsg ] } { + set saved_info $errorInfo + cleanup-after-saved-dg-test + error $errmsg $saved_info + } + cleanup-after-saved-dg-test + } +} + +if { [info procs saved-dg-warning] == [list] \ + && [info exists gcc_warning_prefix] } { + rename dg-warning saved-dg-warning + + proc dg-warning { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + global gcc_warning_prefix + + process-message saved-dg-warning "$gcc_warning_prefix" "$args" + } +} + +if { [info procs saved-dg-error] == [list] \ + && [info exists gcc_error_prefix] } { + rename dg-error saved-dg-error + + proc dg-error { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + global gcc_error_prefix + + process-message saved-dg-error "$gcc_error_prefix" "$args" + } + + # Override dg-bogus at the same time. It doesn't handle a prefix + # but its expression should include a column number. Otherwise the + # line number can match the column number for other messages, leading + # to insanity. + rename dg-bogus saved-dg-bogus + + proc dg-bogus { args } { + upvar dg-messages dg-messages + process-message saved-dg-bogus "" $args + } +} + +# Set variable VARNAME to LINENR + +proc dg-line { linenr varname } { + set org_varname $varname + set varname "saved_linenr_$varname" + eval global $varname + + # Generate defined-but-previously-defined error. + eval set var_defined [info exists $varname] + if { $var_defined } { + eval set deflinenr \$$varname + error "dg-line var $org_varname defined at line $linenr, but previously defined at line $deflinenr" + return + } + + eval set $varname $linenr + + # Schedule cleanup of varname by cleanup-after-saved-dg-test + global save_linenr_varnames + if { [info exists save_linenr_varnames] } { + lappend save_linenr_varnames $varname + } else { + set save_linenr_varnames [list $varname] + } +} + +# Get the absolute line number corresponding to: +# - a relative line number (a non-null useline is required), or +# - a line number variable reference. +# Argument 0 is the line number on which line was used +# Argument 1 is the relative line number or line number variable reference +# +proc get-absolute-line { useline line } { + if { "$line" == "." } { + return $useline + } + + if { [regsub "^\.\[+-\](\[0-9\]+)$" $line "\\1" num] && $useline != "" } { + # Handle relative line specification, .+1 or .-1 etc. + set num [expr $useline [string index $line 1] $num] + return $num + } + + if { ! [regsub "^(\[a-zA-Z\]\[a-zA-Z0-9_\]*)$" $line "\\1" varname] } { + return $line + } + + # Handle linenr variable defined by dg-line + set org_varname $varname + set varname "saved_linenr_$varname" + eval global $varname + + # Generate used-but-not-defined error. + eval set var_defined [info exists $varname] + if { ! $var_defined } { + if { "$useline" != "" } { + error "dg-line var $org_varname used at line $useline, but not defined" + } else { + error "dg-line var $org_varname used, but not defined" + } + return + } + + # Note that varname has been used. + set varname_used "used_$varname" + eval global $varname_used + eval set $varname_used 1 + + # Get line number from var and use it. + eval set num \$$varname + set line $num +} + +# Modify the regular expression saved by a DejaGnu message directive to +# include a prefix and to force the expression to match a single line. +# MSGPROC is the procedure to call. +# MSGPREFIX is the prefix to prepend. +# DGARGS is the original argument list. + +proc process-message { msgproc msgprefix dgargs } { + upvar dg-messages dg-messages + + if { [llength $dgargs] == 5 } { + set num [get-absolute-line [lindex $dgargs 0] [lindex $dgargs 4]] + set dgargs [lreplace $dgargs 4 4 $num] + } + + # Process the dg- directive, including adding the regular expression + # to the new message entry in dg-messages. + set msgcnt [llength ${dg-messages}] + eval $msgproc $dgargs + + # If the target expression wasn't satisfied there is no new message. + if { [llength ${dg-messages}] == $msgcnt } { + return; + } + + # Get the entry for the new message. Prepend the message prefix to + # the regular expression and make it match a single line. + set newentry [lindex ${dg-messages} end] + set expmsg [lindex $newentry 2] + + set column "" + # Handle column numbers from the specified expression (if there is + # one) and set up the search expression that will be used by DejaGnu. + if [regexp {^-:} $expmsg] { + # The expected column is -, so shouldn't appear. + set expmsg [string range $expmsg 2 end] + } elseif [regexp {^[0-9]+:} $expmsg column] { + # The expression in the directive included a column number. + # Remove it from the original expression and move it + # to the proper place in the search expression. + set expmsg [string range $expmsg [string length $column] end] + set column "$column " + } elseif [string match "" [lindex $newentry 0]] { + # The specified line number is 0; don't expect a column number. + } else { + # There is no column number in the search expression, but we + # should expect one in the message itself. + set column {[0-9]+: } + } + set expmsg "$column$msgprefix\[^\n\]*$expmsg" + set newentry [lreplace $newentry 2 2 $expmsg] + + set dg-messages [lreplace ${dg-messages} end end $newentry] + verbose "process-message:\n${dg-messages}" 3 +} + +# Look for messages that don't have standard prefixes. + +proc dg-message { args } { + upvar dg-messages dg-messages + process-message saved-dg-warning "" $args +} + +# Look for a location marker of the form +# file:line:column: +# with no extra text (e.g. a line-span separator). + +proc dg-locus { args } { + upvar dg-messages dg-messages + + # Process the dg- directive, including adding the regular expression + # to the new message entry in dg-messages. + set msgcnt [llength ${dg-messages}] + eval saved-dg-warning $args + + # If the target expression wasn't satisfied there is no new message. + if { [llength ${dg-messages}] == $msgcnt } { + return; + } + + # Get the entry for the new message. Prepend the message prefix to + # the regular expression and make it match a single line. + set newentry [lindex ${dg-messages} end] + set expmsg [lindex $newentry 2] + + set newentry [lreplace $newentry 2 2 $expmsg] + set dg-messages [lreplace ${dg-messages} end end $newentry] + verbose "process-message:\n${dg-messages}" 3 +} + +# Handle output from -fopt-info for MSG_OPTIMIZED_LOCATIONS: +# a successful optimization. + +proc dg-optimized { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + + process-message saved-dg-warning "optimized:" "$args" +} + +# Handle output from -fopt-info for MSG_MISSED_OPTIMIZATION: +# a missed optimization. + +proc dg-missed { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + + process-message saved-dg-warning "missed:" "$args" +} + +# Check the existence of a gdb in the path, and return true if there +# is one. +# +# Set env(GDB_FOR_GCC_TESTING) accordingly. + +proc gdb-exists { args } { + if ![info exists ::env(GDB_FOR_GCC_TESTING)] { + global GDB + if ![info exists ::env(GDB_FOR_GCC_TESTING)] { + if [info exists GDB] { + setenv GDB_FOR_GCC_TESTING "$GDB" + } else { + setenv GDB_FOR_GCC_TESTING "[transform gdb]" + } + } + } + if { [which $::env(GDB_FOR_GCC_TESTING)] != 0 } { + return 1; + } + return 0; +} + +# Helper function for scan-symbol and scan-symbol-not. It scans a symbol in +# the final executable and return 1 if present, otherwise fail. +# +# Argument 0 is the regexp to match. +# Argument 1 handles expected failures and the like +proc scan-symbol-common { scan_directive args } { + global nm + global base_dir + + # Access variable from gcc-dg-test-1 or lto-execute. + upvar 3 output_file output_file + + if { [llength $args] >= 2 } { + switch [dg-process-target [lindex $args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find nm like we find g++ in g++.exp. + if ![info exists nm] { + set nm [findfile $base_dir/../../../binutils/nm \ + $base_dir/../../../binutils/nm \ + [findfile $base_dir/../../nm $base_dir/../../nm \ + [findfile $base_dir/nm $base_dir/nm \ + [transform nm]]]] + verbose -log "nm is $nm" + } + + set output_file "[glob -nocomplain $output_file]" + if { $output_file == "" } { + fail "$scan_directive $args: output file does not exist" + return + } + + set fd [open "| $nm $output_file" r] + set text [read $fd] + close $fd + + if [regexp -- [lindex $args 0] $text] { + return 1 + } else { + return 0 + } +} + +# Utility for scanning a symbol in the final executable, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match. +# Argument 1 handles expected failures and the like +proc scan-symbol { args } { + set testcase [testname-for-summary] + if { [scan-symbol-common "scan-symbol" $args]} { + pass "$testcase scan-symbol $args" + } else { + fail "$testcase scan-symbol $args" + } +} + +# Utility for scanning a symbol in the final executable, invoked via dg-final. +# Call pass if pattern is absent, otherwise fail. +# +# Argument 0 is the regexp to match. +# Argument 1 handles expected failures and the like +proc scan-symbol-not { args } { + set testcase [testname-for-summary] + if { [scan-symbol-common "scan-symbol-not" $args]} { + fail "$testcase scan-symbol-not $args" + } else { + pass "$testcase scan-symbol-not $args" + } +} + +set additional_prunes "" +set dg_runtest_extra_prunes "" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-gdb-test.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-gdb-test.exp new file mode 100644 index 0000000000000000000000000000000000000000..343b16b53cadbf02ab4318c0517f31dc9606fa4d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc-gdb-test.exp @@ -0,0 +1,183 @@ +# Copyright (C) 2009-2020 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 +# . + +# Utility for testing variable values using gdb, invoked via dg-final. +# Call pass if variable has the desired value, otherwise fail. +# +# Argument 0 is the line number on which to put a breakpoint +# Argument 1 is the name of the variable to be checked +# possibly prefixed with type: to get the type of the variable +# instead of the value of the variable (the default). +# Argument 2 is the expected value (or type) of the variable +# When asking for the value, the expected value is produced +# calling print on it in gdb. When asking for the type it is +# the literal string with extra whitespace removed. +# Argument 3 handles expected failures and the like +proc gdb-test { useline args } { + if { ![isnative] || [is_remote target] } { return } + + if { [llength $args] >= 4 } { + switch [dg-process-target [lindex $args 3]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # This assumes that we are three frames down from dg-test, and that + # it still stores the filename of the testcase in a local variable "name". + # A cleaner solution would require a new DejaGnu release. + upvar 2 name testcase + upvar 2 prog prog + + # The command to run on the variable + set arg1 [lindex $args 1] + if { [string equal -length 5 "type:" $arg1] == 1 } { + set command "ptype" + set var [string range $arg1 5 end] + } else { + set command "print" + set var $arg1 + } + + set line [lindex $args 0] + if { [string range $line 0 0] == "@" } { + set line [string range $line 1 end] + } else { + set line [get-absolute-line $useline $line] + } + + set gdb_name $::env(GUALITY_GDB_NAME) + set testname "$testcase line $line [lindex $args 1] == [lindex $args 2]" + set output_file "[file rootname [file tail $prog]].exe" + set cmd_file "[file rootname [file tail $prog]].gdb" + + set fd [open $cmd_file "w"] + puts $fd "break $line" + puts $fd "run" + puts $fd "$command $var" + if { $command == "print" } { + # For values, let gdb interpret them by printing them. + puts $fd "print [lindex $args 2]" + } else { + # Since types can span multiple lines, we need an end marker. + puts $fd "echo TYPE_END\\n" + } + puts $fd "quit" + close $fd + + send_log "Spawning: $gdb_name -nx -nw -quiet -batch -x $cmd_file ./$output_file\n" + set res [remote_spawn target "$gdb_name -nx -nw -quiet -batch -x $cmd_file ./$output_file"] + if { $res < 0 || $res == "" } { + unsupported "$testname" + file delete $cmd_file + return + } + + remote_expect target [timeout_value] { + # Too old GDB + -re "Unhandled dwarf expression|Error in sourced command file|. + +load_lib timeout.exp + +# Utility for running a given test through the simulate-thread harness +# using gdb. This is invoked via dg-final. +# +# Adapted from the guality harness. +# +# Call 'fail' if a given test printed "FAIL:", otherwise call 'pass'. + +proc simulate-thread { args } { + if { ![isnative] || [is_remote target] } { return } + + if { [llength $args] == 1 } { + switch [dg-process-target [lindex $args 0]] { + "F" { setup_xfail "*-*-*" } + } + } + + # This assumes that we are three frames down from dg-test, and that + # it still stores the filename of the testcase in a local variable "name". + # A cleaner solution would require a new DejaGnu release. + upvar 2 name testcase + upvar 2 prog prog + upvar 2 srcdir testsuite_dir + + set gdb_name $::env(GDB_FOR_GCC_TESTING) + set exec_file "[file rootname [file tail $prog]].exe" + set cmd_file "$testsuite_dir/gcc.dg/simulate-thread/simulate-thread.gdb" + + if ![file exists $exec_file] { + return + } + + set message "thread simulation test" + + send_log "Spawning: $gdb_name -nx -nw -batch -x $cmd_file ./$exec_file\n" + set res [remote_spawn target "$gdb_name -nx -nw -batch -x $cmd_file ./$exec_file"] + if { $res < 0 || $res == "" } { + unsupported "$testcase $message" + return + } + + set gdb_worked 0 + + remote_expect target [timeout_value] { + # Too old GDB + -re "Unhandled dwarf expression|Error in sourced command file" { + unsupported "$testcase $message" + remote_close target + return + } + -re "FAIL:" { + fail "$testcase $message" + remote_close target + return + } + # If the gdb output contained simulate_thread_done, assume + # that at the very least, we had a working gdb that was able + # to break in simulate_thread_done. + -re "simulate_thread_done" { + set gdb_worked 1 + exp_continue + } + timeout { + fail "$testcase $message" + remote_close target + return + } + } + + remote_close target + if {$gdb_worked} { + pass "$testcase $message" + } else { + # Unsupported in the absence of a sane GDB. + unsupported "$testcase $message" + } + return +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc.exp new file mode 100644 index 0000000000000000000000000000000000000000..16935b8f3b06653cc9714fcc4b22959e0012e657 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcc.exp @@ -0,0 +1,179 @@ +# Copyright (C) 1992-2020 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Currently maintained by Doug Evans (dje@cygnus.com) + +# This file is loaded by the tool init file (eg: unix.exp). It provides +# default definitions for gcc_start, etc. and other supporting cast members. + +# These globals are used by gcc_start if no compiler arguments are provided. +# They are also used by the various testsuites to define the environment: +# where to find stdio.h, libc.a, etc. + +# we want to use libgloss so we can get find_gcc. +load_lib libgloss.exp +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp + +# +# GCC_UNDER_TEST is the compiler under test. +# + +# +# default_gcc_version -- extract and print the version number of the compiler +# + +proc default_gcc_version { } { + global GCC_UNDER_TEST + + gcc_init + + # ignore any arguments after the command + set compiler [lindex $GCC_UNDER_TEST 0] + + if ![is_remote host] { + set compiler_name [which $compiler] + } else { + set compiler_name $compiler + } + + # verify that the compiler exists + if { $compiler_name != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + clone_output "$compiler_name $version\n" + } else { + clone_output "Couldn't determine version of $compiler_name: $output\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gcc_version -- Call default_gcc_version, so we can override it if needed. +# + +proc gcc_version { } { + default_gcc_version +} + +# +# gcc_init -- called at the start of each .exp script. +# +# There currently isn't much to do, but always using it allows us to +# make some enhancements without having to go back and rewrite the scripts. +# + +set gcc_initialized 0 + +proc gcc_init { args } { + global tmpdir + global libdir + global gluefile wrap_flags + global gcc_initialized + global GCC_UNDER_TEST + global TOOL_EXECUTABLE + global gcc_warning_prefix + global gcc_error_prefix + + if { $gcc_initialized == 1 } { return; } + + if ![info exists GCC_UNDER_TEST] { + if [info exists TOOL_EXECUTABLE] { + set GCC_UNDER_TEST $TOOL_EXECUTABLE + } else { + set GCC_UNDER_TEST "[find_gcc]" + } + } + + if ![info exists tmpdir] then { + set tmpdir /tmp + } + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + gcc_maybe_build_wrapper "${tmpdir}/gcc-testglue.o" +} + +# +# gcc_target_compile -- compile a source file +# + +proc gcc_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global GCC_UNDER_TEST + global TOOL_OPTIONS + global TEST_ALWAYS_FLAGS + global flags_to_postpone + global board_info + + if {[target_info needs_status_wrapper] != "" && \ + [target_info needs_status_wrapper] != "0" && \ + [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" + } + + global TEST_EXTRA_LIBS + if [info exists TEST_EXTRA_LIBS] { + lappend options "ldflags=$TEST_EXTRA_LIBS" + } + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options] + } + + # TOOL_OPTIONS must come first, so that it doesn't override testcase + # specific options. + if [info exists TOOL_OPTIONS] { + set options [concat "{additional_flags=$TOOL_OPTIONS}" $options] + } + + # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is + # appended here to multilib_flags as it can be overridden by the latter + # if it was added earlier. After the target_compile, multilib_flags is + # restored to its orignal content. + set tboard [target_info name] + if {[board_info $tboard exists multilib_flags]} { + set orig_multilib_flags "[board_info [target_info name] multilib_flags]" + append board_info($tboard,multilib_flags) " $flags_to_postpone" + } + + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GCC_UNDER_TEST" + set options [dg-additional-files-options $options $source] + set return_val [target_compile $source $dest $type $options] + + if {[board_info $tboard exists multilib_flags]} { + set board_info($tboard,multilib_flags) $orig_multilib_flags + set flags_to_postpone "" + } + + return $return_val +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcov.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcov.exp new file mode 100644 index 0000000000000000000000000000000000000000..a2832ec4f05fa9d78e7dfe4ff706ea4efb7ae877 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gcov.exp @@ -0,0 +1,374 @@ +# Copyright (C) 1997-2020 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 +# . + +# Verify various kinds of gcov output: line counts, branch percentages, +# and call return percentages. None of this is language-specific. + +global GCOV + +# +# clean-gcov-file -- delete a working file the compiler creates for gcov +# +# TESTCASE is the name of the test. +# SUFFIX is file suffix + +proc clean-gcov-file { testcase suffix } { + set basename [file tail $testcase] + set base [file rootname $basename] + remote_file host delete $base.$suffix +} + +# +# clean-gcov -- delete the working files the compiler creates for gcov +# +# TESTCASE is the name of the test. +# +proc clean-gcov { testcase } { + clean-gcov-file $testcase "gcno" + clean-gcov-file $testcase "gcda" + clean-gcov-file $testcase "gcov" + clean-gcov-file $testcase "h.gcov" +} + +# +# verify-lines -- check that line counts are as expected +# +# TESTNAME is the name of the test, including unique flags. +# TESTCASE is the name of the test file. +# FILE is the name of the gcov output file. +# +proc verify-lines { testname testcase file } { + #send_user "verify-lines\n" + global subdir + + set failed 0 + set fd [open $file r] + while { [gets $fd line] >= 0 } { + # We want to match both "-" and "#####" as count as well as numbers, + # since we want to detect lines that shouldn't be marked as covered. + if [regexp "^ *(\[^:]*): *(\[0-9\\-#]+):.*count\\((\[0-9\\-#=\\.kMGTPEZY\*]+)\\)(.*)" \ + "$line" all is n shouldbe rest] { + if [regexp "^ *{(.*)}" $rest all xfailed] { + switch [dg-process-target $xfailed] { + "N" { continue } + "F" { setup_xfail "*-*-*" } + } + } + if { $is == "" } { + fail "$testname line $n: no data available" + incr failed + } elseif { $is != $shouldbe } { + fail "$testname line $n: is $is:should be $shouldbe" + incr failed + } else { + pass "$testname count for line $n" + } + } + } + close $fd + return $failed +} + + +# +# verify-branches -- check that branch percentages are as expected +# +# TESTNAME is the name of the test, including unique flags. +# TESTCASE is the name of the test file. +# FILE is the name of the gcov output file. +# +# Checks are based on comments in the source file. This means to look for +# branch percentages 10 or 90, 20 or 80, and # 70 or 30: +# /* branch(10, 20, 70) */ +# This means that all specified percentages should have been seen by now: +# /* branch(end) */ +# All specified percentages must also be seen by the next branch(n) or +# by the end of the file. +# +# Each check depends on the compiler having generated the expected +# branch instructions. Don't check for branches that might be +# optimized away or replaced with predicated instructions. +# +proc verify-branches { testname testcase file } { + #send_user "verify-branches\n" + + set failed 0 + set shouldbe "" + set fd [open $file r] + set n 0 + while { [gets $fd line] >= 0 } { + regexp "^\[^:\]+: *(\[0-9\]+):" "$line" all n + if [regexp "branch" $line] { + verbose "Processing branch line $n: $line" 3 + if [regexp "branch\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] { + # All percentages in the current list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected branch percentages not found: $shouldbe" + incr failed + set shouldbe "" + } + set shouldbe $new_shouldbe + #send_user "$n: looking for: $shouldbe\n" + # Record the percentages to check for. Replace percentage + # n > 50 with 100-n, since block ordering affects the + # direction of a branch. + for {set i 0} {$i < [llength $shouldbe]} {incr i} { + set num [lindex $shouldbe $i] + if {$num > 50} { + set shouldbe [lreplace $shouldbe $i $i [expr 100 - $num]] + } + } + } elseif [regexp "branch +\[0-9\]+ taken (-\[0-9\]+)%" "$line" \ + all taken] { + # Percentages should never be negative. + fail "$testname line $n: negative percentage: $taken" + incr failed + } elseif [regexp "branch +\[0-9\]+ taken (\[0-9\]+)%" "$line" \ + all taken] { + #send_user "$n: taken = $taken\n" + # Percentages should never be greater than 100. + if {$taken > 100} { + fail "$testname line $n: branch percentage greater than 100: $taken" + incr failed + } + if {$taken > 50} { + set taken [expr 100 - $taken] + } + # If this percentage is one to check for then remove it + # from the list. It's normal to ignore some reports. + set i [lsearch $shouldbe $taken] + if {$i != -1} { + set shouldbe [lreplace $shouldbe $i $i] + } + } elseif [regexp "branch\\(end\\)" "$line"] { + # All percentages in the list should have been seen by now. + if {[llength $shouldbe] != 0} { + fail "$testname line n: expected branch percentages not found: $shouldbe" + incr failed + } + set shouldbe "" + } + } + } + # All percentages in the list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected branch percentages not found: $shouldbe" + incr failed + } + close $fd + return $failed +} + +# +# verify-calls -- check that call return percentages are as expected +# +# TESTNAME is the name of the test, including unique flags. +# TESTCASE is the name of the test file. +# FILE is the name of the gcov output file. +# +# Checks are based on comments in the source file. This means to look for +# call return percentages 50, 20, 33: +# /* returns(50, 20, 33) */ +# This means that all specified percentages should have been seen by now: +# /* returns(end) */ +# All specified percentages must also be seen by the next returns(n) or +# by the end of the file. +# +# Each check depends on the compiler having generated the expected +# call instructions. Don't check for calls that are inserted by the +# compiler or that might be inlined. +# +proc verify-calls { testname testcase file } { + #send_user "verify-calls\n" + + set failed 0 + set shouldbe "" + set fd [open $file r] + set n 0 + while { [gets $fd line] >= 0 } { + regexp "^\[^:\]+: *(\[0-9\]+):" "$line" all n + if [regexp "return" $line] { + verbose "Processing returns line $n: $line" 3 + if [regexp "returns\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] { + # All percentages in the current list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected return percentages not found: $shouldbe" + incr failed + set shouldbe "" + } + # Record the percentages to check for. + set shouldbe $new_shouldbe + } elseif [regexp "call +\[0-9\]+ returned (-\[0-9\]+)%" "$line" \ + all returns] { + # Percentages should never be negative. + fail "$testname line $n: negative percentage: $returns" + incr failed + } elseif [regexp "call +\[0-9\]+ returned (\[0-9\]+)%" "$line" \ + all returns] { + # For branches we check that percentages are not greater than + # 100 but call return percentages can be, as for setjmp(), so + # don't count that as an error. + # + # If this percentage is one to check for then remove it + # from the list. It's normal to ignore some reports. + set i [lsearch $shouldbe $returns] + if {$i != -1} { + set shouldbe [lreplace $shouldbe $i $i] + } + } elseif [regexp "returns\\(end\\)" "$line"] { + # All percentages in the list should have been seen by now. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected return percentages not found: $shouldbe" + incr failed + } + set shouldbe "" + } + } + } + # All percentages in the list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected return percentages not found: $shouldbe" + incr failed + } + close $fd + return $failed +} + +# Called by dg-final to run gcov and analyze the results. +# +# ARGS consists of the optional strings "branches" and/or "calls", +# (indicating that these things should be verified) followed by a +# list of arguments to provide to gcov, including the name of the +# source file. + +proc run-gcov { args } { + global GCOV + global srcdir subdir + + set gcov_args "" + set gcov_verify_calls 0 + set gcov_verify_branches 0 + set gcov_verify_lines 1 + set gcov_verify_intermediate 0 + set gcov_remove_gcda 0 + set xfailed 0 + + foreach a $args { + if { $a == "calls" } { + set gcov_verify_calls 1 + } elseif { $a == "branches" } { + set gcov_verify_branches 1 + } elseif { $a == "intermediate" } { + set gcov_verify_intermediate 1 + set gcov_verify_calls 0 + set gcov_verify_branches 0 + set gcov_verify_lines 0 + } elseif { $a == "remove-gcda" } { + set gcov_remove_gcda 1 + } elseif { $gcov_args == "" } { + set gcov_args $a + } else { + switch [dg-process-target $a] { + "N" { return } + "F" { set xfailed 1 } + } + } + } + + set testname [testname-for-summary] + + # Extract the test file name from the arguments. + set testcase [lindex $gcov_args end] + + if { $gcov_remove_gcda } { + verbose "Removing $testcase.gcda" + clean-gcov-file $testcase "gcda" + } + + verbose "Running $GCOV $testcase" 2 + set testcase [remote_download host $testcase] + set result [remote_exec host $GCOV $gcov_args] + if { [lindex $result 0] != 0 } { + if { $xfailed } { + setup_xfail "*-*-*" + } + fail "$testname gcov failed: [lindex $result 1]" + clean-gcov $testcase + return + } + + set builtin_index [string first "File ''" $result] + if { $builtin_index != -1 } { + fail "$testname gcov failed: .gcov should not be created" + clean-gcov $testcase + return + } + + # Get the gcov output file after making sure it exists. + set files [glob -nocomplain $testcase.gcov] + if { $files == "" } { + if { $xfailed } { + setup_xfail "*-*-*" + } + fail "$testname gcov failed: $testcase.gcov does not exist" + clean-gcov $testcase + return + } + remote_upload host $testcase.gcov $testcase.gcov + + # Check that line execution counts are as expected. + if { $gcov_verify_lines } { + # Check that line execution counts are as expected. + set lfailed [verify-lines $testname $testcase $testcase.gcov] + } else { + set lfailed 0 + } + + # If requested via the .x file, check that branch and call information + # is correct. + if { $gcov_verify_branches } { + set bfailed [verify-branches $testname $testcase $testcase.gcov] + } else { + set bfailed 0 + } + if { $gcov_verify_calls } { + set cfailed [verify-calls $testname $testcase $testcase.gcov] + } else { + set cfailed 0 + } + if { $gcov_verify_intermediate } { + # Check that intermediate format has the expected format + set ifailed [verify-intermediate $testname $testcase $testcase.gcov] + } else { + set ifailed 0 + } + + # Report whether the gcov test passed or failed. If there were + # multiple failures then the message is a summary. + set tfailed [expr $lfailed + $bfailed + $cfailed + $ifailed] + if { $xfailed } { + setup_xfail "*-*-*" + } + if { $tfailed > 0 } { + fail "$testname gcov: $lfailed failures in line counts, $bfailed in branch percentages, $cfailed in return percentages, $ifailed in intermediate format" + if { $xfailed } { + clean-gcov $testcase + } + } else { + pass "$testname gcov" + clean-gcov $testcase + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..a65b1afd0a6f8d6d24f9c7e3dbac60f97d1be651 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc-dg.exp @@ -0,0 +1,105 @@ +# Copyright (C) 2012-2020 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 +# . + +load_lib gcc-dg.exp + +# Define gdc callbacks for dg.exp. + +proc gdc-dg-test { prog do_what extra_tool_flags } { + upvar dg-do-what dg-do-what + + # Demote link and run tests to compile-only if D runtime is missing. + if ![check_effective_target_d_runtime] { + switch $do_what { + link - + run { + set do_what compile + set dg-do-what compile + } + } + } + + # Strip gdc.test prefix off test names to avoid pathname failures in + # some tests. + set prog [dg-trim-dirname gdc.test $prog] + + set result \ + [gcc-dg-test-1 gdc_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + return [list $comp_output $output_file] +} + +proc gdc-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +# + +proc gdc-dg-runtest { testcases flags default-extra-flags } { + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Use TORTURE_OPTIONS to cycle through an option list. + if [torture-options-exist] then { + global torture_with_loops + set option_list $torture_with_loops + } else { + set option_list { "" } + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } +} + +# +# gdc_load -- wrapper around default gdc_load to handle tests that +# require program arguments passed to them. +# + +if { [info procs gdc_load] != [list] \ + && [info procs prev_gdc_load] == [list] } { + rename gdc_load prev_gdc_load + + proc gdc_load { program args } { + global GDC_EXECUTE_ARGS + if [info exists GDC_EXECUTE_ARGS] then { + set args [concat "{$GDC_EXECUTE_ARGS}"] + } + #print "Running: $program [lindex $args 0]" + set result [eval [list prev_gdc_load $program] $args ] + return $result + } +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc-utils.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc-utils.exp new file mode 100644 index 0000000000000000000000000000000000000000..0e4f57c756d4f0f6c300f0b77a97c461a61f1e8a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc-utils.exp @@ -0,0 +1,499 @@ +# Copyright (C) 2012-2020 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 +# . + +# Test using the DMD testsuite. + +# +# Convert DMD arguments to GDC equivalent +# + +proc gdc-convert-args { args } { + set out "" + + foreach arg [split [lindex $args 0] " "] { + # List of switches kept in ASCII collated order. + if [string match "-D" $arg] { + upvar 1 compilable_output_file_ext compilable_output_file_ext + set compilable_output_file_ext "html" + lappend out "-fdoc" + + } elseif [string match "-H" $arg] { + upvar 1 compilable_output_file_ext compilable_output_file_ext + set compilable_output_file_ext "di" + lappend out "-H" + + } elseif { [regexp -- {^-I([\w+/-]+)} $arg pattern path] } { + lappend out "-I$path" + + } elseif { [regexp -- {^-J([\w+/-]+)} $arg pattern path] } { + lappend out "-J$path" + + } elseif [string match "-X" $arg] { + upvar 1 compilable_output_file_ext compilable_output_file_ext + set compilable_output_file_ext "json" + lappend out "-X" + + } elseif [string match "-allinst" $arg] { + lappend out "-fall-instantiations" + + } elseif [string match "-betterC" $arg] { + lappend out "-fno-druntime" + + } elseif { [string match "-boundscheck" $arg] + || [string match "-boundscheck=on" $arg] } { + lappend out "-fbounds-check" + + } elseif { [string match "-boundscheck=off" $arg] + || [string match "-noboundscheck" $arg] } { + lappend out "-fno-bounds-check" + + } elseif [string match "-boundscheck=safeonly" $arg] { + lappend out "-fbounds-check=safeonly" + + } elseif [string match "-c" $arg] { + lappend out "-c" + + } elseif [string match "-d" $arg] { + lappend out "-Wno-deprecated" + + } elseif [string match "-de" $arg] { + lappend out "-Wdeprecated" + lappend out "-Werror" + + } elseif [string match "-debug" $arg] { + lappend out "-fdebug" + + } elseif [regexp -- {^-debug=(\w+)} $arg pattern value] { + lappend out "-fdebug=$value" + + } elseif [string match "-dip1000" $arg] { + lappend out "-ftransition=dip1000" + + } elseif [string match "-dip25" $arg] { + lappend out "-ftransition=dip25" + + } elseif [string match "-dw" $arg] { + lappend out "-Wdeprecated" + lappend out "-Wno-error" + + } elseif [string match "-fPIC" $arg] { + lappend out "-fPIC" + + } elseif { [string match "-g" $arg] + || [string match "-gc" $arg] } { + lappend out "-g" + + } elseif [string match "-inline" $arg] { + lappend out "-finline-functions" + + } elseif [string match "-main" $arg] { + lappend out "-fmain" + + } elseif [regexp -- {^-mv=([\w+=./-]+)} $arg pattern value] { + lappend out "-fmodule-file=$value" + + } elseif [string match "-O" $arg] { + lappend out "-O2" + + } elseif [string match "-release" $arg] { + lappend out "-frelease" + + } elseif [regexp -- {^-transition=(\w+)} $arg pattern value] { + lappend out "-ftransition=$value" + + } elseif [string match "-unittest" $arg] { + lappend out "-funittest" + + } elseif [string match "-verrors=spec" $arg] { + lappend out "-Wspeculative" + + } elseif [regexp -- {^-verrors=(\d+)} $arg pattern num] { + lappend out "-fmax-errors=$num" + + } elseif [regexp -- {^-version=(\w+)} $arg pattern value] { + lappend out "-fversion=$value" + + } elseif [string match "-vtls" $arg] { + lappend out "-ftransition=tls" + + } elseif [string match "-w" $arg] { + lappend out "-Wall" + lappend out "-Werror" + + } elseif [string match "-wi" $arg] { + lappend out "-Wall" + lappend out "-Wno-error" + + } else { + # print "Unhandled Argument: $arg" + } + } + + return $out +} + +proc gdc-copy-extra { base extra } { + # Split base, folder/file. + set type [file dirname $extra] + + # print "Filename: $base - $extra" + + set fdin [open $base/$extra r] + fconfigure $fdin -encoding binary + + file mkdir $type + set fdout [open $extra w] + fconfigure $fdout -encoding binary + + while { [gets $fdin copy_line] >= 0 } { + set out_line $copy_line + puts $fdout $out_line + } + + close $fdin + close $fdout + + # Remove file once test is finished. + upvar 2 cleanup_extra_files cleanups + lappend cleanups $extra + + return $extra +} + +# +# Translate DMD test directives to dejagnu equivalent. +# +# COMPILE_SEPARATELY: Not handled. +# EXECUTE_ARGS: Parameters to add to the execution of the test. +# COMPILED_IMPORTS: List of modules files that are imported by the main +# source file that should be included in compilation. +# Currently handled the same as EXTRA_SOURCES. +# DFLAGS: Overrides the DFLAGS environment variable if specified +# in the test. No values are permitted; an error will be +# emitted if the value is not empty. +# EXTRA_SOURCES: List of extra sources to build and link along with +# the test. +# EXTRA_CPP_SOURCES: List of extra C++ files to build and link along with +# the test. +# EXTRA_FILES: List of extra files to copy for the test runs. +# PERMUTE_ARGS: The set of arguments to permute in multiple compiler +# invocations. An empty set means only one permutation +# with no arguments. +# TEST_OUTPUT: The output expected from the compilation. +# POST_SCRIPT: Not handled. +# REQUIRED_ARGS: Arguments to add to the compiler command line. +# DISABLED: Not handled. +# + +proc gdc-convert-test { base test } { + global DEFAULT_DFLAGS + global PERMUTE_ARGS + global GDC_EXECUTE_ARGS + + set PERMUTE_ARGS $DEFAULT_DFLAGS + set GDC_EXECUTE_ARGS "" + + set extra_sources "" + set extra_files "" + set needs_phobos 0 + + upvar 1 compilable_do_what compilable_do_what + set compilable_output_file_ext "" + + # Split base, folder/file. + set type [file dirname $test] + set name [file tail $test] + + # print "Filename: $base - $test" + + set fdin [open $base/$test r] + #fconfigure $fdin -encoding binary + + file mkdir $type + set fdout [open $test w] + #fconfigure $fdout -encoding binary + + while { [gets $fdin copy_line] >= 0 } { + set out_line $copy_line + + if [regexp -- {COMPILE_SEPARATELY} $copy_line] { + # COMPILE_SEPARATELY is not handled. + regsub -- {COMPILE_SEPARATELY.*$} $copy_line "" out_line + + } elseif [regexp -- {DISABLED} $copy_line] { + # DISABLED is not handled. + regsub -- {DISABLED.*$} $copy_line "" out_line + + } elseif [regexp -- {POST_SCRIPT} $copy_line] { + # POST_SCRIPT is not handled + regsub -- {POST_SCRIPT.*$} $copy_line "" out_line + + } elseif [regexp -- {DFLAGS\s*:\s*(.*)} $copy_line match args] { + # DFLAGS overrides the default value of PERMUTE_ARGS. + if { $args != "" } { + error "gdc-convert-test: DFLAGS is not empty as expected" + } + if { $PERMUTE_ARGS == $DEFAULT_DFLAGS } { + set PERMUTE_ARGS "" + } + regsub -- {DFLAGS.*$} $copy_line "" out_line + + } elseif [regexp -- {PERMUTE_ARGS\s*:\s*(.*)} $copy_line match args] { + # PERMUTE_ARGS is handled by gdc-do-test. + set PERMUTE_ARGS [gdc-convert-args $args] + regsub -- {PERMUTE_ARGS.*$} $copy_line "" out_line + + } elseif [regexp -- {EXECUTE_ARGS\s*:\s*(.*)} $copy_line match args] { + # EXECUTE_ARGS is handled by gdc_load. + foreach arg $args { + lappend GDC_EXECUTE_ARGS $arg + } + regsub -- {EXECUTE_ARGS.*$} $copy_line "" out_line + + } elseif [regexp -- {REQUIRED_ARGS\s*:\s*(.*)} $copy_line match args] { + # Convert all listed arguments to from dmd to gdc-style. + set new_option "{ dg-additional-options \"[gdc-convert-args $args]\" }" + regsub -- {REQUIRED_ARGS.*$} $copy_line $new_option out_line + + } elseif [regexp -- {EXTRA_SOURCES\s*:\s*(.*)} $copy_line match sources] { + # EXTRA_SOURCES are appended to extra_sources list + foreach srcfile $sources { + lappend extra_sources $srcfile + } + regsub -- {EXTRA_SOURCES.*$} $copy_line "" out_line + + } elseif [regexp -- {EXTRA_CPP_SOURCES\s*:\s*(.*)} $copy_line match sources] { + # EXTRA_CPP_SOURCES are appended to extra_sources list + foreach srcfile $sources { + # C++ sources are found in the extra-files directory. + lappend extra_sources "extra-files/$srcfile" + } + regsub -- {EXTRA_CPP_SOURCES.*$} $copy_line "" out_line + + } elseif [regexp -- {EXTRA_FILES\s*:\s*(.*)} $copy_line match files] { + # EXTRA_FILES are appended to extra_files list + foreach file $files { + lappend extra_files $file + } + regsub -- {EXTRA_FILES.*$} $copy_line "" out_line + + } elseif [regexp -- {COMPILED_IMPORTS\s*:\s*(.*)} $copy_line match sources] { + # COMPILED_IMPORTS are appended to extra_sources list + foreach import $sources { + lappend extra_sources $import + } + regsub -- {COMPILED_IMPORTS.*$} $copy_line "" out_line + + } elseif [regexp -- {RUNNABLE_PHOBOS_TEST} $copy_line match sources] { + # RUNNABLE_PHOBOS_TEST annotates tests that import the std module. + # It will need skipping if phobos is not available on the target. + regsub -- {RUNNABLE_PHOBOS_TEST.*$} $copy_line "" out_line + set needs_phobos 1 + + } elseif [regexp -- {COMPILABLE_MATH_TEST} $copy_line match sources] { + # COMPILABLE_MATH_TEST annotates tests that import the std.math + # module. Which will need skipping if not available on the target. + regsub -- {RUNNABLE_PHOBOS_TEST.*$} $copy_line "" out_line + set needs_phobos 1 + } + + puts $fdout $out_line + } + + # Now that all extra sources and files have been collected, copy them all + # to the testsuite build directory. + if { [llength $extra_sources] > 0 } { + foreach srcfile $extra_sources { + gdc-copy-extra $base "$type/$srcfile" + } + puts $fdout "// { dg-additional-sources \"$extra_sources\" }" + } + + if { [llength $extra_files] > 0 } { + foreach file $extra_files { + gdc-copy-extra $base "$type/$file" + } + puts $fdout "// { dg-additional-files \"$extra_files\" }" + } + + # Add specific options for test type + + # DMD's testsuite is extremely verbose, compiler messages from constructs + # such as pragma(msg, ...) would otherwise cause tests to fail. + puts $fdout "// { dg-prune-output .* }" + + # Compilable files are successful if an output is generated. + # Fail compilable are successful if an output is not generated. + # Runnable must compile, link, and return 0 to be successful by default. + switch $type { + runnable { + if ![isnative] { + puts $fdout "// { dg-final { output-exists } }" + } + if $needs_phobos { + puts $fdout "// { dg-skip-if \"imports phobos\" { ! d_runtime_has_std_library } }" + } + } + + compilable { + puts $fdout "// { dg-final { output-exists } }" + + # Compilable test may require checking another kind of output file. + if { $compilable_output_file_ext != "" } { + set compilable_do_what "compile" + # Check that file generation tests output the expected file. + set genfile "[file rootname $name].$compilable_output_file_ext" + puts $fdout "// { dg-final { if \[file exists $genfile\] \\{ } }" + puts $fdout "// { dg-final { pass \"$test (file exists $genfile)\" } }" + puts $fdout "// { dg-final { \\} else \\{ } }" + puts $fdout "// { dg-final { fail \"$test (file exists $genfile)\" } }" + puts $fdout "// { dg-final { \\} } }" + # Cleanup extra generated files. + puts $fdout "// { dg-final { file delete $genfile } }" + } + if $needs_phobos { + puts $fdout "// { dg-skip-if \"imports phobos\" { ! d_runtime_has_std_library } }" + } + } + + fail_compilation { + puts $fdout "// { dg-final { output-exists-not } }" + } + } + + close $fdin + close $fdout + + return $test +} + +proc gdc-permute-options { options } { + set result { } + set n [expr 1<<[llength $options]] + for { set i 0 } { $i<$n } { incr i } { + set option "" + for { set j 0 } { $j<[llength $options] } { incr j } { + if [expr $i & 1 << $j] { + append option [lindex $options $j] + append option " " + } + } + lappend result $option + + } + return $result +} + +# +# Main loop for running all tests for the subdirectory in gdc.test +# + +proc gdc-do-test { testcases } { + global dg-do-what-default + global subdir + global verbose + + # If a testcase doesn't have special options, use these. + global DEFAULT_DFLAGS + if ![info exists DEFAULT_DFLAGS] then { + set DEFAULT_DFLAGS "-g -O2 -frelease" + #set DEFAULT_DFLAGS "-O2" + } + + # These are special options to use on testcase, and override DEFAULT_DFLAGS + global PERMUTE_ARGS + + # Set if an extra option should be passed to link to shared druntime. + global SHARED_OPTION + + # Additional arguments for gdc_load + global GDC_EXECUTE_ARGS + + # Allow blank linkes in output for all of gdc.test. + global allow_blank_lines + set save_allow_blank_lines $allow_blank_lines + if { !$allow_blank_lines } { + set allow_blank_lines 2 + } + + set saved-dg-do-what-default ${dg-do-what-default} + + # Create gdc.test link so test names include that subdir. + set testdir [file dirname $subdir] + catch { file link $testdir . } + + # Main loop. + + # set verbose 1 + # set dg-final-code "" + # Find all tests and pass to routine. + foreach test $testcases { + regexp -- "(.*)/(.+)/(.+)\.(.+)$" $test match base type name ext + + # Convert to DG test. + set imports [format "-I%s/%s" $base $type] + set cleanup_extra_files "" + set compilable_do_what "assemble" + # Include $testdir prefix so test names follow DejaGnu conventions. + set filename "$testdir/[gdc-convert-test $base $type/$name.$ext]" + + if { $type == "runnable" } { + append PERMUTE_ARGS " $SHARED_OPTION" + } + + set options [gdc-permute-options [lsort -unique $PERMUTE_ARGS]] + + switch $type { + runnable_cxx - + runnable { + for { set i 0 } { $i<[llength $options] } { incr i } { + set flags [lindex $options $i] + if [isnative] { + set dg-do-what-default "run" + } else { + set dg-do-what-default "link" + } + gdc-dg-runtest $filename $flags $imports + } + } + + compilable { + for { set i 0 } { $i<[llength $options] } { incr i } { + set flags [lindex $options $i] + set dg-do-what-default $compilable_do_what + gdc-dg-runtest $filename $flags $imports + } + } + + fail_compilation { + for { set i 0 } { $i<[llength $options] } { incr i } { + set flags [lindex $options $i] + set dg-do-what-default "assemble" + gdc-dg-runtest $filename $flags $imports + } + } + } + + # Cleanup test directory. + foreach srcfile $cleanup_extra_files { + file delete $srcfile + } + file delete $filename + } + + set dg-do-what-default ${saved-dg-do-what-default} + set allow_blank_lines $save_allow_blank_lines +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc.exp new file mode 100644 index 0000000000000000000000000000000000000000..3912d9c1e2196d839c1f5c7279fb3f2a06a90dbf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gdc.exp @@ -0,0 +1,298 @@ +# Copyright (C) 2012-2020 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 +# . + +# +# gdc support library routines +# + +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# GDC_UNDER_TEST is the compiler under test. +# + +set gdc_compile_options "" + + +# +# gdc_version -- extract and print the version number of the compiler +# + +proc gdc_version { } { + global GDC_UNDER_TEST + + gdc_init + + # ignore any arguments after the command + set compiler [lindex $GDC_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gdc_include_flags -- include flags for the gcc tree structure +# + +proc gdc_include_flags { paths } { + global srcdir + global GDC_INCLUDE_CXX_FLAGS + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + if [info exists GDC_INCLUDE_CXX_FLAGS] { + set include_cxx_flags $GDC_INCLUDE_CXX_FLAGS + } else { + set include_cxx_flags 0 + } + + set gccpath ${paths} + + if { $gccpath != "" } { + if [file exists "${gccpath}/libphobos/libdruntime"] { + append flags "-I${gccpath}/libphobos/libdruntime " + } + } + append flags "-I${srcdir}/../../libphobos/libdruntime " + append flags "-I${srcdir}/../../libphobos/src " + + # For the tests that mix C++ and D, need to know where headers are located. + if $include_cxx_flags { + set odir [lookfor_file ${gccpath} libstdc++-v3] + if { ${odir} != "" && [file exists ${odir}/scripts/testsuite_flags] } { + set cxxflags [exec sh ${odir}/scripts/testsuite_flags --build-includes] + set idx [lsearch $cxxflags "-nostdinc++"] + append flags [lreplace $cxxflags $idx $idx] + } + } + + return "$flags" +} + +# +# gdc_link_flags -- linker flags for the gcc tree structure +# + +proc gdc_link_flags { paths } { + global srcdir + global ld_library_path + global GDC_UNDER_TEST + global GDC_INCLUDE_CXX_FLAGS + global shlib_ext + global SHARED_OPTION + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + set SHARED_OPTION "" + verbose "shared lib extension: $shlib_ext" + + if [info exists GDC_INCLUDE_CXX_FLAGS] { + set include_cxx_flags $GDC_INCLUDE_CXX_FLAGS + } else { + set include_cxx_flags 0 + } + + if { $gccpath != "" } { + # Path to libgphobos.spec. + append flags "-B${gccpath}/libphobos/src " + # Path to drtbegin.o/drtend.o. + if { [file exists "${gccpath}/libphobos/libdruntime/gcc/drtbegin.o"] } { + append flags "-B${gccpath}/libphobos/libdruntime/gcc " + } + + if { [file exists "${gccpath}/libphobos/src/.libs/libgphobos.a"] \ + || [file exists "${gccpath}/libphobos/src/.libs/libgphobos.${shlib_ext}"] } { + append flags "-L${gccpath}/libphobos/src/.libs " + append ld_library_path ":${gccpath}/libphobos/src/.libs" + } + # Static linking is default. If only the shared lib is available adjust + # flags to always use it. If both are available, set SHARED_OPTION which + # will be added to PERMUTE_ARGS + if { [file exists "${gccpath}/libphobos/src/.libs/libgphobos.${shlib_ext}"] } { + if { [file exists "${gccpath}/libphobos/src/.libs/libgphobos.a"] } { + set SHARED_OPTION "-shared-libphobos" + } else { + append flags "-shared-libphobos " + } + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + # For the tests that mix C++ and D, need to know where library is located. + if $include_cxx_flags { + if { [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] \ + || [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] } { + append flags "-L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + } + append ld_library_path [gcc-set-multilib-library-path $GDC_UNDER_TEST] + } else { + global tool_root_dir + + set libphobos [lookfor_file ${tool_root_dir} libgphobos] + if { $libphobos != "" } { + append flags "-B${libphobos} -L${libphobos} " + append ld_library_path ":${libphobos}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty] + if { $libiberty != "" } { + append flags "-L${libiberty} " + } + if $include_cxx_flags { + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++] + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} " + append ld_library_path ":${libstdcpp}" + } + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# gdc_init -- called at the start of each subdir of tests +# + +proc gdc_init { args } { + global gdc_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global TOOL_EXECUTABLE + global GDC_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + if ![info exists GDC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GDC_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GDC_UNDER_TEST [transform gdc] + } else { + set GDC_UNDER_TEST [findfile $base_dir/../../gdc "$base_dir/../../gdc -B$base_dir/../../" [findfile $base_dir/gdc "$base_dir/gdc -B$base_dir/" [transform gdc]]] + } + } + } + + if ![is_remote host] { + if { [which $GDC_UNDER_TEST] == 0 } then { + perror "GDC_UNDER_TEST ($GDC_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + gdc_maybe_build_wrapper "${tmpdir}/d-testglue.o" + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + verbose "gdc is initialized" 3 +} + +# +# gdc_target_compile -- compile a source file +# + +proc gdc_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global GDC_UNDER_TEST + global TOOL_OPTIONS + global TEST_ALWAYS_FLAGS + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + set always_dflags "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend always_dflags "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend always_dflags "additional_flags=[gdc_include_flags [get_multilibs ${TOOL_OPTIONS}] ]" + lappend always_dflags "ldflags=[gdc_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend always_dflags "additional_flags=[gdc_include_flags [get_multilibs] ]" + lappend always_dflags "ldflags=[gdc_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend always_dflags "additional_flags=$TOOL_OPTIONS" + } + + verbose "always_dflags set to: $always_dflags" + + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GDC_UNDER_TEST" + + set options [concat "$always_dflags" $options] + set options [dg-additional-files-options $options $source] + return [target_compile $source $dest $type $options] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gfortran-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gfortran-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..21388fb6d3f9cb0e9d77d3c516dc0885e090cbea --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gfortran-dg.exp @@ -0,0 +1,231 @@ +# Copyright (C) 2004-2020 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 +# . + +load_lib gcc-dg.exp +load_lib torture-options.exp + +# Define gfortran callbacks for dg.exp. + +proc gfortran-dg-test { prog do_what extra_tool_flags } { + set result \ + [gcc-dg-test-1 gfortran_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + # gcc's default is to print the caret and source code, but + # most test cases implicitly use the flag -fno-diagnostics-show-caret + # to disable caret (and source code) printing. + # + # However, a few test cases override this back to the default by + # explicily supplying "-fdiagnostics-show-caret", so that we can have + # test coverage for caret/source code printing. + # + # gfortran error messages with caret-printing look like this: + # [name]:[locus]: + # + # some code + # 1 + # Error: Some error at (1) + # or + # [name]:[locus]: + # + # some code + # 1 + # [name]:[locus2]: + # + # some other code + # 2 + # Error: Some error at (1) and (2) + # or + # [name]:[locus]: + # + # some code and some more code + # 1 2 + # Error: Some error at (1) and (2) + # + # If this is such a test case, skip the rest of this function, so + # that the test case can explicitly verify the output that it expects. + if {[string first "-fdiagnostics-show-caret" $extra_tool_flags] >= 0} { + return [list $comp_output $output_file] + } + + # Otherwise, caret-printing is disabled. + # gfortran errors with caret-printing disabled look like this: + # [name]:[locus]: Error: Some error + # or + # [name]:[locus]: Error: (1) + # [name]:[locus2]: Error: Some error at (1) and (2) + # + # Where [locus] is either [line] or [line].[column] or + # [line].[column]-[column] . + # + # We collapse these to look like: + # [name]:[line]:[column]: Error: Some error at (1) and (2) + # or + # [name]:[line]:[column]: Error: Some error at (1) and (2) + # [name]:[line2]:[column]: Error: Some error at (1) and (2) + # + # Note that these regexps only make sense in the combinations used below. + # Note also that is imperative that we first deal with the form with + # two loci. + set locus_regexp "(\[^\n\]+:\[0-9\]+)\[\.:\](\[0-9\]+)(-\[0-9\]+)?:\n\n\[^\n\]+\n\[^\n\]+\n" + set diag_regexp "(\[^\n\]+)\n" + + # We proceed in steps: + + # 1. We add first a column number if none exists. + # (Some Fortran diagnostics have the locus after Warning|Error) + set colnum_regexp "(^|\n)(Warning: |Error: )?(\[^:\n\]+:\[0-9\]+):(\[ \n\])" + regsub -all $colnum_regexp $comp_output "\\1\\3:0:\\4\\2" comp_output + verbose "comput_output0:\n$comp_output" + + # 2. We deal with the form with two different locus lines, + set two_loci "(^|\n)$locus_regexp$locus_regexp$diag_regexp" + regsub -all $two_loci $comp_output "\\1\\2:\\3: \\8\n\\5\:\\6: \\8\n" comp_output + verbose "comput_output1:\n$comp_output" + + set locus_prefix "(\[^:\n\]+:\[0-9\]+:\[0-9\]+: )(Warning: |Error: )" + set two_loci2 "(^|\n)$locus_prefix\\(1\\)\n$locus_prefix$diag_regexp" + regsub -all $two_loci2 $comp_output "\\1\\2\\3\\6\n\\4\\5\\6\n" comp_output + verbose "comput_output2:\n$comp_output" + + # 3. then with the form with only one locus line. + set single_locus "(^|\n)$locus_regexp$diag_regexp" + regsub -all $single_locus $comp_output "\\1\\2:\\3: \\5\n" comp_output + verbose "comput_output3:\n$comp_output" + + # 4. Add a line number if none exists + regsub -all "(^|\n)(Warning: |Error: )" $comp_output "\\1:0:0: \\2" comp_output + verbose "comput_output4:\n$comp_output" + return [list $comp_output $output_file] +} + +proc gfortran-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc gfortran-dg-runtest { testcases flags default-extra-flags } { + global runtests + global torture_with_loops + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # look if this is dg-do-run test, in which case + # we cycle through the option list, otherwise we don't + if [expr [search_for $test "dg-do run"]] { + set option_list $torture_with_loops + } else { + set option_list [list { -O } ] + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + list-module-names $test + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + cleanup-modules "" + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} + +proc gfortran-dg-debug-runtest { target_compile trivial opt_opts testcases } { + global srcdir subdir DEBUG_TORTURE_OPTIONS + + if ![info exists DEBUG_TORTURE_OPTIONS] { + set DEBUG_TORTURE_OPTIONS "" + set type_list [list "-gstabs" "-gstabs+" "-gxcoff" "-gxcoff+" "-gdwarf-2" ] + foreach type $type_list { + set comp_output [$target_compile \ + "$srcdir/$subdir/$trivial" "trivial.S" assembly \ + "additional_flags=$type"] + if { [string match "exit status *" $comp_output] } { + continue + } + if { [string match \ + "* target system does not support the * debug format*" \ + $comp_output] + } { + continue + } + remove-build-file "trivial.S" + foreach level {1 "" 3} { + if { ($type == "-gdwarf-2") && ($level != "") } { + lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}" "-g${level}" "$opt" ] + } + } else { + lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}${level}" "$opt" ] + } + } + } + } + } + + verbose -log "Using options $DEBUG_TORTURE_OPTIONS" + + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + list-module-names $test + + foreach flags $DEBUG_TORTURE_OPTIONS { + set doit 1 + # gcc-specific checking removed here + + if { $doit } { + verbose -log "Testing $nshort, $flags" 1 + dg-test $test $flags "" + cleanup-modules "" + } + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gfortran.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gfortran.exp new file mode 100644 index 0000000000000000000000000000000000000000..016d77ca4f8ddd1785d97cc13fdf29f580ffccdc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gfortran.exp @@ -0,0 +1,268 @@ +# Copyright (C) 2003-2020 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 +# . + +# This file is just 'sed -e 's/77/fortran/g' \ +# -e 's/f2c/gfortran' g77.exp > gfortran.exp' +# +# with some minor modifications to make it work. + +# +# gfortran support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp +load_lib target-supports.exp + +# +# GFORTRAN_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" + + +# +# gfortran_version -- extract and print the version number of the compiler +# + +proc gfortran_version { } { + global GFORTRAN_UNDER_TEST + + gfortran_init + + # ignore any arguments after the command + set compiler [lindex $GFORTRAN_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gfortran_link_flags -- provide new version of gfortran_link_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# + +proc gfortran_link_flags { paths } { + global srcdir + global ld_library_path + global GFORTRAN_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/libgfortran/.libs/libgfortran.a"] { + # Some targets use libgfortran.a%s in their specs, so they need a -B option + # for uninstalled testing. + append flags "-B${gccpath}/libgfortran/.libs " + append flags "-L${gccpath}/libgfortran/.libs " + append ld_library_path ":${gccpath}/libgfortran/.libs" + } + if [file exists "${gccpath}/libgfortran/.libs/libgfortran.${shlib_ext}"] { + append flags "-L${gccpath}/libgfortran/.libs " + append ld_library_path ":${gccpath}/libgfortran/.libs" + } + if [file exists "${gccpath}/libgfortran/libgforbegin.a"] { + append flags "-L${gccpath}/libgfortran " + } + if [file exists "${gccpath}/libatomic/.libs/libatomic.${shlib_ext}"] { + append flags "-L${gccpath}/libatomic/.libs " + append ld_library_path ":${gccpath}/libatomic/.libs" + } + if [file exists "${gccpath}/libatomic/libatomic.a"] { + append flags "-L${gccpath}/libatomic " + } + if [file exists "${gccpath}/libquadmath/.libs/libquadmath.a"] { + # Some targets use libquadmath.a%s in their specs, so they need a -B option + # for uninstalled testing. + append flags "-B${gccpath}/libquadmath/.libs " + append flags "-L${gccpath}/libquadmath/.libs " + append ld_library_path ":${gccpath}/libquadmath/.libs" + } + if [file exists "${gccpath}/libquadmath/.libs/libquadmath.${shlib_ext}"] { + append flags "-L${gccpath}/libquadmath/.libs " + append ld_library_path ":${gccpath}/libquadmath/.libs" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + append ld_library_path \ + [gcc-set-multilib-library-path $GFORTRAN_UNDER_TEST ] + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# gfortran_init -- called at the start of each subdir of tests +# + +proc gfortran_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global objdir srcdir + global ALWAYS_GFORTRANFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GFORTRAN_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + global TEST_ALWAYS_FLAGS + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + set gcc_warning_prefix "\[Ww\]arning:" + set gcc_error_prefix "(Fatal )?\[Ee\]rror:" + + # Many hosts now default to a non-ASCII C locale, however, so + # they can set a charset encoding here if they need. + if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII + } + + if ![info exists GFORTRAN_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GFORTRAN_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GFORTRAN_UNDER_TEST [transform gfortran] + } else { + if [info exists TOOL_OPTIONS] { + set specpath [get_multilibs ${TOOL_OPTIONS}] + } else { + set specpath [get_multilibs] + } + set GFORTRAN_UNDER_TEST [findfile $base_dir/../../gfortran "$base_dir/../../gfortran -B$base_dir/../../ -B$specpath/libgfortran/" [findfile $base_dir/gfortran "$base_dir/gfortran -B$base_dir/" [transform gfortran]]] + } + } + } + + if ![is_remote host] { + if { [which $GFORTRAN_UNDER_TEST] == 0 } then { + perror "GFORTRAN_UNDER_TEST ($GFORTRAN_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + gfortran_maybe_build_wrapper "${tmpdir}/gfortran-testglue.o" + + set ALWAYS_GFORTRANFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TOOL_OPTIONS" + } + + verbose -log "ALWAYS_GFORTRANFLAGS set to $ALWAYS_GFORTRANFLAGS" + + verbose "gfortran is initialized" 3 +} + +# +# gfortran_target_compile -- compile a source file +# + +proc gfortran_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global ALWAYS_GFORTRANFLAGS + global GFORTRAN_UNDER_TEST + global flags_to_postpone + global board_info + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is + # appended here to multilib_flags as it can be overridden by the latter + # if it was added earlier. After the target_compile, multilib_flags is + # restored to its orignal content. + set tboard [target_info name] + if {[board_info $tboard exists multilib_flags]} { + set orig_multilib_flags "[board_info [target_info name] multilib_flags]" + append board_info($tboard,multilib_flags) " $flags_to_postpone" + } + + lappend options "compiler=$GFORTRAN_UNDER_TEST" + lappend options "timeout=[timeout_value]" + + set options [concat "$ALWAYS_GFORTRANFLAGS" $options] + set options [dg-additional-files-options $options $source] + set return_val [target_compile $source $dest $type $options] + + if {[board_info $tboard exists multilib_flags]} { + set board_info($tboard,multilib_flags) $orig_multilib_flags + set flags_to_postpone "" + } + + return $return_val +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gnat-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gnat-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..709fc5e62cc9f7139caaaa9850eeb38d4be017d8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gnat-dg.exp @@ -0,0 +1,89 @@ +# Copyright (C) 2006-2020 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 +# . + +load_lib gcc-dg.exp + +# Remove VALUE from LIST_VARIABLE. +proc lremove {list_variable value} { + upvar 1 $list_variable var + set idx [lsearch -exact $var $value] + set var [lreplace $var $idx $idx] +} + +# Define gcc callbacks for dg.exp. + +proc gnat-dg-test { prog do_what extra_tool_flags } { + if { $do_what == "compile" } { + lappend extra_tool_flags "-c" + lappend extra_tool_flags "-u" + } + set result [gcc-dg-test-1 gnat_target_compile $prog $do_what $extra_tool_flags] + + # Remove additional output files apart from $output_file, which may be + # needed by dg-final. + set output_file [lindex $result 1] + set basename [file rootname $output_file] + set clean_result [remote_exec host [find_gnatclean] "-c -q -n $basename"] + if { [lindex $clean_result 0] != -1 } { + set clean_files [lindex $clean_result 1] + # Purge NL from clean_files. + regsub -all "\[\r\n\]+" $clean_files " " clean_files + # Remove ./ so lremove works. + regsub -all "\./" $clean_files "" clean_files + lremove clean_files $output_file + eval remote_file host delete $clean_files + } + + return $result +} + +proc gnat-dg-prune { system text } { + global additional_prunes + + lappend additional_prunes "gnatmake" + lappend additional_prunes "compilation abandoned" + lappend additional_prunes "fatal error: maximum errors reached" + lappend additional_prunes "linker input file" + + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# +# gnat_load -- wrapper around default gnat_load to declare tasking tests +# unsupported on platforms that lack such support +# + +if { [info procs gnat_load] != [list] \ + && [info procs prev_gnat_load] == [list] } { + rename gnat_load prev_gnat_load + + proc gnat_load { program args } { + upvar name testcase + + set result [eval [list prev_gnat_load $program] $args] + set output [lindex $result 1] + if { [regexp "tasking not implemented" $output] } { + return [list "unsupported" $output] + } + return $result + } +} + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gnat.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gnat.exp new file mode 100644 index 0000000000000000000000000000000000000000..3c970504bc78f9410149bef6a3d91b8f913239f2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/gnat.exp @@ -0,0 +1,248 @@ +# Copyright (C) 2006-2020 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 +# . + +# This file was written by James A. Morrison (ja2morri@uwaterloo.ca) +# based on gcc.exp written by Rob Savoye (rob@cygnus.com). + +# This file is loaded by the tool init file (eg: unix.exp). It provides +# default definitions for gnat_start, etc. and other supporting cast members. + +load_lib prune.exp +load_lib gcc-defs.exp +load_lib gcc.exp +load_lib timeout.exp + +# +# GNAT_UNDER_TEST is the compiler under test. +# + +# +# default_gnat_version -- extract and print the version number of the compiler +# + +proc default_gnat_version { } { + global GNAT_UNDER_TEST + + gnat_init + + # ignore any arguments after the command + set compiler [lindex $GNAT_UNDER_TEST 0] + + if ![is_remote host] { + set compiler_name [which $compiler] + } else { + set compiler_name $compiler + } + + # verify that the compiler exists + if { $compiler_name != 0 } then { + set tmp [remote_exec host "$compiler --version"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp "^GNATMAKE (\[^\n\r\]*)" $output verline version + if { $status == 0 && [info exists version] } then { + # test_summary expects "version" as second field. + clone_output "$compiler_name version $version\n" + } else { + clone_output "Couldn't determine version of $compiler_name: $output\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gnat_version -- Call default_gnat_version, so we can override it if needed. +# + +proc gnat_version { } { + default_gnat_version +} + +# +# gnat_init -- called at the start of each .exp script. +# + +set gnat_initialized 0 + +proc gnat_init { args } { + global rootme + global tmpdir + global libdir + global gluefile wrap_flags + global gnat_initialized + global GNAT_UNDER_TEST + global TOOL_EXECUTABLE + global gnat_target_current + + set gnat_target_current "" + + if { $gnat_initialized == 1 } { return } + + if ![info exists GNAT_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GNAT_UNDER_TEST "$TOOL_EXECUTABLE" + } else { + set GNAT_UNDER_TEST "[local_find_gnatmake]" + } + } + + if ![info exists tmpdir] then { + set tmpdir /tmp + } +} + +proc gnat_target_compile { source dest type options } { + global rootme + global tmpdir + global gluefile wrap_flags + global srcdir + global GNAT_UNDER_TEST + global TOOL_OPTIONS + global gnat_target_current + global TEST_ALWAYS_FLAGS + + # dg-require-effective-target tests must be compiled as C. + if [ string match "*.c" $source ] then { + return [gcc_target_compile $source $dest $type $options] + } + + # If we detect a change of target, we need to recompute both + # GNAT_UNDER_TEST and the appropriate RTS. + if { $gnat_target_current!="[current_target_name]" } { + set gnat_target_current "[current_target_name]" + if [info exists TOOL_OPTIONS] { + set rtsdir "[get_multilibs ${TOOL_OPTIONS}]/libada" + } else { + set rtsdir "[get_multilibs]/libada" + } + if [info exists TOOL_EXECUTABLE] { + set GNAT_UNDER_TEST "$TOOL_EXECUTABLE" + } else { + set GNAT_UNDER_TEST "[local_find_gnatmake]" + } + set GNAT_UNDER_TEST "$GNAT_UNDER_TEST --RTS=$rtsdir" + + # gnatlink looks for system.ads itself and has no --RTS option, so + # specify via environment + setenv ADA_INCLUDE_PATH "$rtsdir/adainclude" + setenv ADA_OBJECTS_PATH "$rtsdir/adainclude" + # Always log so compilations can be repeated manually. + verbose -log "ADA_INCLUDE_PATH=$rtsdir/adainclude" + verbose -log "ADA_OBJECTS_PATH=$rtsdir/adainclude" + } + + lappend options "compiler=$GNAT_UNDER_TEST -q -f" + lappend options "timeout=[timeout_value]" + + if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" + } + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options] + } + + # TOOL_OPTIONS must come first, so that it doesn't override testcase + # specific options. + if [info exists TOOL_OPTIONS] { + set options [concat "additional_flags=$TOOL_OPTIONS" $options] + } + + set options [concat "{ada}" $options] + + return [target_compile $source $dest $type $options] +} + +# Prune messages from GNAT that aren't useful. + +proc prune_gnat_output { text } { + #send_user "Before:$text\n" + regsub -all "(^|\n)\[^\n\]*: In (function|method) \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: At top level:\[^\n\]*" $text "" text + + # prune the output from gnatmake. + regsub -all "(^|\n)\[^\n\]*gnatmake: [^\n\]*" $text "" text + + # It would be nice to avoid passing anything to gnat that would cause it to + # issue these messages (since ignoring them seems like a hack on our part), + # but that's too difficult in the general case. For example, sometimes + # you need to use -B to point gnat at crt0.o, but there are some targets + # that don't have crt0.o. + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text + + #send_user "After:$text\n" + + return $text +} + +# find_gnatmake for some version of DejaGnu will hardcode a -I...rts/ada flag +# which prevent multilib from working, so define a new one. + +proc local_find_gnatmake {} { + global tool_root_dir + + if ![is_remote host] { + set file [lookfor_file $tool_root_dir gnatmake] + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/gnatmake] + } + if { $file != "" } { + set root [file dirname $file] + # Need to pass full --GCC, including multilib flags, to gnatlink, + # otherwise gcc from PATH is invoked. + set dest [target_info name] + set gnatlink_gcc "--GCC=$root/xgcc -B$root [board_info $dest multilib_flags]" + # Escape blanks to get them through DejaGnu's exec machinery. + regsub -all {\s} "$gnatlink_gcc" {\\&} gnatlink_gcc + set CC "$file --GCC=$root/xgcc --GNATBIND=$root/gnatbind --GNATLINK=$root/gnatlink -cargs -B$root -largs $gnatlink_gcc -margs"; + } else { + set CC [transform gnatmake] + } + } else { + set CC [transform gnatmake] + } + return $CC +} + +proc find_gnatclean {} { + global tool_root_dir + + if ![is_remote host] { + set file [lookfor_file $tool_root_dir gnatclean] + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/gnatclean] + } + if { $file != "" } { + set gnatclean $file; + } else { + set gnatclean [transform gnatclean] + } + } else { + set gnatclean [transform gnatclean] + } + return $gnatclean +} + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..49b00b6ba17125009470bfc5aa2260cdf24463ca --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go-dg.exp @@ -0,0 +1,65 @@ +# Copyright (C) 2009-2020 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 +# . + +load_lib gcc-dg.exp + +# Define go callbacks for dg.exp. + +proc go-dg-test { prog do_what extra_tool_flags } { + set result \ + [gcc-dg-test-1 go_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + return [list $comp_output $output_file] +} + +proc go-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc go-dg-runtest { testcases flags default-extra-flags } { + global runtests + global TORTURE_OPTIONS + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # look if this is dg-do-run test, in which case + # we cycle through the option list, otherwise we don't + if [expr [search_for $test "dg-do run"]] { + set option_list $TORTURE_OPTIONS + } else { + set option_list [list { -O } ] + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..f9f99c36e3aff07dbfd841832903c6a58f5285fb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go-torture.exp @@ -0,0 +1,382 @@ +# Copyright (C) 2009-2020 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 +# . + +# Please email any bugs, comments, and/or additions to this file to +# the author. + +# This file was written by Ian Lance Taylor based on +# fortran-torture.exp by Steven Bosscher and Rob Savoye. + +load_lib target-supports.exp + +load_lib target-utils.exp + +# The default option list can be overridden by +# TORTURE_OPTIONS="{ { list1 } ... { listN } }" + +if ![info exists TORTURE_OPTIONS] { + set TORTURE_OPTIONS [list \ + { -O0 } { -O1 } { -O2 } \ + { -O2 -fomit-frame-pointer -finline-functions } \ + { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \ + { -O2 -fbounds-check } \ + { -O3 -g } \ + { -Os }] + + if [check_effective_target_lto] { + set TORTURE_OPTIONS \ + [concat $TORTURE_OPTIONS [list {-flto}]] + } +} + +# +# go-torture-compile -- compile a go.go-torture testcase. +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc go-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and get results in comp_output. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [go_target_compile "$src" "$output" object $options] + + # See if we got something bad. + set fatal_signal "*go*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + go_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $output } + return + } + + if [string match "$fatal_signal 11" $comp_output] then { + go_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $output } + return + } + + if [string match "*internal compiler error*" $comp_output] then { + go_fail $testcase "$option (internal compiler error)" + catch { remote_file build delete $output } + return + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*go*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $output } + return + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [go_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + catch { remote_file build delete $output } + return + } + + # remove any leftover LF/CR to make sure any output is legit + regsub -all -- "\[\r\n\]*" $comp_output "" comp_output + + # If any message remains, we fail. + if ![string match "" $comp_output] then { + go_fail $testcase $option + catch { remote_file build delete $output } + return + } + + go_pass $testcase $option + catch { remote_file build delete $output } +} + + +# +# go-torture-execute -- compile and execute a testcase. +# +# SRC is the full pathname of the testcase. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc go-torture-execute { src } { + global output + global srcdir tmpdir + global tool + global compiler_conditional_xfail_data + global TORTURE_OPTIONS + global go_compile_args + global go_execute_args + + # Check for alternate driver. + set additional_flags "" + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Setup the options for the testcase run. + set option_list $TORTURE_OPTIONS + set executable $tmpdir/[file tail [file rootname $src].x] + regsub "(?q)$srcdir/" $src "" testcase + + if { ! [info exists go_compile_args] } { + set go_compile_args "" + } + if { ! [info exists go_execute_args] } { + set go_execute_args "" + } + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + # Walk the list of options and copmile and run the testcase for all + # options that are not explicitly disabled by the .x script (if present). + foreach option $option_list { + + # Torture_{compile,execute}_xfail are set by the .x script. + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # Torture_execute_before_{compile,execute} can be set by the .x script. + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + # FIXME: We should make sure that the modules required by this testcase + # exist. If not, the testcase should XFAIL. + + # Compile the testcase. + catch { remote_file build delete $executable } + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + if { $go_compile_args != "" } { + lappend options "additional_flags=$go_compile_args" + } + set comp_output [go_target_compile "$src" "$executable" executable $options] + + # See if we got something bad. + set fatal_signal "*go*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + go_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $executable } + continue + } + + if [string match "$fatal_signal 11" $comp_output] then { + go_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $executable } + continue + } + + if [string match "*internal compiler error*" $comp_output] then { + go_fail $testcase "$option (internal compiler error)" + catch { remote_file build delete $executable } + continue + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*go*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $executable } + continue + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [go_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + continue + } elseif ![file exists $executable] { + if ![is3way] { + fail "$testcase compilation, $option" + untested "$testcase execution, $option" + continue + } else { + # FIXME: since we can't test for the existence of a remote + # file without short of doing an remote file list, we assume + # that since we got no output, it must have compiled. + pass "$testcase compilation, $option" + } + } else { + pass "$testcase compilation, $option" + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + # Run the testcase, and analyse the output. + set result [go_load "$executable" "$go_execute_args" ""] + set status [lindex $result 0] + set output [lindex $result 1] + + # In order to cooperate nicely with the master Go testsuite, + # if the output contains the string BUG, we treat the test as + # failing. + if [ string match "*BUG*" $output ] { + set status "fail" + } + + if { $status == "pass" } { + catch { remote_file build delete $executable } + } + $status "$testcase execution, $option" + } +} + + +# +# search_for_re -- looks for a string match in a file +# +proc search_for_re { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + set lower [string tolower $cur_line] + if [regexp "$pattern" $lower] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + + +# +# go-torture -- the go-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# +# SRC is the full pathname of the testcase, or just a file name in which +# case we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc go-torture { args } { + global srcdir subdir + global compiler_conditional_xfail_data + global TORTURE_OPTIONS + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # loop through all the options + set option_list $TORTURE_OPTIONS + foreach option $option_list { + + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + go-torture-compile $src "$option $options" + } +} + +# +# add-ieee-options -- add options necessary for 100% ieee conformance. +# +proc add-ieee-options { } { + # Ensure that excess precision does not cause problems. + if { [istarget i?86-*-*] + || [istarget m68k-*-*] } then { + uplevel 1 lappend additional_flags "-ffloat-store" + } + + # Enable full IEEE compliance mode. + if { [istarget alpha*-*-*] + || [istarget sh*-*-*] } then { + uplevel 1 lappend additional_flags "-mieee" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go.exp new file mode 100644 index 0000000000000000000000000000000000000000..4b1a4a51f537e2a4908ca538ff317ff554542e46 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/go.exp @@ -0,0 +1,226 @@ +# Copyright (C) 2009-2020 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 +# . + +# +# go support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# GOC_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" + + +# +# go_version -- extract and print the version number of the compiler +# + +proc go_version { } { + global GOC_UNDER_TEST + + go_init + + # ignore any arguments after the command + set compiler [lindex $GOC_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# go_include_flags -- include flags for the gcc tree structure +# + +proc go_include_flags { paths } { + global srcdir + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set gccpath ${paths} + + if { $gccpath != "" } { + if [file exists "${gccpath}/libgo/os.gox"] { + append flags "-I${gccpath}/libgo " + } + } +} + +# +# go_link_flags -- linker flags for the gcc tree structure +# + +proc go_link_flags { paths } { + global srcdir + global ld_library_path + global GOC_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/libgo/libgobegin.a"] { + append flags "-L${gccpath}/libgo " + } + if { [file exists "${gccpath}/libgo/.libs/libgo.a"] \ + || [file exists "${gccpath}/libgo/.libs/libgo.${shlib_ext}"] } { + append flags "-L${gccpath}/libgo/.libs " + append ld_library_path ":${gccpath}/libgo/.libs" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + append ld_library_path \ + [gcc-set-multilib-library-path $GOC_UNDER_TEST] + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# go_init -- called at the start of each subdir of tests +# + +proc go_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global objdir srcdir + global ALWAYS_GOCFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GOC_UNDER_TEST + global TESTING_IN_BUILD_TREE + global TEST_ALWAYS_FLAGS + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + if ![info exists GOC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GOC_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GOC_UNDER_TEST [transform gccgo] + } else { + set GOC_UNDER_TEST [findfile $base_dir/../../gccgo "$base_dir/../../gccgo -B$base_dir/../../" [findfile $base_dir/gccgo "$base_dir/gccgo -B$base_dir/" [transform gccgo]]] + } + } + } + + if ![is_remote host] { + if { [which $GOC_UNDER_TEST] == 0 } then { + perror "GOC_UNDER_TEST ($GOC_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + go_maybe_build_wrapper "${tmpdir}/go-testglue.o" + + set ALWAYS_GOCFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_GOCFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GOCFLAGS "additional_flags=[go_include_flags [get_multilibs ${TOOL_OPTIONS}] ]" + lappend ALWAYS_GOCFLAGS "ldflags=[go_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend ALWAYS_GOCFLAGS "additional_flags=[go_include_flags [get_multilibs] ]" + lappend ALWAYS_GOCFLAGS "ldflags=[go_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GOCFLAGS "additional_flags=$TOOL_OPTIONS" + } + + verbose -log "ALWAYS_GOCFLAGS set to $ALWAYS_GOCFLAGS" + + verbose "go is initialized" 3 +} + +# +# go_target_compile -- compile a source file +# + +proc go_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global ALWAYS_GOCFLAGS + global GOC_UNDER_TEST + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GOC_UNDER_TEST" + + set options [concat "$ALWAYS_GOCFLAGS" $options] + set options [dg-additional-files-options $options $source] + return [target_compile $source $dest $type $options] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/lto.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/lto.exp new file mode 100644 index 0000000000000000000000000000000000000000..b2fa7ec8cecbb0f96851b78d31e660201174ce68 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/lto.exp @@ -0,0 +1,888 @@ +# Copyright (C) 2009-2020 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 +# . + +# Contributed by Diego Novillo + +# A subroutine of lto_handle_diagnostics: check TEXT for the expected +# diagnostics for one specific source file, issuing PASS/FAIL results. +# Return TEXT, stripped of any diagnostics that were handled. +# +# NAME is the testcase name to use when reporting PASS/FAIL results. +# FILENAME is the name (with full path) of the file we're interested in. +# MESSAGES_FOR_FILE is a list of expected messages, akin to DejaGnu's +# "dg-messages" variable. +# TEXT is the textual output from the LTO link. + +proc lto_handle_diagnostics_for_file { name filename messages_for_file text } { + global dg-linenum-format + + set filename_without_path [file tail $filename] + + # This loop is adapted from the related part of DejaGnu's dg-test, + # with changes as detailed below to cope with the LTO case. + + foreach i ${messages_for_file} { + verbose "Scanning for message: $i" 4 + + # Remove all error messages for the line [lindex $i 0] + # in the source file. If we find any, success! + set line [lindex $i 0] + set pattern [lindex $i 2] + set comment [lindex $i 3] + verbose "line: $line" 4 + verbose "pattern: $pattern" 4 + verbose "comment: $comment" 4 + #send_user "Before:\n$text\n" + + # Unlike dg-test, we use $filename_without_path in this pattern. + # This is to ensure that we have the correct file/line combination. + # This imposes the restriction that the filename can't contain + # any regexp control characters. We have to strip the path, since + # e.g. the '+' in "g++.dg" wouldn't be valid. + set pat "(^|\n)(\[^\n\]+$filename_without_path$line\[^\n\]*($pattern)\[^\n\]*\n?)+" + if {[regsub -all $pat $text "\n" text]} { + set text [string trimleft $text] + set ok pass + set uhoh fail + } else { + set ok fail + set uhoh pass + } + #send_user "After:\n$text\n" + + # $line will either be a formatted line number or a number all by + # itself. Delete the formatting. + scan $line ${dg-linenum-format} line + + # Unlike dg-test, add the filename to the PASS/FAIL message (rather + # than just the line number) so that the user can identify the + # pertinent directive. + set describe_where "$filename_without_path line $line" + + # Issue the PASS/FAIL, adding "LTO" to the messages (e.g. "LTO errors") + # to distinguish them from the non-LTO case (in case we ever need to + # support both). + switch [lindex $i 1] { + "ERROR" { + $ok "$name $comment (test for LTO errors, $describe_where)" + } + "XERROR" { + x$ok "$name $comment (test for LTO errors, $describe_where)" + } + "WARNING" { + $ok "$name $comment (test for LTO warnings, $describe_where)" + } + "XWARNING" { + x$ok "$name $comment (test for LTO warnings, $describe_where)" + } + "BOGUS" { + $uhoh "$name $comment (test for LTO bogus messages, $describe_where)" + } + "XBOGUS" { + x$uhoh "$name $comment (test for LTO bogus messages, $describe_where)" + } + "BUILD" { + $uhoh "$name $comment (test for LTO build failure, $describe_where)" + } + "XBUILD" { + x$uhoh "$name $comment (test for LTO build failure, $describe_where)" + } + "EXEC" { } + "XEXEC" { } + } + } + return $text +} + +# Support for checking for link-time diagnostics: check for +# the expected diagnostics within TEXT, issuing PASS/FAIL results. +# Return TEXT, stripped of any diagnostics that were handled. +# +# TEXT is the textual output from the LTO link. + +proc lto_handle_diagnostics { text } { + global testcase + + upvar dg-messages-by-file messages_by_file + + verbose "lto_handle_diagnostics: entry: $text" 2 + + if { ![array exists messages_by_file] } { + error "lto_handle_diagnostics: messages_by_file not defined" + } + + foreach src [lsort [array names messages_by_file]] { + set dg-messages $messages_by_file($src) + verbose " messages for $src: ${dg-messages}" 3 + set text [lto_handle_diagnostics_for_file $testcase $src \ + ${dg-messages} $text] + } + + verbose "lto_handle_diagnostics: exit: $text" 2 + + return $text +} + +# Prune messages that aren't useful. + +proc lto_prune_warns { text } { + + verbose "lto_prune_warns: entry: $text" 2 + + # Many tests that use visibility will still pass on platforms that don't support it. + regsub -all "(^|\n)\[^\n\]*: warning: visibility attribute not supported in this configuration; ignored\[^\n\]*" $text "" text + + # Allow mixed-language LTO tests to pass with make check-c++0x + regsub -all "(^|\n)\[^\n\]*: warning: command line option '-std=\[^\n\]*" $text "" text + + # And any stray location lines. + regsub -all "(^|\n)\[^\n\]*: In function \[^\n\]*" $text "" text + regsub -all "(^|\n)In file included from \[^\n\]*" $text "" text + regsub -all "(^|\n)\[ \t\]*from \[^\n\]*" $text "" text + + # Sun ld warns about common symbols with differing sizes. Unlike GNU ld + # --warn-common (off by default), they cannot be disabled. + regsub -all "(^|\n)ld: warning: symbol \[`'\]\[^\n\]*' has differing sizes:" $text "" text + regsub -all "(^|\n)\[ \t\]*\[\(\]file \[^\n\]* value=\[^\n\]*; file \[^\n\]* value=\[^\n\]*\[)\];" $text "" text + regsub -all "(^|\n)\[ \t\]*\[^\n\]* definition taken" $text "" text + + # Ignore informational notes. + regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text + + verbose "lto_prune_warns: exit: $text" 2 + + return $text +} + +# lto_init -- called at the start of each subdir of tests + +proc lto_init { args } { + global LTO_OPTIONS + + if {[info exists args] && $args == "no-mathlib"} { + global board_info + global saved_mathlib + + set dest [target_info name] + if [board_info $dest exists mathlib] { + set saved_mathlib [board_info $dest mathlib] + } + set board_info($dest,mathlib) " " + } + + # Each test is run with the compiler options from this list. + # The default option lists can be overridden by LTO_OPTIONS="[list + # {opts_1} {opts_2}... {opts_n}]" where opts_i are lists of options. + # You can put this in the environment before site.exp is written or + # add it to site.exp directly. + if ![info exists LTO_OPTIONS] { + if [check_linker_plugin_available] { + set LTO_OPTIONS [list \ + {-O0 -flto -flto-partition=none -fuse-linker-plugin} \ + {-O2 -flto -flto-partition=none -fuse-linker-plugin -fno-fat-lto-objects } \ + {-O0 -flto -flto-partition=1to1 -fno-use-linker-plugin } \ + {-O2 -flto -flto-partition=1to1 -fno-use-linker-plugin } \ + {-O0 -flto -fuse-linker-plugin -fno-fat-lto-objects } \ + {-O2 -flto -fuse-linker-plugin} \ + ] + } else { + set LTO_OPTIONS [list \ + {-O0 -flto -flto-partition=none } \ + {-O2 -flto -flto-partition=none } \ + {-O0 -flto -flto-partition=1to1 } \ + {-O2 -flto -flto-partition=1to1 } \ + {-O0 -flto } \ + {-O2 -flto} \ + ] + } + } +} + +# +# lto_finish -- called at the end of each subdir of tests if mathlib is +# changed. +# + +proc lto_finish { } { + global board_info + global saved_mathlib + + set dest [target_info name] + if [info exists saved_mathlib] { + set board_info($dest,mathlib) $saved_mathlib + } elseif [board_info $dest exists mathlib] { + unset board_info($dest,mathlib) + } +} + +# Subsets of tests can be selectively disabled by members of this list: +# - ATTRIBUTE: disable all tests using the __attribute__ extension, +# - COMPLEX: disable all tests using the complex types feature, +# - COMPLEX_INT: disable all tests using the complex integral types extension, +# - VA: disable all tests using the variable number of arguments feature, +# - VLA_IN_STRUCT: disable all tests using the variable-length arrays as +# structure members extension, +# - ZERO_ARRAY: disable all tests using the zero-sized arrays extension. +# The default skip lists can be overriden by +# LTO_SKIPS="[list {skip_1}...{skip_n}]" +# where skip_i are skip identifiers. You can put this in the environment +# before site.exp is written or add it to site.exp directly. +if ![info exists LTO_SKIPS] { + set LTO_SKIPS [list {}] +} + +global lto_skip_list +set lto_skip_list $LTO_SKIPS + +load_lib dg.exp +load_lib gcc-dg.exp +load_lib gcc.exp + +# lto-obj -- compile to an object file +# +# SOURCE is the source file +# DEST is the object file +# OPTALL is the list of compiler options to use with all tests +# OPTFILE is the list of compiler options to use with this file +# OPTSTR is the options to print with test messages +# XFAILDATA is the xfail data to be passed to the compiler +proc lto-obj { source dest optall optfile optstr xfaildata } { + global testcase + global tool + global compiler_conditional_xfail_data + global lto_skip_list + + # Add the skip specifiers. + foreach skip $lto_skip_list { + if { ![string match $skip ""] } { + lappend optall "-DSKIP_$skip" + } + } + + # Set up the options for compiling this file. + set options "" + lappend options "additional_flags=$optall $optfile" + + set compiler_conditional_xfail_data $xfaildata + + # Allow C source files to mix freely with other languages + if [ string match "*.c" $source ] then { + set comp_output [gcc_target_compile "$source" "$dest" object $options] + } else { + set comp_output [${tool}_target_compile "$source" "$dest" object $options] + } + # Prune unimportant visibility warnings before checking output. + set comp_output [lto_prune_warns $comp_output] + ${tool}_check_compile "$testcase $dest assemble" $optstr $dest $comp_output +} + +# lto-link-and-maybe-run -- link the object files and run the executable +# if compile_type is set to "run" +# +# TESTNAME is the mixture of object files to link +# OBJLIST is the list of object files to link +# DEST is the name of the executable +# OPTALL is a list of compiler and linker options to use for all tests +# OPTFILE is a list of compiler and linker options to use for this test +# OPTSTR is the list of options to list in messages +proc lto-link-and-maybe-run { testname objlist dest optall optfile optstr } { + global testcase + global tool + global compile_type + global board_info + + upvar dg-messages-by-file dg-messages-by-file + + verbose "lto-link-and-maybe-run" 2 + + # Check that all of the objects were built successfully. + foreach obj [split $objlist] { + if ![file_on_host exists $obj] then { + unresolved "$testcase $testname link $optstr" + unresolved "$testcase $testname execute $optstr" + return + } + } + + # Set up the options for linking this test. + set options "" + lappend options "additional_flags=$optall $optfile" + + set target_board [target_info name] + set relocatable 0 + + # Some LTO tests do relocatable linking. Some target boards set + # a linker script which can't be used for relocatable linking. + # Use the default linker script instead. + if { [lsearch -exact [split "$optall $optfile"] "-r"] >= 0 } { + set relocatable 1 + } + + if { $relocatable } { + set saved_ldscript [board_info $target_board ldscript] + set board_info($target_board,ldscript) "" + } + + # Link the objects into an executable. + set comp_output [${tool}_target_compile "$objlist" $dest executable \ + "$options"] + + if { $relocatable } { + set board_info($target_board,ldscript) $saved_ldscript + } + + # Check for diagnostics specified by directives + set comp_output [lto_handle_diagnostics $comp_output] + + # Prune unimportant visibility warnings before checking output. + set comp_output [lto_prune_warns $comp_output] + + if ![${tool}_check_compile "$testcase $testname link" $optstr \ + $dest $comp_output] then { + if { ![string compare "execute" $compile_type] } { + unresolved "$testcase $testname execute $optstr" + } + return + } + + # Return if we only needed to link. + if { ![string compare "link" $compile_type] } { + return + } + + # Run the self-checking executable. + if ![string match "*/*" $dest] then { + set dest "./$dest" + } + set result [${tool}_load $dest "" ""] + set status [lindex $result 0] + if { $status == "pass" } then { + file_on_host delete $dest + } + $status "$testcase $testname execute $optstr" +} + +# Potentially handle the given dg- directive (a list) +# Return true is the directive was handled, false otherwise. + +proc lto-can-handle-directive { op } { + set cmd [lindex $op 0] + + # dg-warning and dg-message append to dg-messages. + upvar dg-messages dg-messages + + # A list of directives to recognize, and a list of directives + # to remap them to. + # For example, "dg-lto-warning" is implemented by calling "dg-warning". + set directives { dg-lto-warning dg-lto-message } + set remapped_directives { dg-warning dg-message } + + set idx [lsearch -exact $directives $cmd] + if { $idx != -1 } { + verbose "remapping from: $op" 4 + + set remapped_cmd [lindex $remapped_directives $idx] + set op [lreplace $op 0 0 $remapped_cmd] + + verbose "remapped to: $op" 4 + + set status [catch "$op" errmsg] + if { $status != 0 } { + if { 0 && [info exists errorInfo] } { + # This also prints a backtrace which will just confuse + # testcase writers, so it's disabled. + perror "$name: $errorInfo\n" + } else { + perror "$name: $errmsg for \"$op\"\n" + } + # ??? The call to unresolved here is necessary to clear `errcnt'. + # What we really need is a proc like perror that doesn't set errcnt. + # It should also set exit_status to 1. + unresolved "$name: $errmsg for \"$op\"" + } + + return true + } + + return false +} + +# lto-get-options-main -- get target requirements for a test and +# options for the primary source file and the test as a whole +# +# SRC is the full pathname of the primary source file. +proc lto-get-options-main { src } { + global compile_type + global dg-extra-ld-options + global dg-suppress-ld-options + + set dg-extra-ld-options "" + set dg-suppress-ld-options "" + + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-options sets a variable called tool_flags. + set tool_flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + upvar dg-final-code dg-final-code + set dg-final-code "" + + # dg-warning and dg-message append to dg-messages. + upvar dg-messages-by-file dg-messages-by-file + set dg-messages "" + + set tmp [dg-get-options $src] + verbose "getting options for $src: $tmp" + foreach op $tmp { + set cmd [lindex $op 0] + verbose "cmd is $cmd" + if { [string match "dg-skip-if" $cmd] \ + || [string match "dg-require-*" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { [string match "dg-lto-options" $cmd] } { + set op [lreplace $op 0 0 "dg-options"] + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { ![string compare "dg-xfail-if" $cmd] \ + || ![string compare "dg-options" $cmd] } { + warning "lto.exp does not support $cmd in primary source file" + } elseif { ![string compare "dg-lto-do" $cmd] } { + if { [llength $op] > 3 } { + set kw [lindex [lindex $op 3] 0] + if [string match "target" $kw] { + perror "$src: dg-lto-do does not support \"target\"" + } elseif [string match "xfail" $kw] { + perror "$src: dg-lto-do does not support \"xfail\"" + } else { + perror "$src: dg-lto-do takes a single argument" + } + } + set dgdo [lindex $op 2] + verbose "dg-lto-do command for \"$op\" is $dgdo" + if { ![string compare "assemble" $dgdo] } { + set compile_type "assemble" + } elseif { ![string compare "run" $dgdo] } { + set compile_type "run" + } elseif { ![string compare "link" $dgdo] } { + set compile_type "link" + } else { + warning "lto.exp does not support dg-lto-do $dgdo" + } + } elseif { ![string compare "dg-extra-ld-options" $cmd] } { + if { [llength $op] > 4 } { + error "[lindex $op 0]: too many arguments" + } else { + if { [llength $op] == 3 + || ([llength $op] > 3 + && [dg-process-target [lindex $op 3]] == "S") } { + set dg-extra-ld-options [lindex $op 2] + verbose \ + "dg-extra-ld-options for main is ${dg-extra-ld-options}" + } + } + } elseif { ![string compare "dg-suppress-ld-options" $cmd] } { + if { [llength $op] > 4 } { + error "[lindex $op 0]: too many arguments" + } else { + if { [llength $op] == 3 + || ([llength $op] > 3 + && [dg-process-target [lindex $op 3]] == "S") } { + set dg-suppress-ld-options [lindex $op 2] + verbose \ + "dg-suppress-ld-options for main is ${dg-suppress-ld-options}" + } + } + } elseif { ![string compare "dg-final" $cmd] } { + if { [llength $op] > 3 } { + error "[lindex $op 0]: too many arguments" + } else { + append dg-final-code "[lindex $op 2]\n" + } + } elseif { ![lto-can-handle-directive $op] } { + # Ignore unrecognized dg- commands, but warn about them. + warning "lto.exp does not support $cmd" + } + } + + verbose "dg-messages: ${dg-messages}" 3 + set dg-messages-by-file($src) ${dg-messages} + + # Return flags to use for compiling the primary source file and for + # linking. + verbose "dg-extra-tool-flags for main is ${dg-extra-tool-flags}" + return ${dg-extra-tool-flags} +} + + +# lto-get-options -- get special tool flags to use for a secondary +# source file +# +# SRC is the full pathname of the source file. +# The result is a list of options to use. +# +# This code is copied from proc dg-test in dg.exp from DejaGNU. +proc lto-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-xfail-if sets compiler_conditional_xfail_data. + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data "" + + # dg-xfail-if needs access to dg-do-what. + upvar dg-do-what dg-do-what + + # dg-warning appends to dg-messages. + upvar dg-messages-by-file dg-messages-by-file + set dg-messages "" + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || ![string compare "dg-xfail-if" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { [string match "dg-require-*" $cmd] } { + warning "lto.exp does not support $cmd in secondary source files" + } elseif { ![lto-can-handle-directive $op] } { + # Ignore unrecognized dg- commands, but warn about them. + warning "lto.exp does not support $cmd in secondary source files" + } + } + + verbose "dg-messages: ${dg-messages}" 3 + if { [info exists dg-messages-by-file($src)] } { + append dg-messages-by-file($src) ${dg-messages} + } else { + set dg-messages-by-file($src) ${dg-messages} + } + + return ${dg-extra-tool-flags} +} + +# lto-execute -- compile multi-file tests +# +# SRC1 is the full pathname of the main file of the testcase. +# SID identifies a test suite in the names of temporary files. +proc lto-execute { src1 sid } { + global srcdir tmpdir + global lto_option_list + global tool + global verbose + global testcase + global gluefile + global compiler_conditional_xfail_data + global dg-do-what-default + global compile_type + global dg-extra-ld-options + global dg-suppress-ld-options + global LTO_OPTIONS + global dg-final-code + global testname_with_flags + + # Get extra flags for this test from the primary source file, and + # process other dg-* options that this suite supports. Warn about + # unsupported flags. + verbose "lto-execute: $src1" 1 + set compile_type "run" + set dg-do-what [list ${dg-do-what-default} "" P] + array set dg-messages-by-file [list] + set extra_flags(0) [lto-get-options-main $src1] + set compile_xfail(0) "" + + # If the main file defines dg-options, those flags are used to + # overwrite the default lto_option_list taken from LTO_OPTIONS. + if { [string length $extra_flags(0)] > 0 } { + set lto_option_list $extra_flags(0) + set extra_flags(0) "" + } else { + set lto_option_list $LTO_OPTIONS + } + + # Set up the names of the other source files. + set dir [file dirname $src1] + set base [file rootname $src1] + set base [string range $base [string length $dir] end] + regsub "_0" $base "" base + regsub "/" $base "" base + set src_list $src1 + set i 1 + set done 0 + while { !$done } { + set names [glob -nocomplain -types f -- "${dir}/${base}_${i}.*"] + if { [llength ${names}] > 1 } { + warning "lto-execute: more than one file matched ${dir}/${base}_${i}.*" + } + if { [llength ${names}] == 1 } { + lappend src_list [lindex ${names} 0] + incr i + } else { + set num_srcs ${i} + set done 1 + } + } + + # Use the dg-options mechanism to specify extra flags for each + # of the secondary files. + # The extra flags in each file are used to compile that file, and the + # extra flags in *_0.* are also used for linking. + verbose "\tsrc_list is: $src_list" + for {set i 1} {$i < $num_srcs} {incr i} { + set extra_flags($i) [lto-get-options [lindex $src_list $i]] + set compile_xfail($i) $compiler_conditional_xfail_data + } + + # Define the names of the object files. + set obj_list "" + for {set i 0} {$i < $num_srcs} {incr i} { + lappend obj_list "${sid}_${base}_${i}.o" + } + + # Get the base name of this test, for use in messages. + set testcase [lindex ${src_list} 0] + + # Remove the $srcdir and $tmpdir prefixes from $src1. (It would + # be possible to use "regsub" here, if we were careful to escape + # all regular expression characters in $srcdir and $tmpdir, but + # that would be more complicated that this approach.) + if {[string first "$srcdir/" "${testcase}"] == 0} { + set testcase [string range "${testcase}" [string length "$srcdir/"] end] + } + if {[string first "$tmpdir/" "$testcase"] == 0} { + set testcase [string range "$testcase" [string length "$tmpdir/"] end] + set testcase "tmpdir-$testcase" + } + # If we couldn't rip $srcdir out of `src1' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] then { + set testcase "[file tail [file dirname $src1]]/[file tail $src1]" + } + + # Check whether this test is supported for this target. + if { [lindex ${dg-do-what} 1 ] == "N" } { + unsupported "$testcase" + verbose "$testcase not supported on this target, skipping it" 3 + return + } + # Should be safe for non-fortran too but be paranoid.. + if {$sid eq "f_lto"} { + list-module-names $src_list + } + regsub "_0.*" $testcase "" testcase + + # Set up the base name of executable files so they'll be unique. + regsub -all "\[./\]" $testcase "-" execbase + + # Loop through all of the option lists used for this test. + set count 0 + foreach option $lto_option_list { + verbose "Testing $testcase, $option" + + # There's a unique name for each executable we generate. + set execname "${execbase}-${count}1.exe" + + # The LTO tests don't use dg-test, so testname_with_flags and + # output_file need to be defined explicitly for each file. scan-symbol + # directives rely on both of these to be defined to find the symbol to + # scan and for the text to print in the PASS/FAIL since they can also + # be called from dg-test. testname_with_flags is also used via + # testname-for-summary when calling into generic function below to + # clean temporary files. + set output_file $execname + set testname_with_flags $execname + + incr count + + file_on_host delete $execname + + # Compile pieces with the compiler under test. + set i 0 + foreach src $src_list obj $obj_list { + lto-obj $src $obj $option $extra_flags($i) $option \ + $compile_xfail($i) + incr i + } + + # Link (using the compiler under test), run, and clean up tests. + if { ![string compare "run" $compile_type] \ + || ![string compare "link" $compile_type] } { + + # Filter out any link options we were asked to suppress. + set reduced {} + foreach x [split $option] { + if {[lsearch ${dg-suppress-ld-options} $x] == -1} { + lappend reduced $x + } + } + set filtered [join $reduced " "] + + lto-link-and-maybe-run \ + "[lindex $obj_list 0]-[lindex $obj_list end]" \ + $obj_list $execname $filtered ${dg-extra-ld-options} \ + $filtered + } + + + # Are there any further tests to perform? + # Note that if the program has special run-time requirements, running + # of the program can be delayed until here. Ditto for other situations. + # It would be a bit cumbersome though. + + if ![string match ${dg-final-code} ""] { + regsub -all "\\\\(\[{}\])" ${dg-final-code} "\\1" dg-final-code + # Note that the use of `args' here makes this a varargs proc. + proc dg-final-proc { args } ${dg-final-code} + verbose "Running dg-final tests." 3 + verbose "dg-final-proc:\n[info body dg-final-proc]" 4 + if [catch "dg-final-proc $src1" errmsg] { + perror "$src1: error executing dg-final: $errmsg" + # ??? The call to unresolved here is necessary to clear + # `errcnt'. What we really need is a proc like perror that + # doesn't set errcnt. It should also set exit_status to 1. + unresolved "$src1: error executing dg-final: $errmsg" + } + } + + # Clean up object files. + set files [glob -nocomplain ${sid}_*.o] + if { $files != "" } { + foreach objfile $files { + if { ![info exists gluefile] || $objfile != $gluefile } { + eval "file_on_host delete $objfile" + } + } + } + + # Clean up after -save-temps. + eval "cleanup-saved-temps" + + for {set i 0} {$i < $num_srcs} {incr i} { + set testname_with_flags "${base}_${i}" + eval "cleanup-saved-temps" + set testname_with_flags "${sid}_${base}_${i}" + eval "cleanup-saved-temps" + } + + unset testname_with_flags + + if { ![string compare "run" $compile_type] \ + || ![string compare "link" $compile_type] } { + file_on_host delete $execname + } + # Should be safe for non-fortran too but be paranoid.. + if {$sid eq "f_lto"} { + cleanup-modules "" + } + } +} + +# Call pass if object readelf is ok, otherwise fail. +# example: /* { dg-final { object-readelf Tag_ABI_enum_size int} } */ +proc object-readelf { args } { + global readelf + global base_dir + upvar 2 execname execname + + if { [llength $args] < 2 } { + error "object-readelf: too few arguments" + return + } + if { [llength $args] > 3 } { + error "object-readelf: too many arguments" + return + } + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find size like we find g++ in g++.exp. + if ![info exists readelf] { + set readelf [findfile $base_dir/../../../binutils/readelf \ + $base_dir/../../../binutils/readelf \ + [findfile $base_dir/../../readelf $base_dir/../../readelf \ + [findfile $base_dir/readelf $base_dir/readelf \ + [transform readelf]]]] + verbose -log "readelf is $readelf" + } + + set what [lindex $args 0] + set with [lindex $args 1] + + if ![file_on_host exists $execname] { + verbose -log "$execname does not exist" + unresolved "object-readelf $what " + return + } + + set output [remote_exec host "$readelf -A" "$execname"] + set status [lindex $output 0] + if { $status != 0 } { + verbose -log "object-readelf: $readelf failed" + unresolved "object-readelf $what $execname" + return + } + + set text [lindex $output 1] + set lines [split $text "\n"] + + set done 0 + set i 0 + while { !$done } { + set line_tex [lindex $lines $i] + if { [llength ${line_tex}] > 1} { + incr i + if [regexp -- $what $line_tex] { + set match [regexp -- $with $line_tex] + set done 1 + } + } else { + set done 1 + } + } + + verbose -log "$what size is $with;" + if { $match == 1 } { + pass "object-readelf $what size is correct." + } else { + fail "object-readelf $what size is incorrect." + } +} + + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/mike-g++.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/mike-g++.exp new file mode 100644 index 0000000000000000000000000000000000000000..2903358aab14d3ef6c3eb8b938f774000dd49e5c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/mike-g++.exp @@ -0,0 +1,263 @@ +# Copyright (C) 1988-2020 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 +# . + +# This file was written by Mike Stump + +load_lib target-utils.exp + +# +# mike_cleanup -- remove any files that are created by the testcase +# +proc mike_cleanup { src_code output_file assembly_file } { + remote_file build delete $output_file $assembly_file +} + +# +# prebase -- sets up a Mike Stump (mrs@cygnus.com) style G++ test +# +proc prebase { } { + global compiler_output + global not_compiler_output + global compiler_result + global not_compiler_result + global program_output + global groups + global run + global actions + global target_regexp + + set compiler_output "^$" + set not_compiler_output ".*Internal compiler error.*" + set compiler_result "" + set not_compiler_result "" + set program_output ".*PASS.*" + set groups {} + set run no + set actions assemble + set target_regexp ".*" +} + +# +# run the test +# +proc postbase { src_code run groups args } { + global verbose + global srcdir + global subdir + global not_compiler_output + global compiler_output + global compiler_result + global not_compiler_result + global program_output + global actions + global target_regexp + global host_triplet + global target_triplet + global tool + global tmpdir + global objdir + global base_dir + + if ![regexp $target_regexp $target_triplet] { + unsupported $subdir/$src_code + return + } + + if { [llength $args] > 0 } { + set comp_options [lindex $args 0] + } else { + set comp_options "" + } + + set fail_message $subdir/$src_code + set pass_message $subdir/$src_code + + if [info exists GROUP] { + if {[lsearch $groups $GROUP] == -1} { + return + } + } + + if [string match $run yes] { + set actions run + } + + set output_file "$tmpdir/[file tail [file rootname $src_code]]" + set assembly_file "$output_file" + append assembly_file ".S" + + set compile_type "none" + + case $actions { + compile + { + set compile_type "assembly" + set output_file $assembly_file + } + assemble + { + set compile_type "object" + append output_file ".o" + } + link + { + set compile_type "executable" + append output_file ".exe" + } + run + { + set compile_type "executable" + append output_file ".exe" + set run yes + } + default + { + set output_file "" + set compile_type "none" + } + } + + set src_file "$srcdir/$subdir/$src_code" + set options "" + + if { $comp_options != "" } { + lappend options "additional_flags=$comp_options" + } + + if ![ishost "*-dos-*"] { + lappend options "libs=-lstdc++ -lg++" + } else { + lappend options "libs=-lstdcxx -lgxx" + } + + set comp_output [g++_target_compile $src_file $output_file $compile_type $options] + + set pass no + + # Delete things like "ld.so warning" messages. + set comp_output [prune_warnings $comp_output] + + if [regexp -- $not_compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "\nChecking:\n$not_compiler_output\nto make sure it does not match:\n$comp_output\nbut it does.\n\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + fail $fail_message + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + mike_cleanup $src_code $output_file $assembly_file + return + } + + # remove any leftover CRs. + regsub -all -- "\r" $comp_output "" comp_output + + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $comp_output "" comp_output + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $comp_output "" comp_output + + set unsupported_message [${tool}_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$subdir/$src_code: $unsupported_message" + mike_cleanup $src_code $output_file $assembly_file + return + } + + if { $verbose > 1 } { + send_user "\nChecking:\n$compiler_output\nto see if it matches:\n$comp_output\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + if [regexp -- $compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + set pass yes + if [file exists [file rootname [file tail $src_code]].s] { + set fd [open [file rootname [file tail $src_code]].s r] + set dot_s [read $fd] + close $fd + if { $compiler_result != "" } { + verbose "Checking .s file for $compiler_result" 2 + if [regexp -- $compiler_result $dot_s] { + verbose "Yes, it matches." 2 + } else { + verbose "Nope, doesn't match." 2 + verbose $dot_s 4 + set pass no + } + } + if { $not_compiler_result != "" } { + verbose "Checking .s file for not $not_compiler_result" 2 + if ![regexp -- $not_compiler_result $dot_s] { + verbose "Nope, not found (that's good)." 2 + } else { + verbose "Uh oh, it was found." 2 + verbose $dot_s 4 + set pass no + } + } + } + if [string match $run yes] { + set result [g++_load $output_file] + set status [lindex $result 0] + set output [lindex $result 1] + + if { $status == -1 } { + mike_cleanup $src_code $output_file $assembly_file + return + } + if { $verbose > 1 } { + send_user "Checking:\n$program_output\nto see if it matches:\n$output\n\n" + } + if ![regexp -- $program_output $output] { + set pass no + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } else { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + } + } + } else { + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } + + if [string match $pass "yes"] { + pass $pass_message + } else { + fail $fail_message + } + + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + + mike_cleanup $src_code $output_file $assembly_file +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/mike-gcc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/mike-gcc.exp new file mode 100644 index 0000000000000000000000000000000000000000..2d5d8b45b5bceeb8aa297b385e554d279bffb857 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/mike-gcc.exp @@ -0,0 +1,261 @@ +# Copyright (C) 1988-2020 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 +# . + +# This file was derived from mike-g++.exp written by Mike Stump + +load_lib target-utils.exp + +# +# mike_cleanup -- remove any files that are created by the testcase +# +proc mike_cleanup { src_code output_file assembly_file } { + remote_file build delete $output_file $assembly_file +} + +# +# prebase -- sets up a Mike Stump (mrs@cygnus.com) style gcc test +# +proc prebase { } { + global compiler_output + global not_compiler_output + global compiler_result + global not_compiler_result + global program_output + global groups + global run + global actions + global target_regexp + + set compiler_output "^$" + set not_compiler_output ".*Internal compiler error.*" + set compiler_result "" + set not_compiler_result "" + set program_output ".*PASS.*" + set groups {} + set run no + set actions assemble + set target_regexp ".*" +} + +# +# run the test +# +proc postbase { src_code run groups args } { + global verbose + global srcdir + global subdir + global not_compiler_output + global compiler_output + global compiler_result + global not_compiler_result + global program_output + global actions + global target_regexp + global host_triplet + global target_triplet + global tool + global tmpdir + global GCC_UNDER_TEST + global GROUP + + if ![info exists GCC_UNDER_TEST] { + error "No compiler specified for testing." + } + + if ![regexp $target_regexp $target_triplet] { + unsupported $subdir/$src_code + return + } + + if { [llength $args] > 0 } { + set comp_options [lindex $args 0] + } else { + set comp_options "" + } + + set fail_message $subdir/$src_code + set pass_message $subdir/$src_code + + if [info exists GROUP] { + if {[lsearch $groups $GROUP] == -1} { + return + } + } + + if [string match $run yes] { + set actions run + } + + set output_file "$tmpdir/[file tail [file rootname $src_code]]" + set assembly_file "$output_file" + append assembly_file ".S" + + set compile_type "none" + + case $actions { + compile + { + set compile_type "assembly" + set output_file $assembly_file + } + assemble + { + set compile_type "object" + append output_file ".o" + } + link + { + set compile_type "executable" + append output_file ".exe" + } + run + { + set compile_type "executable" + append output_file ".exe" + set run yes + } + default + { + set output_file "" + set compile_type "none" + } + } + + set src_file "$srcdir/$subdir/$src_code" + set options "" + lappend options "compiler=$GCC_UNDER_TEST" + + if { $comp_options != "" } { + lappend options "additional_flags=$comp_options" + } + + set comp_output [gcc_target_compile $src_file $output_file $compile_type $options] + + set pass no + + # Delete things like "ld.so warning" messages. + set comp_output [prune_warnings $comp_output] + + if [regexp -- $not_compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "\nChecking:\n$not_compiler_output\nto make sure it does not match:\n$comp_output\nbut it does.\n\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + fail $fail_message + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + mike_cleanup $src_code $output_file $assembly_file + return + } + + # remove any leftover CRs. + regsub -all -- "\r" $comp_output "" comp_output + + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $comp_output "" comp_output + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $comp_output "" comp_output + + set unsupported_message [${tool}_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$subdir/$src_code: $unsupported_message" + mike_cleanup $src_code $output_file $assembly_file + return + } + + if { $verbose > 1 } { + send_user "\nChecking:\n$compiler_output\nto see if it matches:\n$comp_output\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + if [regexp -- $compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + set pass yes + if [file exists [file rootname [file tail $src_code]].s] { + set fd [open [file rootname [file tail $src_code]].s r] + set dot_s [read $fd] + close $fd + if { $compiler_result != "" } { + verbose "Checking .s file for $compiler_result" 2 + if [regexp -- $compiler_result $dot_s] { + verbose "Yes, it matches." 2 + } else { + verbose "Nope, doesn't match." 2 + verbose $dot_s 4 + set pass no + } + } + if { $not_compiler_result != "" } { + verbose "Checking .s file for not $not_compiler_result" 2 + if ![regexp -- $not_compiler_result $dot_s] { + verbose "Nope, not found (that's good)." 2 + } else { + verbose "Uh oh, it was found." 2 + verbose $dot_s 4 + set pass no + } + } + } + if [string match $run yes] { + set result [gcc_load $output_file] + set status [lindex $result 0] + set output [lindex $result 1] + if { $status == -1 } { + mike_cleanup $src_code $output_file $assembly_file + return + } + if { $verbose > 1 } { + send_user "Checking:\n$program_output\nto see if it matches:\n$output\n\n" + } + if ![regexp -- $program_output $output] { + set pass no + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } else { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + } + } + } else { + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } + + if [string match $pass "yes"] { + pass $pass_message + } else { + fail $fail_message + } + + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + + mike_cleanup $src_code $output_file $assembly_file +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/multiline.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/multiline.exp new file mode 100644 index 0000000000000000000000000000000000000000..627ad68817f3cf964aaee2deccbdfd4a0663f909 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/multiline.exp @@ -0,0 +1,356 @@ +# Copyright (C) 2015-2020 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 +# . + +# Testing of multiline output + +# We have pre-existing testcases like this: +# |typedef struct _GMutex GMutex; // { dg-message "previously declared here"} +# (using "|" here to indicate the start of a line), +# generating output like this: +# |gcc/testsuite/g++.dg/diagnostic/wrong-tag-1.C:4:16: note: 'struct _GMutex' was previously declared here +# where the location of the dg-message determines the expected line at +# which the error should be reported. +# +# To handle rich error-reporting, we want to be able to verify that we +# get output like this: +# |gcc/testsuite/g++.dg/diagnostic/wrong-tag-1.C:4:16: note: 'struct _GMutex' was previously declared here +# | typedef struct _GMutex GMutex; // { dg-message "previously declared here"} +# | ^~~~~~~ +# where the compiler's first line of output is as before, but in +# which it then echoes the source lines, adding annotations. +# +# We want to be able to write testcases that verify that the +# emitted source-and-annotations are sane. +# +# A complication here is that the source lines contain comments +# containing DejaGnu directives (such as the "dg-message" above). +# +# We punt this somewhat by only matching the beginnings of lines. +# so that we can write e.g. +# |/* { dg-begin-multiline-output "" } +# | typedef struct _GMutex GMutex; +# | ^~~~~~~ +# | { dg-end-multiline-output "" } */ +# to have the testsuite verify the expected output. + +############################################################################ +# Global variables. +############################################################################ + +# This is intended to only be used from within multiline.exp. +# The line number of the last dg-begin-multiline-output directive. +set _multiline_last_beginning_line -1 + +# A list of +# first-line-number, last-line-number, lines +# where each "lines" is a list of strings. +# This is cleared at the end of each test by gcc-dg.exp's wrapper for dg-test. +set multiline_expected_outputs [] + +# Was dg-enable-nn-line-numbers called? +set nn_line_numbers_enabled 0 + +############################################################################ +# Exported functions. +############################################################################ + +# Mark the beginning of an expected multiline output +# All lines between this and the next dg-end-multiline-output are +# expected to be seen. + +proc dg-begin-multiline-output { args } { + global _multiline_last_beginning_line + verbose "dg-begin-multiline-output: args: $args" 3 + set line [expr [lindex $args 0] + 1] + + # Complain if there hasn't been a dg-end-multiline-output + # since the last dg-begin-multiline-output + if { $_multiline_last_beginning_line != -1 } { + set last_directive_line [expr $_multiline_last_beginning_line - 1] + error "$last_directive_line: unterminated dg-begin-multiline-output" + } + + set _multiline_last_beginning_line $line +} + +# Mark the end of an expected multiline output +# All lines up to here since the last dg-begin-multiline-output are +# expected to be seen. +# +# dg-end-multiline-output comment [{ target/xfail selector }] + +proc dg-end-multiline-output { args } { + global _multiline_last_beginning_line + verbose "dg-end-multiline-output: args: $args" 3 + set first_line $_multiline_last_beginning_line + + # Complain if there hasn't been a dg-begin-multiline-output + if { $first_line == -1 } { + error "[lindex $args 0]: dg-end-multiline-output without dg-begin-multiline-output" + return + } + set _multiline_last_beginning_line -1 + + set last_line [expr [lindex $args 0] - 1] + verbose "multiline output lines: $first_line-$last_line" 3 + + if { [llength $args] > 3 } { + error "[lindex $args 0]: too many arguments" + return + } + + set maybe_x "" + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "F" { set maybe_x "x" } + "P" { set maybe_x "" } + "N" { + # If we get "N", this output doesn't apply to us so ignore it. + return + } + } + } + + upvar 1 prog prog + verbose "prog: $prog" 3 + # "prog" now contains the filename + # Load it and split it into lines + + set lines [_get_lines $prog $first_line $last_line] + + verbose "lines: $lines" 3 + # Create an entry of the form: first-line, last-line, lines, maybe_x + set entry [list $first_line $last_line $lines $maybe_x] + global multiline_expected_outputs + lappend multiline_expected_outputs $entry + verbose "within dg-end-multiline-output: multiline_expected_outputs: $multiline_expected_outputs" 3 +} + +# Hook to be called by prune.exp's prune_gcc_output to +# look for the expected multiline outputs, pruning them, +# reporting PASS for those that are found, and FAIL for +# those that weren't found. +# +# It returns a pruned version of its output. + +proc handle-multiline-outputs { text } { + global multiline_expected_outputs + global testname_with_flags + set index 0 + foreach entry $multiline_expected_outputs { + verbose " entry: $entry" 3 + set start_line [lindex $entry 0] + set end_line [lindex $entry 1] + set multiline [lindex $entry 2] + set maybe_x [lindex $entry 3] + verbose " multiline: $multiline" 3 + set rexp [_build_multiline_regex $multiline $index] + verbose "rexp: ${rexp}" 4 + # Escape newlines in $rexp so that we can print them in + # pass/fail results. + set escaped_regex [string map {"\n" "\\n"} $rexp] + verbose "escaped_regex: ${escaped_regex}" 4 + + set title "$testname_with_flags expected multiline pattern lines $start_line-$end_line" + + # Use "regsub" to attempt to prune the pattern from $text + if {[regsub -line $rexp $text "" text]} { + # The multiline pattern was pruned. + ${maybe_x}pass "$title was found: \"$escaped_regex\"" + } else { + ${maybe_x}fail "$title not found: \"$escaped_regex\"" + } + + set index [expr $index + 1] + } + + return $text +} + +# DejaGnu directive to enable post-processing the line numbers printed in +# the left-hand margin when printing the source code, converting them to +# "NN", e.g from: +# +# 100 | if (flag) +# | ^ +# | | +# | (1) following 'true' branch... +# 101 | { +# 102 | foo (); +# | ^ +# | | +# | (2) ...to here +# +# to: +# +# NN | if (flag) +# | ^ +# | | +# | (1) following 'true' branch... +# NN | { +# NN | foo (); +# | ^ +# | | +# | (2) ...to here +# +# This is useful e.g. when testing how interprocedural paths are printed +# via dg-begin/end-multiline-output, to avoid depending on precise line +# numbers. + +proc dg-enable-nn-line-numbers { args } { + verbose "dg-nn-line-numbers: args: $args" 2 + global nn_line_numbers_enabled + set nn_line_numbers_enabled 1 +} + +# Hook to be called by prune.exp's prune_gcc_output to convert such line +# numbers to "NN" form. +# +# Match substrings of the form: +# " 25 |" +# and convert them to: +# " NN |" +# +# It returns a copy of its input, with the above changes. + +proc maybe-handle-nn-line-numbers { text } { + global testname_with_flags + + verbose "maybe-handle-nn-line-numbers" 3 + + global nn_line_numbers_enabled + if { [expr {!$nn_line_numbers_enabled}] } { + verbose "nn_line_numbers_enabled false; bailing out" 3 + return $text + } + + verbose "maybe-handle-nn-line-numbers: text before: ${text}" 4 + + # dg.exp's dg-test trims leading whitespace from the output + # in this line: + # set comp_output [string trimleft $comp_output] + # so we can't rely on the exact leading whitespace for the + # first line in the output. + # Match initial input lines that start like: + # "25 |" + # and convert them to: + # " NN |" + set rexp2 {(^[0-9]+ \|)} + set count_a [regsub -all $rexp2 $text " NN |" text] + verbose "maybe-handle-nn-line-numbers: count_a: $count_a" 4 + + # Match lines that start like: + # " 25 |" + # and convert them to: + # " NN |" + set rexp {([ ]+[0-9]+ \|)} + set count_b [regsub -all $rexp $text " NN |" text] + verbose "maybe-handle-nn-line-numbers: count_b: $count_b" 4 + + verbose "maybe-handle-nn-line-numbers: text after: ${text}" 4 + + return $text +} + +############################################################################ +# Internal functions +############################################################################ + +# Load FILENAME and extract the lines from FIRST_LINE +# to LAST_LINE (inclusive) as a list of strings. + +proc _get_lines { filename first_line last_line } { + verbose "_get_lines" 3 + verbose " filename: $filename" 3 + verbose " first_line: $first_line" 3 + verbose " last_line: $last_line" 3 + + set fp [open $filename r] + set file_data [read $fp] + close $fp + set data [split $file_data "\n"] + set linenum 1 + set lines [] + foreach line $data { + verbose "line $linenum: $line" 4 + if { $linenum >= $first_line && $linenum <= $last_line } { + lappend lines $line + } + set linenum [expr $linenum + 1] + } + + return $lines +} + +# Convert $multiline from a list of strings to a multiline regex +# We need to support matching arbitrary followup text on each line, +# to deal with comments containing containing DejaGnu directives. + +proc _build_multiline_regex { multiline index } { + verbose "_build_multiline_regex: $multiline $index" 4 + + set rexp "" + foreach line $multiline { + verbose " line: $line" 4 + + # We need to escape "^" and other regexp metacharacters. + set line [string map {"^" "\\^" + "(" "\\(" + ")" "\\)" + "[" "\\[" + "]" "\\]" + "{" "\\{" + "}" "\\}" + "." "\\." + "\\" "\\\\" + "?" "\\?" + "+" "\\+" + "*" "\\*" + "|" "\\|"} $line] + + append rexp $line + if {[string match "*^" $line] || [string match "*~" $line]} { + # Assume a line containing a caret/range. This must be + # an exact match. + } else { + # Assume that we have a quoted source line. + if {![string equal "" $line] } { + # Support arbitrary followup text on each non-empty line, + # to deal with comments containing containing DejaGnu + # directives. + append rexp ".*" + } + } + append rexp "\n" + } + + # dg.exp's dg-test trims leading whitespace from the output + # in this line: + # set comp_output [string trimleft $comp_output] + # so we can't rely on the exact leading whitespace for the + # first line in the *first* multiline regex. + # + # Trim leading whitespace from the regexp, replacing it with + # a "\s*", to match zero or more whitespace characters. + if { $index == 0 } { + set rexp [string trimleft $rexp] + set rexp "\\s*$rexp" + } + + verbose "rexp: $rexp" 4 + + return $rexp +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/obj-c++-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/obj-c++-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..edadb6ed5b5d6ea334d44d8bb5166836dcbb73ee --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/obj-c++-dg.exp @@ -0,0 +1,73 @@ +# Copyright (C) 2004-2020 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 +# . + +# Define obj-c++ callbacks for dg.exp. + +load_lib gcc-dg.exp + +proc obj-c++-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 obj-c++_target_compile $prog $do_what $extra_tool_flags] +} + + +proc obj-c++-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc obj-c++-dg-runtest { testcases flags default-extra-flags } { + global runtests + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS LTO_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS [list {}] $LTO_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + global torture_with_loops torture_without_loops + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + # combine flags so that dg-skip & xfail will see the extras. + set combined_flags "$flags $flags_t ${default-extra-flags}" + verbose "Testing $nshort, $combined_flags" 1 + dg-test $test $combined_flags "" + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/obj-c++.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/obj-c++.exp new file mode 100644 index 0000000000000000000000000000000000000000..063afe33b3907b8e588fea0f3380fa174cf354a0 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/obj-c++.exp @@ -0,0 +1,410 @@ +# Copyright (C) 2004-2020 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Many modifications by Jeffrey Wheat (cassidy@cygnus.com) +# With modifications by Mike Stump . + +# +# obj-c++ support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# OBJCXX_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" + +# +# obj-c++_version -- extract and print the version number of the compiler +# + +proc obj-c++_version { } { + global OBJCXX_UNDER_TEST + + obj-c++_init + + # Ignore any arguments after the command. + set compiler [lindex $OBJCXX_UNDER_TEST 0] + + # Verify that the compiler exists. + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0]; + set output [lindex $tmp 1]; + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # Compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# obj-c++_include_flags -- provide new version of obj-c++_include_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# +proc obj-c++_include_flags { paths } { + global srcdir + global HAVE_LIBSTDCXX_V3 + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set gccpath ${paths} + + set odir [lookfor_file ${gccpath} libstdc++-v3] + if { ${odir} != "" } { + append flags [exec sh ${odir}/scripts/testsuite_flags --build-includes] + } + + return "$flags" +} + +# +# obj-c++_link_flags -- provide new version of obj-c++_link_flags +# (originally from libgloss.exp) which knows about the gcc tree structure. +# + +proc obj-c++_link_flags { paths } { + global rootme + global srcdir + global ld_library_path + global OBJCXX_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/lib/libstdc++.a"] { + append ld_library_path ":${gccpath}/lib" + } + if [file exists "${gccpath}/libg++/libg++.a"] { + append flags " -L${gccpath}/libg++ " + append ld_library_path ":${gccpath}/libg++" + } + if [file exists "${gccpath}/libstdc++/libstdc++.a"] { + append flags " -L${gccpath}/libstdc++ " + append ld_library_path ":${gccpath}/libstdc++" + } + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] { + # Allow for %s spec substitutions + append flags " -B${gccpath}/libstdc++-v3/src/.libs " + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + # Look for libstdc++.${shlib_ext}. + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] { + # Allow for %s spec substitutions + append flags " -B${gccpath}/libstdc++-v3/src/.libs " + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags " -L${gccpath}/libiberty " + } + if [file exists "${gccpath}/librx/librx.a"] { + append flags " -L${gccpath}/librx " + } + + set objcpath "[get_multilibs]" + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.a] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.a] + } + # Now check if we have a shared only build. + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.${shlib_ext}] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.${shlib_ext}] + } + } + + verbose "libobjc_dir: $libobjc_dir" + + if { $libobjc_dir != "" } { + set libobjc_dir [file dirname ${libobjc_dir}] + # Allow for %s spec substitutions + append flags " -B${libobjc_dir} " + append flags " -L${libobjc_dir} " + append ld_library_path ":${libobjc_dir}" + } + append ld_library_path \ + [gcc-set-multilib-library-path $OBJCXX_UNDER_TEST] + } else { + global tool_root_dir; + + set libgpp [lookfor_file ${tool_root_dir} libg++]; + if { $libgpp != "" } { + append flags "-L${libgpp} "; + append ld_library_path ":${libgpp}" + } + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++]; + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} "; + append ld_library_path ":${libstdcpp}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty]; + if { $libiberty != "" } { + append flags "-L${libiberty} "; + } + set librx [lookfor_file ${tool_root_dir} librx]; + if { $librx != "" } { + append flags "-L${librx} "; + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# obj-c++_init -- called at the start of each subdir of tests +# + +proc obj-c++_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags; + global objdir srcdir + global ALWAYS_OBJCXXFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global OBJCXX_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + global TEST_ALWAYS_FLAGS + + if ![info exists OBJCXX_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set OBJCXX_UNDER_TEST $TOOL_EXECUTABLE; + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set OBJCXX_UNDER_TEST [transform c++] + } else { + set OBJCXX_UNDER_TEST [findfile $base_dir/../../xg++ "$base_dir/../../xg++ -B$base_dir/../../" [findfile $base_dir/xg++ "$base_dir/xg++ -B$base_dir/" [transform c++]]] + } + } + } + + # Bleah, nasty. Bad taste. + if [ishost "*-dos-*" ] { + regsub "c\\+\\+" "$OBJCXX_UNDER_TEST" "gcc" OBJCXX_UNDER_TEST + } + + if ![is_remote host] { + if { [which $OBJCXX_UNDER_TEST] == 0 } then { + perror "OBJCXX_UNDER_TEST ($OBJCXX_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + obj-c++_maybe_build_wrapper "${tmpdir}/obj-c++-testglue.o" "-fexceptions" + + set ALWAYS_OBJCXXFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=[obj-c++_include_flags [get_multilibs ${TOOL_OPTIONS}] ]"; + lappend ALWAYS_OBJCXXFLAGS "ldflags=[obj-c++_link_flags [get_multilibs ${TOOL_OPTIONS}] ]"; + } else { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=[obj-c++_include_flags [get_multilibs] ]"; + lappend ALWAYS_OBJCXXFLAGS "ldflags=[obj-c++_link_flags [get_multilibs] ]"; + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=$TOOL_OPTIONS"; + } + + # Make sure that lines are not wrapped. That can confuse the + # error-message parsing machinery. + lappend ALWAYS_OBJCXXFLAGS "additional_flags=-fmessage-length=0" + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + if { [istarget *-*-darwin*] } { + lappend ALWAYS_OBJCXXFLAGS "ldflags=-multiply_defined suppress" + } + + verbose -log "ALWAYS_OBJCXXFLAGS set to $ALWAYS_OBJCXXFLAGS" + + verbose "obj-c++ is initialized" 3 +} + +# +# obj-c++_target_compile -- compile a source file +# + +proc obj-c++_target_compile { source dest type options } { + global tmpdir + global srcdir + global gpp_compile_options + global gluefile wrap_flags + global ALWAYS_OBJCXXFLAGS + global OBJCXX_UNDER_TEST + global shlib_ext + + set shlib_ext [get_shlib_extension] + verbose "input-options: $options" 4 + + # We have to figure out which runtime will be used on darwin because + # we need to add the include path for the gnu runtime if that is in + # use. + # First, set the default... + if { [istarget *-*-darwin*] } { + set nextruntime 1 + } else { + set nextruntime 0 + } + verbose "initial next runtime state : $nextruntime" 2 + # Next, see if we define the option in dg-options... + foreach opt $options { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + verbose "next runtime state after dg opts: $nextruntime" 2 + + set tgt [target_info name] + if [board_info $tgt exists multilib_flags] { + set lb [board_info $tgt multilib_flags] + verbose "board multilib_flags $lb" 2 + foreach opt $lb { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + } + verbose "next runtime state after any multilib opts: $nextruntime" 2 + + lappend options "libs=-lobjc" + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + # If we have built libobjc along with the compiler, point the test harness + # at it (and associated headers). + + set objcpath "[get_multilibs]" + + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.a] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.a] + } + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.${shlib_ext}] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.${shlib_ext}] + } + } + + if { $libobjc_dir != "" } { + # If we are using the gnu runtime, add its includes. + if { $nextruntime == 0 } { + set objc_include_dir "${srcdir}/../../libobjc" + lappend options "additional_flags=-I${objc_include_dir}" + } + } + + lappend options "additional_flags=[libio_include_flags]" + lappend options "compiler=$OBJCXX_UNDER_TEST"; + lappend options "timeout=[timeout_value]" + + set options [concat $gpp_compile_options $options] + + set options [concat "$ALWAYS_OBJCXXFLAGS" $options]; + + set options [dg-additional-files-options $options $source] + + set result [target_compile $source $dest $type $options] + + return $result +} + +# +# ${tool}_option_help +# + +proc ${tool}_option_help { } { + send_user " --additional_options,OPTIONS\t\tUse OPTIONS to compile the testcase files. OPTIONS should be comma-separated.\n" +} + +# +# ${tool}_option_proc +# + +proc ${tool}_option_proc { option } { + if [regexp "^--additional_options," $option] { + global gpp_compile_options + regsub "--additional_options," $option "" option + foreach x [split $option ","] { + lappend gpp_compile_options "additional_flags=$x" + } + return 1; + } else { + return 0 + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..12ea9a9a358ab2da8320e87b350130c9693eb479 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc-dg.exp @@ -0,0 +1,74 @@ +# Copyright (C) 1997-2020 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 +# . + +load_lib gcc-dg.exp + +# Define gcc callbacks for dg.exp. + +proc objc-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 objc_target_compile $prog $do_what $extra_tool_flags] +} + +proc objc-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc objc-dg-runtest { testcases flags default-extra-flags } { + global runtests + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS LTO_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS [list {}] $LTO_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + global torture_with_loops torture_without_loops + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + # combine flags so that dg-skip & xfail will see the extras. + set combined_flags "$flags $flags_t ${default-extra-flags}" + verbose "Testing $nshort, $combined_flags" 1 + dg-test $test $combined_flags "" + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..9aa5792f6568ecefd6c65a72c4eb2c4ee42a5c3b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc-torture.exp @@ -0,0 +1,390 @@ +# Copyright (C) 1992-2020 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 +# . + +# This file was written by Rob Savoye. (rob@cygnus.com) + +load_lib file-format.exp +load_lib target-supports.exp + +# Make sure that the runtime list is re-evaluated for each multilib. +proc objc-set-runtime-options { dowhat args } { + global OBJC_RUNTIME_OPTIONS + set rtlist [list "-fgnu-runtime" ] + # At present (4.6), the only NeXT runtime target is Darwin. + # The previously used approach of testing trivial compiles is not reliable + # for determining the absence of the NeXT runtime, since a non-Darwin + # installation can have the objc headers present in the same locations + # that Darwin uses. If NeXT is ported to another target, then it should + # be listed here. + if [istarget *-*-darwin*] { + lappend rtlist "-fnext-runtime" + } + if [info exists OBJC_RUNTIME_OPTIONS] { + foreach other $OBJC_RUNTIME_OPTIONS { + # Don't do tests twice... + if { ( $other == "-fnext-runtime" || $other == "-fgnu-runtime" ) } { + continue + } + lappend rtlist $other + } + } + + set OBJC_RUNTIME_OPTIONS "" + + foreach type $rtlist { + global srcdir subdir target_triplet tmpdir + + set options "additional_flags=$type" + if [info exists args] { + lappend options $args + } + verbose "options $options" + if [info exists dowhat] { + switch $dowhat { + "compile" { + # We should check that the generated asm is sensible, so do + # the equivalent of -c. + set compile_type "object" + set output_file "trivial.o" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" "$output_file" "$compile_type" $options] + + remote_file build delete $output_file + # If we get any error, then we failed. + if ![string match "" $comp_output] then { + continue; + } + } + "execute" { + set test_obj "trivial.exe" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" $test_obj "executable" $options] + + # If we get any error, then we failed. + if ![string match "" $comp_output] then { + remote_file build delete $test_obj + continue; + } + set result [objc_load "$tmpdir/$test_obj" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $test_obj + if { $status != "pass" } { + verbose -log "trivial execute failed with $status $output" + continue; + } + } + default { + perror "$dowhat: not a valid objc-torture action" + return "" + } + } + } else { + set test_obj "trivial.exe" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" $test_obj executable $options] + + # If we get any error, then we failed. + remote_file build delete $test_obj + if ![string match "" $comp_output] then { + continue; + } + } + lappend OBJC_RUNTIME_OPTIONS $type + } + + verbose -log "Using the following runtimes: $OBJC_RUNTIME_OPTIONS" +} + +# The default option list can be overridden by +# TORTURE_OPTIONS="{ { list1 } ... { listN } }" + +if [info exists TORTURE_OPTIONS] { + set OBJC_TORTURE_OPTIONS $TORTURE_OPTIONS +} else { + # It is theoretically beneficial to group all of the O2/O3 options together, + # as in many cases the compiler will generate identical executables for + # all of them--and the objc-torture testsuite will skip testing identical + # executables multiple times. + # Also note that -finline-functions is explicitly included in one of the + # items below, even though -O3 is also specified, because some ports may + # choose to disable inlining functions by default, even when optimizing. + set OBJC_TORTURE_OPTIONS [list \ + " -O0 " \ + " -O1 " \ + " -O2 " \ + " -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions " \ + " -O3 -g " \ + " -Os " ] +} + +if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set OBJC_TORTURE_OPTIONS \ + [concat $OBJC_TORTURE_OPTIONS $ADDITIONAL_TORTURE_OPTIONS] +} + +# +# objc-torture-compile -- runs the Tege OBJC-torture test +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc objc-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and analyze the results. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [objc_target_compile "$src" "$output" object $options] + objc_check_compile $testcase $option $output $comp_output + remote_file build delete $output +} + +# +# objc-torture-execute -- utility to compile and execute a testcase +# +# SRC is the full pathname of the testcase. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc objc-torture-execute { src args } { + global tmpdir tool srcdir output compiler_conditional_xfail_data + + if { [llength $args] > 0 } { + set additional_flags [lindex $args 0] + } else { + set additional_flags "" + } + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set executable $tmpdir/[file tail [file rootname $src].x] + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + set count 0 + set oldstatus "foo" + foreach option $option_list { + if { $count > 0 } { + if [info exists oldexec] { + remote_file build delete $oldexec + } + set oldexec $execname + } + set execname "${executable}${count}" + incr count + + # torture_{compile,execute}_xfail are set by the .x script + # (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_{compile,execute} can be set by the .x script + # (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + remote_file build delete $execname + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + set comp_output [objc_target_compile "$src" "${execname}" executable $options] + + if ![objc_check_compile "$testcase compilation" $option $execname $comp_output] { + unresolved "$testcase execution, $option" + remote_file build delete $execname + continue + } + + # See if this source file uses "long long" types, if it does, and + # no_long_long is set, skip execution of the test. + if [target_info exists no_long_long] then { + if [expr [search_for $src "long long"]] then { + unsupported "$testcase execution, $option" + remote_file build delete $execname + continue + } + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + + # Sometimes we end up creating identical executables for two + # consecutive sets of different of compiler options. + # + # In such cases we know the result of this test will be identical + # to the result of the last test. + # + # So in cases where the time to load and run/simulate the test + # is relatively high, compare the two binaries and avoid rerunning + # tests if the executables are identical. + # + # Do not do this for native testing since the cost to load/execute + # the test is fairly small and the comparison step actually slows + # the entire process down because it usually does not "hit". + set skip 0 + if { ![isnative] && [info exists oldexec] } { + if { [remote_file build cmp $oldexec $execname] == 0 } { + set skip 1 + set status $oldstatus + } + } + if { $skip == 0 } { + set result [objc_load "$execname" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + } + $status "$testcase execution, $option" + set oldstatus $status + # for each option + } + # tidy up + if [info exists execname] { + remote_file build delete $execname + } + if [info exists oldexec] { + remote_file build delete $oldexec + } +} + +# +# search_for -- looks for a string match in a file +# +proc search_for { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + +# +# objc-torture -- the objc-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# SRC is the full pathname of the testcase, or just a file name in which case +# we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc objc-torture { args } { + global srcdir subdir compiler_conditional_xfail_data + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + # loop through all the options + foreach option $option_list { + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + objc-torture-compile $src "$option $options" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc.exp new file mode 100644 index 0000000000000000000000000000000000000000..acdeb5b1a16c3a3fa57160e03ad2d8db890a5dcb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/objc.exp @@ -0,0 +1,356 @@ +# Copyright (C) 1992-2020 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Currently maintained by Doug Evans (dje@cygnus.com) + +# This file is loaded by the tool init file (eg: unix.exp). It provides +# default definitions for objc_start, etc. and other supporting cast members. + +# These globals are used by objc_start if no compiler arguments are provided. +# They are also used by the various testsuites to define the environment: +# where to find stdio.h, libc.a, etc. + +load_lib libgloss.exp +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp +load_lib target-utils.exp + +# +# OBJC_UNDER_TEST is the compiler under test. +# + +# +# default_objc_version -- extract and print the version number of the compiler +# + +proc default_objc_version { } { + global OBJC_UNDER_TEST + + objc_init + + # Ignore any arguments after the command. + set compiler [lindex $OBJC_UNDER_TEST 0] + + if ![is_remote host] { + set compiler_name [which $compiler] + } else { + set compiler_name $compiler + } + + # Verify that the compiler exists. + if { $compiler_name != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + clone_output "$compiler_name $version\n" + } else { + clone_output "Couldn't determine version of $compiler_name: $output\n" + } + } else { + # Compiler does not exist (this should have already been detected). + warning "$compiler does not exist" + } +} + +# +# Call objc_version. We do it this way so we can override it if needed. +# +proc objc_version { } { + default_objc_version +} + +# +# objc_init -- called at the start of each .exp script. +# +# There currently isn't much to do, but always using it allows us to +# make some enhancements without having to go back and rewrite the scripts. +# + +set objc_initialized 0 + +proc objc_init { args } { + global rootme + global tmpdir + global libdir + global gluefile wrap_flags + global objc_initialized + global OBJC_UNDER_TEST + global TOOL_EXECUTABLE + global objc_libgcc_s_path + global gcc_warning_prefix + global gcc_error_prefix + + # We set LC_ALL and LANG to C so that we get the same error messages as + # expected. + setenv LC_ALL C + setenv LANG C + + # Many hosts now default to a non-ASCII C locale, however, so + # they can set a charset encoding here if they need. + if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII + } + + if { $objc_initialized == 1 } { return; } + + if ![info exists OBJC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set OBJC_UNDER_TEST $TOOL_EXECUTABLE + } else { + set OBJC_UNDER_TEST [find_gcc] + } + } + + if ![info exists tmpdir] then { + set tmpdir /tmp + } + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + objc_maybe_build_wrapper "${tmpdir}/objc-testglue.o" + + set objc_libgcc_s_path [gcc-set-multilib-library-path $OBJC_UNDER_TEST] +} + +proc objc_target_compile { source dest type options } { + global rootme + global tmpdir + global gluefile wrap_flags + global srcdir + global OBJC_UNDER_TEST + global TOOL_OPTIONS + global ld_library_path + global objc_libgcc_s_path + global shlib_ext + global TEST_ALWAYS_FLAGS + + set shlib_ext [get_shlib_extension] + set ld_library_path ".:${objc_libgcc_s_path}" + + # We have to figure out which runtime will be used on darwin because + # we need to add the include path for the gnu runtime if that is in + # use. + # First set the default... + if { [istarget *-*-darwin*] } { + set nextruntime 1 + } else { + set nextruntime 0 + } + verbose "initial next runtime state : $nextruntime" 2 + # Next, see if we define the option in dg-options... + foreach opt $options { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + verbose "next runtime state after dg opts: $nextruntime" 2 + + set tgt [target_info name] + if [board_info $tgt exists multilib_flags] { + set lb [board_info $tgt multilib_flags] + verbose "board multilib_flags $lb" 2 + foreach opt $lb { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + } + verbose "next runtime state after any multilib opts: $nextruntime" 2 + + lappend options "libs=-lobjc" + verbose "shared lib extension: $shlib_ext" 3 + + if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" + } + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options] + } + + # TOOL_OPTIONS must come first, so that it doesn't override testcase + # specific options. + if [info exists TOOL_OPTIONS] { + set options [concat "{additional_flags=$TOOL_OPTIONS}" $options] + } + + # If we have built libobjc along with the compiler, point the test harness + # at it (and associated headers). + + set objcpath "[get_multilibs]" + + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.a] + if { $libobjc_dir == "" } { + # On darwin there is, potentially, a gnu runtime too. + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.a] + } + # Perhaps we didn't build static libs. + if { $libobjc_dir == "" } { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.${shlib_ext}] + # On darwin there is, potentially, a gnu runtime too. + if { $libobjc_dir == "" } { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.${shlib_ext}] + } + } + + if { $libobjc_dir != "" } { + # If we are using the gnu runtime, add its includes. + if { $nextruntime == 0 } { + set objc_include_dir "${srcdir}/../../libobjc" + lappend options "additional_flags=-I${objc_include_dir}" + verbose "adding gnu runtime include dir: $objc_include_dir " + } + set libobjc_dir [file dirname ${libobjc_dir}] + # Allow for %s spec substitutions.. + set objc_link_flags " -B${libobjc_dir} " + lappend options "additional_flags=${objc_link_flags}" + set objc_link_flags " -L${libobjc_dir} " + lappend options "additional_flags=${objc_link_flags}" + append ld_library_path ":${libobjc_dir}" + } + if { $type == "precompiled_header" } { + # If we generating a precompiled header, we have say this is an + # objective-C header. + set source [concat "-x objective-c-header" $source] + } + lappend options "compiler=$OBJC_UNDER_TEST" + lappend options "timeout=[timeout_value]" + + set_ld_library_path_env_vars + + set options [dg-additional-files-options $options $source] + + return [target_compile $source $dest $type $options] +} + +# +# objc_pass -- utility to record a testcase passed. +# + +proc objc_pass { testcase cflags } { + if { "$cflags" == "" } { + pass "$testcase" + } else { + pass "$testcase, $cflags" + } +} + +# +# objc_fail -- utility to record a testcase failed +# + +proc objc_fail { testcase cflags } { + if { "$cflags" == "" } { + fail "$testcase" + } else { + fail "$testcase, $cflags" + } +} + +# +# objc_finish -- called at the end of every .exp script that calls objc_init +# +# The purpose of this proc is to hide all quirks of the testing environment +# from the testsuites. It also exists to undo anything that objc_init did +# (that needs undoing). +# + +proc objc_finish { } { + # The testing harness apparently requires this. + global errorInfo + + if [info exists errorInfo] then { + unset errorInfo + } + + # Might as well reset these (keeps our caller from wondering whether + # s/he has to or not). + global prms_id bug_id + set prms_id 0 + set bug_id 0 +} + +proc objc_exit { } { + global gluefile + + if [info exists gluefile] { + file_on_build delete $gluefile + unset gluefile + } +} + +# If this is an older version of dejagnu (without runtest_file_p), +# provide one and assume the old syntax: foo1.exp bar1.c foo2.exp bar2.c. +# This can be deleted after next dejagnu release. + +if { [info procs runtest_file_p] == "" } then { + proc runtest_file_p { runtests testcase } { + if { $runtests != "" && [regexp "\[.\]\[cC\]" $runtests] } then { + if { [lsearch $runtests [file tail $testcase]] >= 0 } then { + return 1 + } else { + return 0 + } + } + return 1 + } +} + +# Provide a definition of this if missing (delete after next dejagnu release). + +if { [info procs prune_warnings] == "" } then { + proc prune_warnings { text } { + return $text + } +} + +# Prune messages from objc that aren't useful. + +proc prune_objc_output { text } { + #send_user "Before:$text\n" + regsub -all "(^|\n)\[^\n\]*: In (function|method) \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: At top level:\[^\n\]*" $text "" text + + # It would be nice to avoid passing anything to objc that would cause it to + # issue these messages (since ignoring them seems like a hack on our part), + # but that's too difficult in the general case. For example, sometimes + # you need to use -B to point objc at crt0.o, but there are some targets + # that don't have crt0.o. + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text + + #send_user "After:$text\n" + + return $text +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/options.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/options.exp new file mode 100644 index 0000000000000000000000000000000000000000..44ea51075bc5d7d09876c888a27f19e483f75499 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/options.exp @@ -0,0 +1,116 @@ +# Copyright (C) 2009-2020 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 +# . + +# We set LC_ALL and LANG to C so that we get the same error messages as expected. +setenv LC_ALL C +setenv LANG C + +# Many hosts now default to a non-ASCII C locale, however, so +# they can set a charset encoding here if they need. +if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII +} + +# Run the LANGUAGE compiler with GCC_OPTIONS and inspect the compiler +# output excluding EXCLUDE lines to make sure that they match the +# newline-separated patterns in COMPILER_PATTERNS but not the patterns in +# COMPILER_NON_PATTERNS. In case of failure, xfail if XFAIL is nonempty. + +proc check_for_options_with_filter { language gcc_options exclude \ + compiler_patterns \ + compiler_non_patterns \ + expected_failure } { + set test "compiler driver $gcc_options option(s):" + set gcc_options "\{additional_flags=$gcc_options\}" + + switch "$language" { + "c" { + set compiler cc1 + set suffix c + } + "c++" { + set compiler cc1plus + set suffix cc + } + default { error "unknown language" } + } + + set filebase test-[pid] + set srcfname $filebase.$suffix + set fd [open $srcfname w] + puts $fd "int main (void) { return 0; }" + close $fd + remote_download host $srcfname + + set gcc_output [gcc_target_compile $srcfname $filebase.x executable $gcc_options] + remote_file build delete $srcfname $filebase.x $filebase.gcno + + if { $exclude != "" } { + set lines [split $gcc_output "\n"] + set gcc_output "" + foreach line $lines { + if {[regexp -line -- "$exclude" $line]} { + continue + } + if { $gcc_output == "" } { + set gcc_output "$line" + } else { + set gcc_output "$gcc_output\n$line" + } + } + } + + # Verify that COMPILER_PATTERRNS appear in gcc output. + foreach pattern [split $compiler_patterns "\n"] { + if {$pattern != ""} { + if {[regexp -line -- "$pattern" $gcc_output]} { + pass "$test $pattern" + } else { + if {$expected_failure != ""} { + xfail "$test \"$pattern\" present in output" + } else { + fail "$test \"$pattern\" present in output" + } + } + } + } + + # Verify that COMPILER_NON_PATTERRNS do not appear in gcc output. + foreach pattern [split $compiler_non_patterns "\n"] { + if {$pattern != ""} { + if {![regexp -line -- "$pattern" $gcc_output result]} { + pass "$test $pattern" + } else { + if {$expected_failure != ""} { + xfail "$test \"$pattern\" absent from output" + } else { + # Print the unexpected line that caused the failure + # to make it easier to find in the multiline output. + fail "$test \"$pattern\" absent from output: \"$result\"" + } + } + } + } +} + +# As check_for_options_with_filter, but without the EXCLUDE parameter. + +proc check_for_options { language gcc_options compiler_patterns \ + compiler_non_patterns expected_failure } { + check_for_options_with_filter $language $gcc_options "" $compiler_patterns \ + $compiler_non_patterns $expected_failure +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/plugin-support.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/plugin-support.exp new file mode 100644 index 0000000000000000000000000000000000000000..b37db3c1d2cfc5d30970fd957ea7ed95e5a438e8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/plugin-support.exp @@ -0,0 +1,132 @@ +# Copyright (C) 2009-2020 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 +# . +# + +# This file contains the support procedures for testing the plugin mechanism. + +load_lib dg.exp +load_lib gcc.exp + +# +# plugin-get-options -- process test directives +# +# SRC is the full pathname of the plugin source file. +# +proc plugin-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "plugin.exp does not support $cmd" + } + } + + # Return flags to use for compiling the plugin source file + return ${dg-extra-tool-flags} +} + +# +# plugin-test-execute -- build the plugin first and then compile the +# test files with the plugin. +# +# PLUGIN_SRC is the full pathname of the plugin source file. +# PLUGIN_TESTS is a list of input test source files. +# +proc plugin-test-execute { plugin_src plugin_tests } { + global srcdir objdir + global verbose + global GMPINC + global PLUGINCC + global PLUGINCFLAGS + + set basename [file tail $plugin_src] + set base [file rootname $basename] + set plugin_lib $base.so + + set testcase [dg-trim-dirname $srcdir $plugin_src] + verbose "Test the plugin $testcase" 1 + + # Build the plugin itself + set extra_flags [plugin-get-options $plugin_src] + + # Note that the plugin test support currently only works when the GCC + # build tree is available. (We make sure that is the case in plugin.exp.) + # Once we have figured out how/where to package/install GCC header files + # for general plugin support, we should modify the following include paths + # accordingly. + set gcc_srcdir "$srcdir/../.." + set gcc_objdir "$objdir/../../.." + set includes "-I. -I${srcdir} -I${gcc_srcdir}/gcc -I${gcc_objdir}/gcc \ + -I${gcc_srcdir}/include -I${gcc_srcdir}/libcpp/include \ + $GMPINC -I${gcc_objdir}/intl" + + if { [ ishost *-*-darwin* ] } { + # -mdynamic-no-pic is incompatible with -fPIC. + set plug_cflags "" + foreach op $PLUGINCFLAGS { + if { [string compare "-mdynamic-no-pic" $op] } { + set plug_cflags [concat $plug_cflags " $op"] + } + } + set optstr "$includes" + foreach op $extra_flags { + if { [string compare "-mdynamic-no-pic" $op] } { + set optstr [concat $optstr " $op"] + } + } + set optstr [concat $optstr "-DIN_GCC -fPIC -shared -fno-rtti -undefined dynamic_lookup"] + } else { + set plug_cflags $PLUGINCFLAGS + set optstr "$includes $extra_flags -DIN_GCC -fPIC -shared -fno-rtti" + } + + # Temporarily switch to the environment for the plugin compiler. + restore_ld_library_path_env_vars + set status [remote_exec build "$PLUGINCC $plug_cflags $plugin_src $optstr -o $plugin_lib"] + set status [lindex $status 0] + set_ld_library_path_env_vars + + if { $status != 0 } then { + fail "$testcase compilation" + # Strictly, this is wrong: the tests compiled with the plugin should + # become unresolved instead. + return + } else { + pass "$testcase compilation" + } + + # Compile the input source files with the plugin + global default_flags + set plugin_enabling_flags "-fplugin=./$plugin_lib" + dg-runtest $plugin_tests $plugin_enabling_flags $default_flags + + # Clean up + remote_file build delete $plugin_lib +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/profopt.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/profopt.exp new file mode 100644 index 0000000000000000000000000000000000000000..0b853a1559fdf059a54eaae52f27f3b8e4a84133 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/profopt.exp @@ -0,0 +1,602 @@ +# Copyright (C) 2001-2020 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 +# . +# +# This script was submitted by Janis Johnson . + +# Test the functionality and optionally, performance improvement, of +# programs compiled with profile-directed optimizations. Compile and +# run a test with profile options, compile it with options using the +# profile feedback, and then run the test again. Optionally compile +# and run a third time without the profile-directed optimization and +# compare timing results of the program with normal optimization and +# with the profile-directed optimization. Each test is run using +# multiple sets of optimization and/or code generation options in +# addition to the profiling and feedback options. + +# If perf_ext is defined and the performance value for the +# profile-directed test run is nonzero then the performance check will +# be done. + +load_lib dg.exp +load_lib gcc-dg.exp + +global PROFOPT_OPTIONS perf_delta + +# The including .exp file must define these. +global tool profile_option feedback_option prof_ext profile_wrapper +if ![info exists tool] { + error "Tools is not specified." +} +if ![info exists prof_ext] { + error "No profile data file extensions specified." +} + +# The maximum perforance degradation can be defined in the including file. +if ![info exists perf_delta] { + set perf_delta 4 +} + +# The default option list can be overridden by +# PROFOPT_OPTIONS="{ { list1 } ... { list2 } }" + +if ![info exists PROFOPT_OPTIONS] { + set PROFOPT_OPTIONS [list \ + { -g } \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O3 } \ + { -O3 -g } \ + { -Os } ] +} + +# +# profopt-cleanup -- remove profiling or performance results files. +# +# TESTCASE is the name of the test +# EXT is the extensions of files to remove +# +proc profopt-cleanup { testcase extlist } { + set basename [file tail $testcase] + set base [file rootname $basename] + foreach ext $extlist { + set files [glob -nocomplain $base.$ext] + if { $files != "" } { + eval "remote_file build delete $files" + } + } +} + +# +# profopt-target-cleanup -- remove profiling result files. +# +# DIR is the name of the directory +# TESTCASE is the name of the test +# EXT is the extensions of files to remove +# +proc profopt-target-cleanup { dir testcase ext } { + global additional_sources_used + set basename [file tail $testcase] + set base [file rootname $basename] + set file "$dir/$base.$ext" + eval "remote_file target delete $file" + + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + set basename [file tail $srcfile] + set base [file rootname $basename] + set file "$dir/$base.$ext" + eval "remote_file target delete $file" + } + } +} + +# +# profopt-perf-value -- get performance value for a test +# +# TESTCASE is the name of the test +# PERF_EXT is the extension of the performance result file +# OPTSTR is the string of compiler options +# +proc profopt-perf-value { testcase perf_ext optstr } { + set basename [file tail $testcase] + set base [file rootname $basename] + set files [glob -nocomplain $base.$perf_ext] + # The file doesn't exist; let the caller decide if that's a problem. + if { $files == "" } { + return -2 + } + remote_upload host $base.$perf_ext $base.$perf_ext + set fd [open $base.$perf_ext r] + gets $fd line + set val -2 + if [regexp "TIME" $line] { + if [regexp "TIME -1" $line] { + fail "$testcase perf check: no consistent time available, $optstr" + set val -1 + } elseif ![regexp "(\[0-9\]+)" "$line" val] { + set val -2 + } + } + # Report problems with an existing file. + if { $val == -2 } { + fail "$testcase perf check: file $base.$perf_ext has wrong format, $optstr" + } + close $fd + profopt-cleanup $testcase $perf_ext + return $val +} + +# +# dg-final-generate -- process code to run after the profile-generate step +# +# ARGS is the line number of the directive followed by the commands. +# +proc dg-final-generate { args } { + global generate_final_code + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + append generate_final_code "[lindex $args 1]\n" +} + +# +# dg-final-use -- process code to run after the profile-use step +# +# ARGS is the line number of the directive followed by the commands. +# +proc dg-final-use { args } { + global use_final_code + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + append use_final_code "[lindex $args 1]\n" +} + +# +# dg-final-use-not-autofdo -- process code to run after the profile-use step +# but only if not running autofdo +# ARGS is the line number of the directive followed by the commands. +# +proc dg-final-use-not-autofdo { args } { + global use_final_code + global run_autofdo + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + + if { $run_autofdo == 1 } { + return + } + append use_final_code "[lindex $args 1]\n" +} + +# +# dg-final-use-autofdo -- process code to run after the profile-use step +# but only if running autofdo +# ARGS is the line number of the directive followed by the commands. +# + +proc dg-final-use-autofdo { args } { + global use_final_code + global run_autofdo + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + + if { $run_autofdo != 1 } { + return + } + append use_final_code "[lindex $args 1]\n" +} + +# +# profopt-final-code -- run final code +# +# WHICH is "generate" or "use". +# FINAL_CODE is the TCL code to run. +# TESTCASE is the name of the test, for error messages. +# +proc profopt-final-code { which final_code name } { + # This is copied from dg-test in dg.exp of DejaGnu. + regsub -all "\\\\(\[{}\])" $final_code "\\1" final_code + proc profopt-final-proc { args } $final_code + if [catch "profopt-final-proc $name" errmsg] { + perror "$name: error executing dg-final-${which}: $errmsg" + unresolved "$name: Error executing dg-final-${which}: $errmsg" + } +} + +# +# profopt-get-options -- process test directives +# +# SRC is the full pathname of the testcase. +# +proc profopt-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + + # current_compiler_flags reads tool_flags from the same stack frame + # as dg-extra-tool-flags + set tool_flags "" + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || ![string compare "dg-additional-options" $cmd] \ + || ![string compare "dg-add-options" $cmd] \ + || ![string compare "dg-skip-if" $cmd] \ + || ![string compare "dg-final-generate" $cmd] \ + || ![string compare "dg-final-use" $cmd] \ + || ![string compare "dg-final-use-not-autofdo" $cmd] \ + || ![string compare "dg-final-use-autofdo" $cmd] \ + || ![string compare "dg-additional-sources" $cmd] \ + || [string match "dg-require-*" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "$src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "profopt.exp does not support $cmd" + } + } + + # Return flags to use for compiling the primary source file and for + # linking. + return ${dg-extra-tool-flags} +} + +# auto-profopt-execute -- Compile for auto profiling and then feedback, +# then normal. SRC is the full path name of the testcase. +proc auto-profopt-execute { src } { + global profile_wrapper + global profile_option + global feedback_option + global run_autofdo + global srcdir + + if { ! [check_profiling_available "-fauto-profile"] } { + regsub "(?q)$srcdir/" $src "" testcase + unsupported "$testcase -fauto-profile" + return + } + set profile_wrapper [profopt-perf-wrapper] + set profile_option "-g" + set feedback_option "-fauto-profile" + set run_autofdo 1 + profopt-execute $src + unset profile_wrapper + unset profile_option + unset feedback_option + unset run_autofdo +} + +# +# c-prof-execute -- compile for profiling and then feedback, then normal +# +# SRC is the full pathname of the testcase. +# +proc profopt-execute { src } { + global srcdir tmpdir + global PROFOPT_OPTIONS + global tool profile_option feedback_option prof_ext perf_ext perf_delta + global profile_wrapper run_autofdo ld_library_path + global generate_final_code use_final_code + global verbose + global testname_with_flags + + if ![info exists profile_option] { + error "No profile option specified for first compile." + } + if ![info exists feedback_option] { + error "No feedback option specified for second compile." + } + if ![info exists profile_wrapper] { + set profile_wrapper "" + } + if ![info exists run_autofdo] { + set run_autofdo "" + } + + # Use the default option list or one defined for a set of tests. + if ![info exists PROFOPT_OPTIONS] { + error "PROFOPT_OPTIONS is not defined" + } + set prof_option_list $PROFOPT_OPTIONS + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + # Several procedures access the name of the test with torture flags, + # normally defined in dg-test. Profile optimization tests don't + # use dg-test, so define it here to make it accessible via + # testname-for-summary. + set testname_with_flags $testcase + + set executable $tmpdir/[file tail [file rootname $src].x] + set basename [file tail $testcase] + set base [file rootname $basename] + + set count 0 + foreach option $prof_option_list { + set execname1 "${executable}${count}1" + set execname2 "${executable}${count}2" + set execname3 "${executable}${count}3" + incr count + + remote_file build delete $execname1 + remote_file build delete $execname2 + remote_file build delete $execname3 + verbose "Testing $testcase, $option" 1 + + # Remove old performance data files. + if [info exists perf_ext] { + profopt-cleanup $testcase $perf_ext + } + + # Process test directives. + + set generate_final_code "" + set use_final_code "" + set dg-do-what [list "run" "" P] + set extra_flags [profopt-get-options $src] + if { [lindex ${dg-do-what} 1 ] == "N" } { + unsupported "$testcase" + unset testname_with_flags + verbose "$src not supported on this target, skipping it" 3 + return + } + + # schedule removal of dump files et al + # Do this before the call below destroys additional_sources.. + append use_final_code [schedule-cleanups "$option $extra_flags"] + set extra_options [dg-additional-files-options "" "$src"] + + # Remove old profiling data files. Make sure additional_sources_used is + # valid, by running it after dg-additional-files-options. + foreach ext $prof_ext { + profopt-target-cleanup $tmpdir $base $ext + profopt-target-cleanup $tmpdir $base "perf.data" + } + + # Tree profiling requires TLS runtime support, which may need + # additional flags. + if { [string first "-fprofile-generate" $profile_option] >= 0 } { + set extra_flags [add_options_for_tls $extra_flags] + } + + # Compile for profiling. + + set options "$extra_options" + lappend options "additional_flags=$option $extra_flags $profile_option" + set optstr "$option $profile_option" + set comp_output [${tool}_target_compile "$src" "$execname1" executable $options] + if ![${tool}_check_compile "$testcase compilation" $optstr $execname1 $comp_output] { + unresolved "$testcase execution, $optstr" + unresolved "$testcase compilation, $option $feedback_option" + unresolved "$testcase execution, $option $feedback_option" + continue + } + + # Run the profiled test. + if { $run_autofdo == 1 } { + if { ![info exists ld_library_path]} { + set ld_library_path "" + } + set orig_ld_library_path "[getenv LD_LIBRARY_PATH]" + setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" + verbose -log "Running $profile_wrapper -o $tmpdir/$base.perf.data $execname1" + set id [remote_spawn "" "$profile_wrapper -o $tmpdir/$base.perf.data $execname1" "readonly"] + setenv LD_LIBRARY_PATH $orig_ld_library_path + if { $id < 0 } { + warning "Failed to run profiler" + set status "fail" + } else { + set result [remote_wait "" 300] + set status [lindex $result 0] + verbose "perf result $result" + if { $status == 0 } { + set status "pass" + } else { + set status "fail" + } + } + } else { + set result [${tool}_load $execname1 "" ""] + set status [lindex $result 0] + } + + set missing_file 0 + set bprefix "" + # Make sure the profile data was generated, and fail if not. + if { $status == "pass" } { + # convert profile + if { $run_autofdo == 1 } { + set bprefix "afdo." + set cmd "create_gcov --binary $execname1 --profile=$tmpdir/$base.perf.data -gcov_version=1 --gcov=$tmpdir/$bprefix$base.$ext" + verbose "Running $cmd" + set id [remote_spawn "" $cmd] + if { $id < 0 } { + unsupported "$testcase -fauto-profile: cannot run create_gcov" + set status "fail" + return + } + set status [remote_wait "" 300] + set status "pass" + } + + foreach ext $prof_ext { + remote_upload target $tmpdir/$bprefix$base.$ext + set files [glob -nocomplain $bprefix$base.$ext] + if { $files == "" } { + set status "fail" + set missing_file 1 + fail "$testcase execution: file $bprefix$base.$ext does not exist, $option $profile_option" + } + } + } + if { $missing_file == 0 } { + $status "$testcase execution, $optstr" + } + + # If there is dg-final code to execute for the generate step, do it + # even if it failed; it might clean up temporary files. + if ![string match $generate_final_code ""] { + profopt-final-code "generate" $generate_final_code $testcase + } + + remote_file build delete $execname1 + + # Quit for this round if it failed + if { $status != "pass" } { + unresolved "$testcase compilation, $option $feedback_option" + unresolved "$testcase execution, $option $feedback_option" + continue + } + + # Compile with feedback-directed optimizations. + + set options "$extra_options" + lappend options "additional_flags=$option $extra_flags $feedback_option" + set optstr "$option $feedback_option" + if { [string first "-fauto-profile" $options] >= 0} { + set options [regsub -- "-fauto-profile" $options "-fauto-profile=$tmpdir/$bprefix$base.$ext"] + } + + set comp_output [${tool}_target_compile "$src" "$execname2" "executable" $options] + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + if ![${tool}_check_compile "$testcase compilation" $optstr $execname2 $comp_output] { + unresolved "$testcase execution, $optstr" + continue + } + + # Run the profile-directed optimized test. + + set result [${tool}_load "$execname2" "" ""] + set status [lindex $result 0] + $status "$testcase execution, $optstr" + + # If there is dg-final code to execute for the use step, do it. + if ![string match $use_final_code ""] { + profopt-final-code "use" $use_final_code $testcase + } + + # Remove the profiling data files. + foreach ext $prof_ext { + profopt-target-cleanup $tmpdir "$bprefix$base" $ext + profopt-target-cleanup $tmpdir $base "perf.data" + profopt-target-cleanup $tmpdir $base "gcda.imports" + } + + if { $status != "pass" } { + continue + } + + # If the test is not expected to produce performance data then + # we're done now. + if ![info exists perf_ext] { + remote_file build delete $execname2 + continue + } + + # Get the performance data from the test built with + # profile-directed optimization. If the file doesn't exist or if + # the value is zero, skip the performance comparison. + set val2 [profopt-perf-value $testcase $perf_ext $optstr] + if { $val2 <= 0 } { + remote_file build delete $execname2 + continue + } + + # Compile with normal optimizations. + + set options "$extra_options" + lappend options "additional_flags=$option" + set optstr "$option" + set comp_output [${tool}_target_compile "$src" "$execname3" "executable" $options] + if ![${tool}_check_compile "$testcase compilation" $optstr $execname3 $comp_output] { + unresolved "$testcase execution, $optstr" + unresolved "$testcase perf check, $optstr" + continue + } + + # Run the test with normal optimizations. + + set result [${tool}_load "$execname3" "" ""] + set status [lindex $result 0] + $status "$testcase execution, $optstr" + if { $status != "pass" } { + unresolved "$testcase perf check, $optstr" + continue + } + + # Get the performance data from the test built with normal + # optimization. + set val1 [profopt-perf-value $testcase $perf_ext $optstr] + if { $val1 < 0 } { + if { $val1 == -2 } { + # The data file existed with the profile-directed + # optimization so this one should, too. + fail "$testcase perf check: file $base.$perf_ext does not exist, $optstr" + } + continue + } + + # Compare results of the two runs and fail if the time with the + # profile-directed optimization is significantly more than the time + # without it. + set status "pass" + if { $val2 > $val1 } { + # Check for a performance degration outside of allowable limits. + if { [expr $val2 - $val1] > [expr [expr $val1 * $perf_delta] / 100] } { + set status "fail" + } + } + if { $status == "fail" } { + fail "$testcase perf check: orig: $val1 new: $val2, $optstr" + } else { + $status "$testcase perf check, $optstr" + verbose "$testcase orig: $val1 new: $val2, $optstr" 2 + remote_file build delete $execname2 + remote_file build delete $execname3 + } + } + unset testname_with_flags +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/prune.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/prune.exp new file mode 100644 index 0000000000000000000000000000000000000000..eea4bf383a7844f4a28a30d1311e3b1bfd89469e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/prune.exp @@ -0,0 +1,127 @@ +# Copyright (C) 1997-2020 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 +# . + +# Prune messages from gcc that aren't useful. + +load_lib multiline.exp + +if ![info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "" +} +set TEST_ALWAYS_FLAGS "-fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never -fdiagnostics-urls=never $TEST_ALWAYS_FLAGS" + +proc prune_gcc_output { text } { + global srcdir + + #send_user "Before:$text\n" + + # Handle any freeform regexps. + set text [handle-dg-regexps $text] + + regsub -all "(^|\n)(\[^\n\]*: \[iI\]|I)n ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|substitution|program|subroutine|block-data)\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: (recursively )?required \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: in .constexpr. expansion \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: in requirements \[^\n\]*" $text "" text + regsub -all "(^|\n) inlined from \[^\n\]*" $text "" text + regsub -all "(^|\n)collect2: error: ld returned \[^\n\]*" $text "" text + regsub -all "(^|\n)collect: re(compiling|linking)\[^\n\]*" $text "" text + regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text + regsub -all "(^|\n)\[0-9\]\[0-9\]* errors\." $text "" text + regsub -all "(^|\n)(In file included|\[ \]+from)\[^\n\]*" $text "" text + + # Ignore informational notes. + regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text + + # Ignore harmless -fpic warnings. + regsub -all "(^|\n)\[^\n\]*: warning: -f(pic|PIC) ignored for target\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: warning: -f(pic|PIC)( and -fpic are| is)? not supported\[^\n\]*" $text "" text + + # Ignore errata warning from IA64 assembler. + regsub -all "(^|\n)\[^\n\]*: Additional NOP may be necessary to workaround Itanium processor A/B step errata" $text "" text + regsub -all "(^|\n)\[^\n*\]*: Assembler messages:\[^\n\]*" $text "" text + + # Ignore harmless VTA note. + regsub -all "(^|\n)\[^\n\]*: note: variable tracking size limit exceeded with -fvar-tracking-assignments, retrying without\[^\n\]*" $text "" text + + # It would be nice to avoid passing anything to gcc that would cause it to + # issue these messages (since ignoring them seems like a hack on our part), + # but that's too difficult in the general case. For example, sometimes + # you need to use -B to point gcc at crt0.o, but there are some targets + # that don't have crt0.o. + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text + + # Ignore harmless warnings from Xcode 3.2.x. + regsub -all "(^|\n)\[^\n\]*ld: warning: can't add line info to anonymous symbol\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*warning: DWARFDebugInfoEntry::AppendDependants\[^\n\]*AT_\[^\n\]*FORM_ref4\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*warning:\[^\n\]*TAG_variable: AT_location\[^\n\]*didn't have valid function low pc\[^\n\]*" $text "" text + + # Ignore harmless warnings from Xcode 4.0. + regsub -all "(^|\n)\[^\n\]*ld: warning: could not create compact unwind for\[^\n\]*" $text "" text + + # If dg-enable-nn-line-numbers was provided, then obscure source-margin + # line numbers by converting them to "NN" form. + set text [maybe-handle-nn-line-numbers $text] + + # Call into multiline.exp to handle any multiline output directives. + set text [handle-multiline-outputs $text] + + #send_user "After:$text\n" + + return $text +} + +# escape metacharacters in literal string, so it can be used in regex + +proc escape_regex_chars { line } { + return [string map {"^" "\\^" + "$" "\\$" + "(" "\\(" + ")" "\\)" + "[" "\\[" + "]" "\\]" + "{" "\\{" + "}" "\\}" + "." "\\." + "\\" "\\\\" + "?" "\\?" + "+" "\\+" + "*" "\\*" + "|" "\\|"} $line] +} + +proc prune_file_path { text } { + global srcdir + + set safedir [escape_regex_chars $srcdir] + regsub -all "$safedir\/" $text "" text + + # Truncate absolute file path into relative path. + set topdir "[file dirname [file dirname [file dirname $safedir]]]" + regsub -all "$topdir\/" $text "" text + + return $text +} + +# Provide a definition of this if missing (delete after next dejagnu release). + +if { [info procs prune_warnings] == "" } then { + proc prune_warnings { text } { + return $text + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanasm.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanasm.exp new file mode 100644 index 0000000000000000000000000000000000000000..d5f2be47d2f7f423011adde68caf579416bdacfc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanasm.exp @@ -0,0 +1,742 @@ +# Copyright (C) 2000-2020 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 +# . + +# Various utilities for scanning assembler output, used by gcc-dg.exp and +# g++-dg.exp. + +# Utility for scanning compiler result, invoked via dg-final. + +# Transform newline and similar characters into their escaped form. +proc make_pattern_printable { pattern } { + return [string map {\t \\t \n \\n \r \\r \\ \\\\} $pattern] +} + +# Scan the OUTPUT_FILE for a pattern. If it is present and POSITIVE +# is non-zero, or it is not present and POSITIVE is zero, the test +# passes. The ORIG_ARGS is the list of arguments provided by dg-final +# to scan-assembler. The first element in ORIG_ARGS is the regular +# expression to look for in the file. The second element, if present, +# is a DejaGNU target selector. + +proc dg-scan { name positive testcase output_file orig_args } { + if { [llength $orig_args] < 1 } { + error "$name: too few arguments" + return + } + if { [llength $orig_args] > 2 } { + error "$name: too many arguments" + return + } + if { [llength $orig_args] >= 2 } { + switch [dg-process-target [lindex $orig_args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set pattern [lindex $orig_args 0] + set printable_pattern [make_pattern_printable $pattern] + + if { [is_remote host] } { + remote_upload host "$output_file" + } + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase $name $printable_pattern" + return + } + set fd [open $output_file r] + set text [read $fd] + close $fd + + set match [regexp -- $pattern $text] + if { $match == $positive } { + pass "$testcase $name $printable_pattern" + } else { + fail "$testcase $name $printable_pattern" + } +} + +# Look for a pattern in the .s file produced by the compiler. See +# dg-scan for details. + +proc scan-assembler { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + dg-scan "scan-assembler" 1 $testcase $output_file $args +} + +force_conventional_output_for scan-assembler + +# Check that a pattern is not present in the .s file produced by the +# compiler. See dg-scan for details. + +proc scan-assembler-not { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + + dg-scan "scan-assembler-not" 0 $testcase $output_file $args +} + +force_conventional_output_for scan-assembler-not + +# Return the scan for the assembly for hidden visibility. + +proc hidden-scan-for { symbol } { + + set objformat [gcc_target_object_format] + + switch $objformat { + coff { return "$symbol\[,\d\]*hidden" } + elf { return "hidden\[ \t_\]*$symbol" } + mach-o { return "private_extern\[ \t_\]*_?$symbol" } + default { return "" } + } + +} + + +# Check that a symbol is defined as a hidden symbol in the .s file +# produced by the compiler. + +proc scan-hidden { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + + if { [llength $args] > 0 } { + set symbol [lindex $args 0] + + set hidden_scan [hidden-scan-for $symbol] + + set args [lreplace $args 0 0 "$hidden_scan"] + } + + dg-scan "scan-hidden" 1 $testcase $output_file $args +} + +# Check that a symbol is not defined as a hidden symbol in the .s file +# produced by the compiler. + +proc scan-not-hidden { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + + if { [llength $args] > 0 } { + set symbol [lindex $args 0] + set hidden_scan [hidden-scan-for $symbol] + + set args [lreplace $args 0 0 "$hidden_scan"] + } + + dg-scan "scan-not-hidden" 0 $testcase $output_file $args +} + +# Look for a pattern in OUTPUT_FILE. See dg-scan for details. + +proc scan-file { output_file args } { + set testcase [testname-for-summary] + dg-scan "scan-file" 1 $testcase $output_file $args +} + +# Check that a pattern is not present in the OUTPUT_FILE. See dg-scan +# for details. + +proc scan-file-not { output_file args } { + set testcase [testname-for-summary] + dg-scan "scan-file-not" 0 $testcase $output_file $args +} + +# Look for a pattern in the .su file produced by the compiler. See +# dg-scan for details. + +proc scan-stack-usage { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].su" + + dg-scan "scan-stack-usage" 1 $testcase $output_file $args +} + +# Check that a pattern is not present in the .su file produced by the +# compiler. See dg-scan for details. + +proc scan-stack-usage-not { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].su" + + dg-scan "scan-stack-usage-not" 0 $testcase $output_file $args +} + +# Return the filename of the Ada spec corresponding to the argument. + +proc get_ada_spec_filename { testcase } { + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set tailname [file tail $filename] + set extension [string trimleft [file extension $tailname] {.}] + regsub -all {\-} [file rootname $tailname] {_} rootname + + return [string tolower "${rootname}_${extension}.ads"] +} + +# Look for a pattern in the .ads file produced by the compiler. See +# dg-scan for details. + +proc scan-ada-spec { args } { + set testcase [testname-for-summary] + set output_file "[get_ada_spec_filename $testcase]" + + dg-scan "scan-ada-spec" 1 $testcase $output_file $args +} + +# Check that a pattern is not present in the .ads file produced by the +# compiler. See dg-scan for details. + +proc scan-ada-spec-not { args } { + set testcase [testname-for-summary] + set output_file "[get_ada_spec_filename $testcase]" + + dg-scan "scan-ada-spec-not" 0 $testcase $output_file $args +} + +# Call pass if pattern is present given number of times, otherwise fail. +proc scan-assembler-times { args } { + if { [llength $args] < 2 } { + error "scan-assembler-times: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-assembler-times: too many arguments" + return + } + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set pattern [lindex $args 0] + set times [lindex $args 1] + set pp_pattern [make_pattern_printable $pattern] + + # This must match the rule in gcc-dg.exp. + set output_file "[file rootname [file tail $filename]].s" + + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase scan-assembler-times $pp_pattern $times" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + set result_count [llength [regexp -inline -all -- $pattern $text]] + if {$result_count == $times} { + pass "$testcase scan-assembler-times $pp_pattern $times" + } else { + verbose -log "$testcase: $pp_pattern found $result_count times" + fail "$testcase scan-assembler-times $pp_pattern $times" + } +} + +force_conventional_output_for scan-assembler-times + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +proc scan-assembler-dem { args } { + global cxxfilt + global base_dir + + if { [llength $args] < 1 } { + error "scan-assembler-dem: too few arguments" + return + } + if { [llength $args] > 2 } { + error "scan-assembler-dem: too many arguments" + return + } + if { [llength $args] >= 2 } { + switch [dg-process-target [lindex $args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set pattern [lindex $args 0] + set pp_pattern [make_pattern_printable $pattern] + set output_file "[file rootname [file tail $filename]].s" + + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase scan-assembler-dem $pp_pattern" + return + } + + set output [remote_exec host "$cxxfilt" "" "$output_file"] + set text [lindex $output 1] + + if [regexp -- $pattern $text] { + pass "$testcase scan-assembler-dem $pp_pattern" + } else { + fail "$testcase scan-assembler-dem $pp_pattern" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +proc scan-assembler-dem-not { args } { + global cxxfilt + global base_dir + + if { [llength $args] < 1 } { + error "scan-assembler-dem-not: too few arguments" + return + } + if { [llength $args] > 2 } { + error "scan-assembler-dem-not: too many arguments" + return + } + if { [llength $args] >= 2 } { + switch [dg-process-target [lindex $args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set pattern [lindex $args 0] + set pp_pattern [make_pattern_printable $pattern] + set output_file "[file rootname [file tail $filename]].s" + + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase scan-assembler-dem-not $pp_pattern" + return + } + + set output [remote_exec host "$cxxfilt" "" "$output_file"] + set text [lindex $output 1] + + if ![regexp -- $pattern $text] { + pass "$testcase scan-assembler-dem-not $pp_pattern" + } else { + fail "$testcase scan-assembler-dem-not $pp_pattern" + } +} + +# Call pass if object size is ok, otherwise fail. +# example: /* { dg-final { object-size text <= 54 } } */ +proc object-size { args } { + global size + global base_dir + + if { [llength $args] < 3 } { + error "object-size: too few arguments" + return + } + if { [llength $args] > 4 } { + error "object-size: too many arguments" + return + } + if { [llength $args] >= 4 } { + switch [dg-process-target [lindex $args 3]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find size like we find g++ in g++.exp. + if ![info exists size] { + set size [findfile $base_dir/../../../binutils/size \ + $base_dir/../../../binutils/size \ + [findfile $base_dir/../../size $base_dir/../../size \ + [findfile $base_dir/size $base_dir/size \ + [transform size]]]] + verbose -log "size is $size" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set what [lindex $args 0] + set where [lsearch { text data bss total } $what] + if { $where == -1 } { + error "object-size: illegal argument: $what" + return + } + set cmp [lindex $args 1] + if { [lsearch { < > <= >= == != } $cmp] == -1 } { + error "object-size: illegal argument: $cmp" + return + } + set with [lindex $args 2] + if ![string is integer $with ] { + error "object-size: illegal argument: $with" + return + } + + set output_file "[file rootname [file tail $filename]].o" + if ![file_on_host exists $output_file] { + verbose -log "$testcase: $output_file does not exist" + unresolved "$testcase object-size $what $cmp $with" + return + } + set output [remote_exec host "$size" "$output_file"] + set status [lindex $output 0] + if { $status != 0 } { + verbose -log "$testcase object-size: $size failed" + unresolved "$testcase object-size $what $cmp $with" + return + } + + set text [lindex $output 1] + set lines [split $text "\n"] + + set l0match {^\s*text\s+data\s+bss\s+dec\s+hex\s+filename\s*$} + set l1match {^\s*\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+} + + if { [istarget *-*-darwin*] } { + set l0match {^\s*__TEXT\s+__DATA\s+__OBJC\s+others\s+dec\s+hex\s*$} + set l1match {^\s*\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+} + } + + set line0 [lindex $lines 0] + if ![regexp $l0match $line0] { + verbose -log "$testcase object-size: $size did not produce expected first line: $line0" + unresolved "$testcase object-size $what $cmp $with" + return + } + + set line1 [lindex $lines 1] + if ![regexp $l1match $line1] { + verbose -log "$testcase object-size: $size did not produce expected second line: $line1" + unresolved "$testcase object-size $what $cmp $with" + return + } + + set actual [lindex $line1 $where] + verbose -log "$what size is $actual" + + if [expr $actual $cmp $with] { + pass "$testcase object-size $what $cmp $with" + } else { + fail "$testcase object-size $what $cmp $with" + } +} + +# Utility for testing that a function is defined on the current line. +# Call pass if so, otherwise fail. Invoked directly; the file must +# have been compiled with -g -dA. +# +# Argument 0 is the current line, passed implicitly by dejagnu +# Argument 1 is the function to check +# Argument 2 handles expected failures and the like +# Argument 3 is "." to match the current line, or an integer to match +# an explicit line. +proc dg-function-on-line { args } { + # Upvar from dg-final: + upvar dg-final-code final-code + + set line [lindex $args 0] + set symbol [lindex $args 1] + set failures [lindex $args 2] + + if { [llength $args] >= 4 } { + switch [lindex $args 3] { + "." { } + "default" { set line [lindex $args 3] } + } + } + + if { [istarget hppa*-*-linux*] } { + set pattern [format {%s:\n\t.PROC\n\t.CALLINFO.*\n\t.ENTRY\n.L.*:\n(\t.file[^\t]*)*\t[^:]+:%d(:[0-9]+)?\n} \ + $symbol $line] + } elseif { [istarget hppa*-*-*] } { + set pattern [format {\t;[^:]+:%d(:[0-9]+)?\n(\t[^\t]+\n)+%s:\n\t.PROC} \ + $line $symbol] + } elseif { [istarget mips*-*-*] } { + set pattern [format {\t\.loc [0-9]+ %d [0-9]+( [^\n]*)?\n(\t.cfi_startproc[^\t]*\n)*\t\.set\t(no)?mips16\n\t(\.set\t(no)?micromips\n\t)?\.ent\t%s\n\t\.type\t%s, @function\n%s:\n} \ + $line $symbol $symbol $symbol] + } elseif { [istarget microblaze*-*-*] } { + set pattern [format {:%d(:[0-9]+)?\n\$.*:\n\t\.ent\t%s\n\t\.type\t%s, @function\n%s:\n} \ + $line $symbol $symbol $symbol] + } else { + set pattern [format {%s:[^\t]*(\t.(fnstart|frame|mask|file)[^\t]*)*\t[^:]+:%d(:[0-9]+)?\n} \ + $symbol $line] + } + + # The lack of spaces around $pattern is important, since they'd + # become part of the regex scan-assembler tries to match. + set cmd "scan-assembler {$pattern}" + if { [llength $args] >= 3 } { + set cmd "$cmd {$failures}" + } + + append final-code "$cmd\n" +} + +# Look for a pattern in the .exe.ltrans0.s file produced by the +# compiler. See dg-scan for details. + +proc scan-lto-assembler { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].exe.ltrans0.s" + verbose "output_file: $output_file" + dg-scan "scan-lto-assembler" 1 $testcase $output_file $args +} + +# Read assembly file FILENAME and store a mapping from function names +# to function bodies in array RESULT. FILENAME has already been uploaded +# locally where necessary and is known to exist. + +proc parse_function_bodies { filename result } { + upvar $result up_result + + # Regexp for the start of a function definition (name in \1). + set label {^([a-zA-Z_]\S+):$} + + # Regexp for the end of a function definition. + set terminator {^\s*\.size} + + # Regexp for lines that aren't interesting. + set fluff {^\s*(?:\.|//|@)} + + set fd [open $filename r] + set in_function 0 + while { [gets $fd line] >= 0 } { + if { [regexp $label $line dummy function_name] } { + set in_function 1 + set function_body "" + } elseif { $in_function } { + if { [regexp $terminator $line] } { + set up_result($function_name) $function_body + set in_function 0 + } elseif { ![regexp $fluff $line] } { + append function_body $line "\n" + } + } + } + close $fd +} + +# FUNCTIONS is an array that maps function names to function bodies. +# Return true if it contains a definition of function NAME and if +# that definition matches BODY_REGEXP. + +proc check_function_body { functions name body_regexp } { + upvar $functions up_functions + + if { ![info exists up_functions($name)] } { + return 0 + } + return [regexp "^$body_regexp\$" $up_functions($name)] +} + +# Check the implementations of functions against expected output. Used as: +# +# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR]] } } +# +# See sourcebuild.texi for details. + +proc check-function-bodies { args } { + if { [llength $args] < 2 } { + error "too few arguments to check-function-bodies" + } + if { [llength $args] > 4 } { + error "too many arguments to check-function-bodies" + } + + if { [llength $args] >= 3 } { + set required_flags [lindex $args 2] + + upvar 2 dg-extra-tool-flags extra_tool_flags + set flags $extra_tool_flags + + global torture_current_flags + if { [info exists torture_current_flags] } { + append flags " " $torture_current_flags + } + foreach required_flag $required_flags { + switch -- $required_flag { + target - + xfail { + error "misplaced $required_flag in check-function-bodies" + } + } + } + foreach required_flag $required_flags { + if { ![regexp " $required_flag " $flags] } { + return + } + } + } + + set xfail_all 0 + if { [llength $args] >= 4 } { + switch [dg-process-target [lindex $args 3]] { + "S" { } + "N" { return } + "F" { set xfail_all 1 } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + + global srcdir + set input_filename "$srcdir/$filename" + set output_filename "[file rootname [file tail $filename]].s" + + set prefix [lindex $args 0] + set prefix_len [string length $prefix] + set terminator [lindex $args 1] + if { [string equal $terminator ""] } { + set terminator "*/" + } + set terminator_len [string length $terminator] + + set have_bodies 0 + if { [is_remote host] } { + remote_upload host "$filename" + } + if { [file exists $output_filename] } { + parse_function_bodies $output_filename functions + set have_bodies 1 + } else { + verbose -log "$testcase: output file does not exist" + } + + set count 0 + set function_regexp "" + set label {^(\S+):$} + + set lineno 1 + set fd [open $input_filename r] + set in_function 0 + while { [gets $fd line] >= 0 } { + if { [string equal -length $prefix_len $line $prefix] } { + set line [string trim [string range $line $prefix_len end]] + if { !$in_function } { + if { [regexp "^(.*?\\S)\\s+{(.*)}\$" $line dummy \ + line selector] } { + set selector [dg-process-target $selector] + } else { + set selector "P" + } + if { ![regexp $label $line dummy function_name] } { + close $fd + error "check-function-bodies: line $lineno does not have a function label" + } + set in_function 1 + set function_regexp "" + } elseif { [string equal $line "("] } { + append function_regexp "(?:" + } elseif { [string equal $line "|"] } { + append function_regexp "|" + } elseif { [string equal $line ")"] } { + append function_regexp ")" + } elseif { [string equal $line "..."] } { + append function_regexp ".*" + } else { + append function_regexp "\t" $line "\n" + } + } elseif { [string equal -length $terminator_len $line $terminator] } { + if { ![string equal $selector "N"] } { + if { $xfail_all || [string equal $selector "F"] } { + setup_xfail "*-*-*" + } + set testname "$testcase check-function-bodies $function_name" + if { !$have_bodies } { + unresolved $testname + } elseif { [check_function_body functions $function_name \ + $function_regexp] } { + pass $testname + } else { + fail $testname + } + } + set in_function 0 + incr count + } + incr lineno + } + close $fd + if { $in_function } { + error "check-function-bodies: missing \"$terminator\"" + } + if { $count == 0 } { + error "check-function-bodies: no matches found" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scandump.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scandump.exp new file mode 100644 index 0000000000000000000000000000000000000000..d6ba350acc89c92150ad5f358a22abf895784352 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scandump.exp @@ -0,0 +1,291 @@ +# Copyright (C) 2000-2020 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 +# . + +# Various utilities for scanning dump output, used by gcc-dg.exp and +# g++-dg.exp. +# +# This is largely borrowed from scanasm.exp. + +# Extract the constant part of the dump file suffix from the regexp. +# Argument 0 is the regular expression. +proc dump-suffix { arg } { + set idx [expr [string first "." $arg] + 1] + return [string range $arg $idx end] +} + +# Construct the dumpbase. +# Argument 0 is the src file +# Argument 1 is the dump base suffix +proc dump-base { args } { + set src [lindex $args 0] + set dumpbase_suf [lindex $args 1] + set dumpbase $src + if { [string length $dumpbase_suf] != 0 } { + regsub {[.][^.]*$} $src $dumpbase_suf dumpbase + } + return $dumpbase +} + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump { args } { + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + + set printable_pattern [make_pattern_printable [lindex $args 1]] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + set output_file "[glob -nocomplain $dumpbase.[lindex $args 2]]" + if { $output_file == "" } { + verbose -log "$testcase: dump file does not exist" + verbose -log "dump file: $dumpbase.$suf" + unresolved "$testname" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + if [regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is number of times the regexp must be found +# Argument 3 is the suffix for the dump file +# Argument 4 is the suffix of the dump base +# Argument 5 handles expected failures and the like +proc scan-dump-times { args } { + + if { [llength $args] >= 6 } { + switch [dg-process-target [lindex $args 5]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set times [lindex $args 2] + set suf [dump-suffix [lindex $args 3]] + set printable_pattern [make_pattern_printable [lindex $args 1]] + set testname "$testcase scan-[lindex $args 0]-dump-times $suf \"$printable_pattern\" [lindex $args 2]" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 4]] + set output_file "[glob -nocomplain $dumpbase.[lindex $args 3]]" + if { $output_file == "" } { + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + set result_count [llength [regexp -inline -all -- [lindex $args 1] $text]] + if {$result_count == $times} { + pass "$testname" + } else { + verbose -log "$testcase: pattern found $result_count times" + fail "$testname" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump-not { args } { + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set printable_pattern [make_pattern_printable [lindex $args 1]] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump-not $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + set output_file "[glob -nocomplain $dumpbase.[lindex $args 2]]" + if { $output_file == "" } { + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + if ![regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump-dem { args } { + global cxxfilt + global base_dir + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set printable_pattern [make_pattern_printable [lindex $args 1]] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump-dem $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + set output_file "[glob -nocomplain $dumpbase.[lindex $args 2]]" + if { $output_file == "" } { + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" + return + } + + set fd [open "| $cxxfilt < $output_file" r] + set text [read $fd] + close $fd + + if [regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump-dem-not { args } { + global cxxfilt + global base_dir + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set printable_pattern [make_pattern_printable [lindex $args 1] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump-dem-not $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + set output_file "[glob -nocomplain $dumpbase.[lindex $args 2]]" + if { $output_file == "" } { + verbose -log "$testcase: dump file does not exist" + unresolved "$testname" + return + } + + set fd [open "| $cxxfilt < $output_file" r] + set text [read $fd] + close $fd + + if ![regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanipa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanipa.exp new file mode 100644 index 0000000000000000000000000000000000000000..51bd3fba880dd1aae4431a137bcdc20ed371fcde --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanipa.exp @@ -0,0 +1,146 @@ +# Copyright (C) 2000-2020 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 +# . + +# Various utilities for scanning ipa dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped ipa pass +# Argument 3 handles expected failures and the like +proc scan-ipa-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-ipa-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-ipa-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scan-dump-times "ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" "" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanlang.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanlang.exp new file mode 100644 index 0000000000000000000000000000000000000000..2f80f65f5695d0011a8bec614b6a96c12ccd15b7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanlang.exp @@ -0,0 +1,45 @@ +# Copyright (C) 2000-2020 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 +# . + +# Various utilities for scanning tree dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped lang pass +# Argument 2 handles expected failures and the like +proc scan-lang-dump { args } { + + if { [llength $args] < 2 } { + error "scan-lang-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-lang-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "lang" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "lang" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 1]" "" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanltranstree.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanltranstree.exp new file mode 100644 index 0000000000000000000000000000000000000000..cff956b2f9e3c47f3f4ed7b6f5299f26527647b9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanltranstree.exp @@ -0,0 +1,148 @@ +# Copyright (C) 2000-2020 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 +# . + +# Various utilities for scanning ltrans tree dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" \ + [lindex $args 2] + } else { + scan-dump "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped tree pass +# Argument 3 handles expected failures and the like +proc scan-ltrans-tree-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-ltrans-tree-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-ltrans-tree-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "ltrans-tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" \ + ".exe.ltrans0" [lindex $args 3] + } else { + scan-dump-times "ltrans-tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" ".exe.ltrans0" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" \ + [lindex $args 2] + } else { + scan-dump-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" \ + [lindex $args 2] + } else { + scan-dump-dem "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \ + ".exe.ltrans0" [lindex $args 2] + } else { + scan-dump-dem-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \ + ".exe.ltrans0" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanoffloadrtl.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanoffloadrtl.exp new file mode 100644 index 0000000000000000000000000000000000000000..69e4e7c843cec715c0aeed80bfc849ffb0731dd1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanoffloadrtl.exp @@ -0,0 +1,147 @@ +# Copyright (C) 2018-2020 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 +# . + +# Various utilities for scanning offloading rtl dump output, used by +# libgomp.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped rtl pass +# Argument 3 handles expected failures and the like +proc scan-offload-rtl-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-offload-rtl-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-offload-rtl-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "offload-rtl" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 2]" ".o" \ + [lindex $args 3] + } else { + scan-dump-times "offload-rtl" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 2]" ".o" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump-dem "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump-dem-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" ".o" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanoffloadtree.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanoffloadtree.exp new file mode 100644 index 0000000000000000000000000000000000000000..76a28d036a885fd7c96775379ffa04035b6d67a2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanoffloadtree.exp @@ -0,0 +1,147 @@ +# Copyright (C) 2018-2020 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 +# . + +# Various utilities for scanning offloading tree dump output, used by +# libgomp.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped tree pass +# Argument 3 handles expected failures and the like +proc scan-offload-tree-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-offload-tree-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-offload-tree-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "offload-tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 2]" ".o" \ + [lindex $args 3] + } else { + scan-dump-times "offload-tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 2]" ".o" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump-dem "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" \ + [lindex $args 2] + } else { + scan-dump-dem-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" ".o" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanrtl.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanrtl.exp new file mode 100644 index 0000000000000000000000000000000000000000..fae0f26aabbc54e5213e355a1982141c846b5efc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanrtl.exp @@ -0,0 +1,156 @@ +# Copyright (C) 2006-2020 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 +# . + +# Various utilities for scanning rtl dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped rtl pass +# Argument 3 handles expected failures and the like +proc scan-rtl-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-rtl-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-rtl-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "rtl" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scan-dump-times "rtl" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 2]" "" + } +} + +force_conventional_output_for scan-rtl-dump-times + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump-not + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump-dem + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" \ + "" [lindex $args 2] + } else { + scan-dump-dem-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump-dem-not diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scantree.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scantree.exp new file mode 100644 index 0000000000000000000000000000000000000000..d77fb1e1ddbfac4bb62009738beed8bf430dfc74 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scantree.exp @@ -0,0 +1,146 @@ +# Copyright (C) 2000-2020 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 +# . + +# Various utilities for scanning tree dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped tree pass +# Argument 3 handles expected failures and the like +proc scan-tree-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-tree-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-tree-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scan-dump-times "tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" "" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \ + "" [lindex $args 2] + } else { + scan-dump-dem-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanwpaipa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanwpaipa.exp new file mode 100644 index 0000000000000000000000000000000000000000..2f58823a4f3c03ff29279a0cb30446782f3dad29 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/scanwpaipa.exp @@ -0,0 +1,170 @@ +# Copyright (C) 2018-2020 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 +# . + +# Various utilities for scanning ipa dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \ + [lindex $args 2] + } else { + scan-dump "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" + } +} + +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-pgo-wpa-ipa-dump { args } { + + if { [llength $args] < 2 } { + error "scan-pgo-wpa-ipa-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-pgo-wpa-ipa-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "pgo-wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".x02.wpa" \ + [lindex $args 2] + } else { + scan-dump "pgo-wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".x02.wpa" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped ipa pass +# Argument 3 handles expected failures and the like +proc scan-wpa-ipa-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-wpa-ipa-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-wpa-ipa-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "wpa-ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".exe.wpa" \ + [lindex $args 3] + } else { + scan-dump-times "wpa-ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".exe.wpa" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \ + [lindex $args 2] + } else { + scan-dump-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \ + [lindex $args 2] + } else { + scan-dump-dem "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \ + [lindex $args 2] + } else { + scan-dump-dem-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-libpath.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-libpath.exp new file mode 100644 index 0000000000000000000000000000000000000000..9882a4e74f42207c4056576f2085c655765a2430 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-libpath.exp @@ -0,0 +1,289 @@ +# Copyright (C) 2004-2020 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 +# . + +# This file was contributed by John David Anglin (dave.anglin@nrc-cnrc.gc.ca) + +set orig_environment_saved 0 +set orig_ld_library_path_saved 0 +set orig_ld_run_path_saved 0 +set orig_shlib_path_saved 0 +set orig_ld_library_path_32_saved 0 +set orig_ld_library_path_64_saved 0 +set orig_dyld_library_path_saved 0 +set orig_path_saved 0 +set orig_gcc_exec_prefix_saved 0 +set orig_gcc_exec_prefix_checked 0 + + +####################################### +# proc set_gcc_exec_prefix_env_var { } +####################################### + +proc set_gcc_exec_prefix_env_var { } { + global TEST_GCC_EXEC_PREFIX + global env + + # Set GCC_EXEC_PREFIX for the compiler under test to pick up files not in + # the build tree from a specified location (normally the install tree). + if [info exists TEST_GCC_EXEC_PREFIX] { + setenv GCC_EXEC_PREFIX "$TEST_GCC_EXEC_PREFIX" + } +} + +####################################### +# proc set_ld_library_path_env_vars { } +####################################### + +proc set_ld_library_path_env_vars { } { + global ld_library_path + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_gcc_exec_prefix_saved + global orig_gcc_exec_prefix_checked + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + global orig_gcc_exec_prefix + global env + + # Save the original GCC_EXEC_PREFIX. + if { $orig_gcc_exec_prefix_checked == 0 } { + if [info exists env(GCC_EXEC_PREFIX)] { + set orig_gcc_exec_prefix "$env(GCC_EXEC_PREFIX)" + set orig_gcc_exec_prefix_saved 1 + } + set orig_gcc_exec_prefix_checked 1 + } + + set_gcc_exec_prefix_env_var + + # Setting the ld library path causes trouble when testing cross-compilers. + if { [is_remote target] } { + return + } + + if { $orig_environment_saved == 0 } { + set orig_environment_saved 1 + + # Save the original environment. + if [info exists env(LD_LIBRARY_PATH)] { + set orig_ld_library_path "$env(LD_LIBRARY_PATH)" + set orig_ld_library_path_saved 1 + } + if [info exists env(LD_RUN_PATH)] { + set orig_ld_run_path "$env(LD_RUN_PATH)" + set orig_ld_run_path_saved 1 + } + if [info exists env(SHLIB_PATH)] { + set orig_shlib_path "$env(SHLIB_PATH)" + set orig_shlib_path_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_32)] { + set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)" + set orig_ld_library_path_32_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_64)] { + set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)" + set orig_ld_library_path_64_saved 1 + } + if [info exists env(DYLD_LIBRARY_PATH)] { + set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)" + set orig_dyld_library_path_saved 1 + } + if [info exists env(PATH)] { + set orig_path "$env(PATH)" + set orig_path_saved 1 + } + } + + # We need to set ld library path in the environment. Currently, + # unix.exp doesn't set the environment correctly for all systems. + # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a + # program. We also need the environment set for compilations, etc. + # + # On Darwin, we have to set variables akin to LD_LIBRARY_PATH, but called + # DYLD_LIBRARY_PATH. The same applies to Solaris 32 bit + # (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64), and HP-UX + # (SHLIB_PATH). In some cases, the variables are independent of + # LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the + # variable is not defined. + # + # Doing this is somewhat of a hack as ld_library_path gets repeated in + # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables. + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH "$ld_library_path" + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path" + } else { + setenv LD_RUN_PATH "$ld_library_path" + } + # The default shared library dynamic path search for 64-bit + # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH. + # LD_LIBRARY_PATH isn't used for 32-bit executables. Thus, we + # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent. + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path" + } else { + setenv SHLIB_PATH "$ld_library_path" + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_32 "$ld_library_path" + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_64 "$ld_library_path" + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" + } else { + setenv DYLD_LIBRARY_PATH "$ld_library_path" + } + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + if { $orig_path_saved } { + setenv PATH "$ld_library_path:$orig_path" + } else { + setenv PATH "$ld_library_path" + } + } + + verbose -log "LD_LIBRARY_PATH=[getenv LD_LIBRARY_PATH]" + verbose -log "LD_RUN_PATH=[getenv LD_RUN_PATH]" + verbose -log "SHLIB_PATH=[getenv SHLIB_PATH]" + verbose -log "LD_LIBRARY_PATH_32=[getenv LD_LIBRARY_PATH_32]" + verbose -log "LD_LIBRARY_PATH_64=[getenv LD_LIBRARY_PATH_64]" + verbose -log "DYLD_LIBRARY_PATH=[getenv DYLD_LIBRARY_PATH]" +} + +####################################### +# proc restore_gcc_exec_prefix_env_var { } +####################################### + +proc restore_gcc_exec_prefix_env_var { } { + global orig_gcc_exec_prefix_saved + global orig_gcc_exec_prefix + global env + + if { $orig_gcc_exec_prefix_saved } { + setenv GCC_EXEC_PREFIX "$orig_gcc_exec_prefix" + } elseif [info exists env(GCC_EXEC_PREFIX)] { + unsetenv GCC_EXEC_PREFIX + } +} + +####################################### +# proc restore_ld_library_path_env_vars { } +####################################### + +proc restore_ld_library_path_env_vars { } { + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + global env + + restore_gcc_exec_prefix_env_var + + if { $orig_environment_saved == 0 } { + return + } + + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$orig_ld_library_path" + } elseif [info exists env(LD_LIBRARY_PATH)] { + unsetenv LD_LIBRARY_PATH + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$orig_ld_run_path" + } elseif [info exists env(LD_RUN_PATH)] { + unsetenv LD_RUN_PATH + } + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$orig_shlib_path" + } elseif [info exists env(SHLIB_PATH)] { + unsetenv SHLIB_PATH + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32" + } elseif [info exists env(LD_LIBRARY_PATH_32)] { + unsetenv LD_LIBRARY_PATH_32 + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64" + } elseif [info exists env(LD_LIBRARY_PATH_64)] { + unsetenv LD_LIBRARY_PATH_64 + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path" + } elseif [info exists env(DYLD_LIBRARY_PATH)] { + unsetenv DYLD_LIBRARY_PATH + } + if { $orig_path_saved } { + setenv PATH "$orig_path" + } elseif [info exists env(PATH)] { + unsetenv PATH + } +} + +####################################### +# proc get_shlib_extension { } +####################################### + +proc get_shlib_extension { } { + global shlib_ext + + if { [istarget *-*-darwin*] } { + set shlib_ext "dylib" + } elseif { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + set shlib_ext "dll" + } elseif { [istarget hppa*-*-hpux*] } { + set shlib_ext "sl" + } else { + set shlib_ext "so" + } + return $shlib_ext +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-supports-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-supports-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..2a21424b8905d82bc2cceb62dc0987da6bd1e28e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-supports-dg.exp @@ -0,0 +1,639 @@ +# Copyright (C) 1997-2020 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 +# . + +# DejaGnu's dg-test defines extra flags that are used to compile a test. +# Access them for directives that need to examine all options that are +# used for a test, including checks for non-cached effective targets. +# We don't know how far up the call chain it is but we know we'll hit +# it eventually, and that we're at least 3 calls down. + +proc current_compiler_flags { } { + set frames 2 + while { ![info exists flags1] } { + set frames [expr $frames + 1] + upvar $frames dg-extra-tool-flags flags1 + } + upvar $frames tool_flags flags2 + return "$flags1 $flags2" +} + +# DejaGnu's dg-test defines a test name that includes torture options +# which is used in most pass/fail messages. Grab a copy of it. + +proc testname-for-summary { } { + global testname_with_flags + + # A variable called "name" is too generic, so identify dg-test by + # the existence of dg-extra-tool-flags. + if ![info exists testname_with_flags] { + set frames 2 + while { ![info exists flags] } { + set frames [expr $frames + 1] + upvar $frames dg-extra-tool-flags flags + } + + # We've got the stack level for dg-test; get the variable we want. + upvar $frames name name + set testname_with_flags $name + + # If there are flags, add an extra space to improve readability of + # the test summary. + if { [llength $testname_with_flags] > 1 } { + set testname_with_flags "$testname_with_flags " + } + } + return "$testname_with_flags" +} + +# If this target does not support weak symbols, skip this test. + +proc dg-require-weak { args } { + set weak_available [ check_weak_available ] + if { $weak_available == -1 } { + upvar name name + unresolved "$name" + } + if { $weak_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support overriding weak symbols, skip this +# test. + +proc dg-require-weak-override { args } { + set weak_override_available [ check_weak_override_available ] + if { $weak_override_available == -1 } { + upvar name name + unresolved "$name" + } + if { $weak_override_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "visibility" attribute, skip this +# test. + +proc dg-require-visibility { args } { + set visibility_available [ check_visibility_available [lindex $args 1 ] ] + if { $visibility_available == -1 } { + upvar name name + unresolved "$name" + } + if { $visibility_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "alias" attribute, skip this +# test. + +proc dg-require-alias { args } { + set alias_available [ check_alias_available ] + if { $alias_available == -1 } { + upvar name name + unresolved "$name" + } + if { $alias_available < 2 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "ifunc" attribute, skip this +# test. + +proc dg-require-ifunc { args } { + if { ![ check_ifunc_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target's linker does not support the --gc-sections flag, +# skip this test. + +proc dg-require-gc-sections { args } { + if { ![ check_gc_sections_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support profiling, skip this test. + +proc dg-require-profiling { args } { + if { ![ check_profiling_available [lindex $args 1] ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support DLL attributes skip this test. + +proc dg-require-dll { args } { + # As a special case, the mcore-*-elf supports these attributes. + # All Symbian OS targets also support these attributes. + if { [istarget mcore-*-elf] + || [istarget *-*-symbianelf] } { + return + } + # PE/COFF targets support dllimport/dllexport. + if { [gcc_target_object_format] == "pe" } { + return + } + + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] +} + +# If this host does not support an ASCII locale, skip this test. + +proc dg-require-ascii-locale { args } { + if { ![ check_ascii_locale_available] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +proc dg-require-iconv { args } { + if { ![ check_iconv_available ${args} ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this host does not have "dot", skip this test. + +proc dg-require-dot { args } { + verbose "dg-require-dot" 2 + if { ![ check_dot_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not have sufficient stack size, skip this test. + +proc dg-require-stack-size { args } { + if { ![is-effective-target stack_size] } { + return + } + + set stack_size [dg-effective-target-value stack_size] + set required [expr [lindex $args 1]] + if { $stack_size < $required } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support named sections skip this test. + +proc dg-require-named-sections { args } { + if { ![ check_named_sections_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If the target does not match the required effective target, skip this test. +# Only apply this if the optional selector matches. + +proc dg-require-effective-target { args } { + set args [lreplace $args 0 0] + # Verify the number of arguments. The last is optional. + if { [llength $args] < 1 || [llength $args] > 2 } { + error "syntax error, need a single effective-target keyword with optional selector" + } + + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + # Evaluate selector if present. + if { [llength $args] == 2 } { + switch [dg-process-target-1 [lindex $args 1]] { + "S" { } + "N" { return } + } + } + + if { ![is-effective-target [lindex $args 0]] } { + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not have fork, skip this test. + +proc dg-require-fork { args } { + if { ![check_fork_available] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not have mkfifo, skip this test. + +proc dg-require-mkfifo { args } { + if { ![check_mkfifo_available] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not use __cxa_atexit, skip this test. + +proc dg-require-cxa-atexit { args } { + if { ![ check_cxa_atexit_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If the host is remote rather than the same as the build system, skip +# this test. Some tests are incompatible with DejaGnu's handling of +# remote hosts, which involves copying the source file to the host and +# compiling it with a relative path and "-o a.out". + +proc dg-require-host-local { args } { + if [ is_remote host ] { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +proc dg-require-linker-plugin { args } { + set linker_plugin_available [ check_linker_plugin_available ] + if { $linker_plugin_available == 0 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "stack-check" option, skip this +# test. + +proc dg-require-stack-check { args } { + set stack_check_available [ check_stack_check_available [lindex $args 1 ] ] + if { $stack_check_available == -1 } { + upvar name name + unresolved "$name" + } + if { $stack_check_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# Add any target-specific flags needed for accessing the given list +# of features. This must come after all dg-options. + +proc dg-add-options { args } { + upvar dg-extra-tool-flags extra-tool-flags + + foreach arg [lrange $args 1 end] { + if { [info procs add_options_for_$arg] != "" } { + set extra-tool-flags \ + [eval [list add_options_for_$arg ${extra-tool-flags}]] + } else { + error "Unrecognized option type: $arg" + } + } +} + +# Compare flags for a test directive against flags that will be used to +# compile the test: multilib flags, flags for torture options, and either +# the default flags for this group of tests or flags specified with a +# previous dg-options directive. + +proc check-flags { args } { + global compiler_flags + global TOOL_OPTIONS + global TEST_ALWAYS_FLAGS + + # The args are within another list; pull them out. + set args [lindex $args 0] + + # Start the list with a dummy tool name so the list will match "*" + # if there are no flags. + set compiler_flags " toolname " + append compiler_flags [current_compiler_flags] + # If running a subset of the test suite, $TOOL_OPTIONS may not exist. + catch {append compiler_flags " $TOOL_OPTIONS "} + # If running a subset of the test suite, $TEST_ALWAYS_FLAGS may not exist. + catch {append compiler_flags " $TEST_ALWAYS_FLAGS "} + set dest [target_info name] + if [board_info $dest exists cflags] { + append compiler_flags "[board_info $dest cflags] " + } + if [board_info $dest exists multilib_flags] { + append compiler_flags "[board_info $dest multilib_flags] " + } + + # The next two arguments are optional. If they were not specified, + # use the defaults. + if { [llength $args] == 2 } { + lappend $args [list "*"] + } + if { [llength $args] == 3 } { + lappend $args [list ""] + } + + # If the option strings are the defaults, or the same as the + # defaults, there is no need to call check_conditional_xfail to + # compare them to the actual options. + if { [string compare [lindex $args 2] "*"] == 0 + && [string compare [lindex $args 3] "" ] == 0 } { + set result 1 + } else { + # The target list might be an effective-target keyword, so replace + # the original list with "*-*-*", since we already know it matches. + set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]] + } + + # Any value in this variable was left over from an earlier test. + set compiler_flags "" + + return $result +} + +# Skip the test (report it as UNSUPPORTED) if the target list and +# included flags are matched and the excluded flags are not matched. +# +# The first argument is the line number of the dg-skip-if directive +# within the test file. Remaining arguments are as for xfail lists: +# message { targets } { include } { exclude } +# +# This tests against multilib flags plus either the default flags for this +# group of tests or flags specified with a previous dg-options command. + +proc dg-skip-if { args } { + # Verify the number of arguments. The last two are optional. + set args [lreplace $args 0 0] + if { [llength $args] < 2 || [llength $args] > 4 } { + error "dg-skip-if 2: need 2, 3, or 4 arguments" + } + + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + if [check-flags $args] { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } + } +} + +# Like check_conditional_xfail, but callable from a dg test. + +proc dg-xfail-if { args } { + # Verify the number of arguments. The last three are optional. + set args [lreplace $args 0 0] + if { [llength $args] < 2 || [llength $args] > 4 } { + error "dg-xfail-if: need 2, 3, or 4 arguments" + } + + # Don't change anything if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + global compiler_conditional_xfail_data + + # The target list might be an effective-target keyword. Replace + # the original list with "*-*-*", since we already know it matches. + set args [lreplace $args 1 1 "*-*-*"] + + # Supply default values for unspecified optional arguments. + if { [llength $args] == 2 } { + lappend $args [list "*"] + } + if { [llength $args] == 3 } { + lappend $args [list ""] + } + + set compiler_conditional_xfail_data $args + } +} + +# Like dg-xfail-if but for the execute step. + +proc dg-xfail-run-if { args } { + # Verify the number of arguments. The last two are optional. + set args [lreplace $args 0 0] + if { [llength $args] < 2 || [llength $args] > 4 } { + error "dg-xfail-run-if: need 2, 3, or 4 arguments" + } + + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + if [check-flags $args] { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "S" "F"] + } + } +} + +# Record whether the program is expected to return a nonzero status. + +set shouldfail 0 + +proc dg-shouldfail { args } { + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + global shouldfail + + set args [lreplace $args 0 0] + if { [llength $args] > 1 } { + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + # The target matches, now check the flags. + if [check-flags $args] { + set shouldfail 1 + } + } + } else { + set shouldfail 1 + } +} + +# Intercept the call to the DejaGnu version of dg-process-target to +# support use of an effective-target keyword in place of a list of +# target triplets to xfail or skip a test. +# +# The argument to dg-process-target is the keyword "target" or "xfail" +# followed by a selector: +# target-triplet-1 ... +# effective-target-keyword +# selector-expression +# +# For a target list the result is "S" if the target is selected, "N" otherwise. +# For an xfail list the result is "F" if the target is affected, "P" otherwise. + +# In contexts that allow either "target" or "xfail" the argument can be +# target selector1 xfail selector2 +# which returns "N" if selector1 is not selected, otherwise the result of +# "xfail selector2". +# +# A selector expression appears within curly braces and uses a single logical +# operator: !, &&, or ||. An operand is another selector expression, an +# effective-target keyword, or a list of target triplets within quotes or +# curly braces. + +if { [info procs saved-dg-process-target] == [list] } { + rename dg-process-target saved-dg-process-target + + # Evaluate an operand within a selector expression. + proc selector_opd { op } { + set selector "target" + lappend selector $op + set answer [ expr { [dg-process-target $selector] == "S" } ] + verbose "selector_opd: `$op' $answer" 2 + return $answer + } + + # Evaluate a target triplet list within a selector expression. + # Unlike other operands, this needs to be expanded from a list to + # the same string as "target". + proc selector_list { op } { + set selector "target [join $op]" + set answer [ expr { [dg-process-target $selector] == "S" } ] + verbose "selector_list: `$op' $answer" 2 + return $answer + } + + # Evaluate a selector expression. + proc selector_expression { exp } { + if { [llength $exp] == 2 } { + if [string match "!" [lindex $exp 0]] { + set op1 [lindex $exp 1] + set answer [expr { ! [selector_opd $op1] }] + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + } elseif { [llength $exp] == 3 } { + set op1 [lindex $exp 0] + set opr [lindex $exp 1] + set op2 [lindex $exp 2] + if [string match "&&" $opr] { + set answer [expr { [selector_opd $op1] && [selector_opd $op2] }] + } elseif [string match "||" $opr] { + set answer [expr { [selector_opd $op1] || [selector_opd $op2] }] + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + + verbose "selector_expression: `$exp' $answer" 2 + return $answer + } + + # Evaluate "target selector" or "xfail selector". + + proc dg-process-target-1 { args } { + verbose "dg-process-target-1: `$args'" 2 + + # Extract the 'what' keyword from the argument list. + set selector [string trim [lindex $args 0]] + if [regexp "^xfail " $selector] { + set what "xfail" + } elseif [regexp "^target " $selector] { + set what "target" + } else { + error "syntax error in target selector \"$selector\"" + } + + # Extract the rest of the list, which might be a keyword. + regsub "^${what}" $selector "" rest + set rest [string trim $rest] + + if [is-effective-target-keyword $rest] { + # The selector is an effective target keyword. + if [is-effective-target $rest] { + return [expr { $what == "xfail" ? "F" : "S" }] + } else { + return [expr { $what == "xfail" ? "P" : "N" }] + } + } + + if [string match "{*}" $rest] { + if [selector_expression [lindex $rest 0]] { + return [expr { $what == "xfail" ? "F" : "S" }] + } else { + return [expr { $what == "xfail" ? "P" : "N" }] + } + } + + # The selector is not an effective-target keyword, so process + # the list of target triplets. + return [saved-dg-process-target $selector] + } + + # Intercept calls to the DejaGnu function. In addition to + # processing "target selector" or "xfail selector", handle + # "target selector1 xfail selector2". + + proc dg-process-target { args } { + verbose "replacement dg-process-target: `$args'" 2 + + set selector [string trim [lindex $args 0]] + + # If the argument list contains both 'target' and 'xfail', + # process 'target' and, if that succeeds, process 'xfail'. + if [regexp "^target .* xfail .*" $selector] { + set xfail_index [string first "xfail" $selector] + set xfail_selector [string range $selector $xfail_index end] + set target_selector [string range $selector 0 [expr $xfail_index-1]] + set target_selector [string trim $target_selector] + if { [dg-process-target-1 $target_selector] == "N" } { + return "N" + } + return [dg-process-target-1 $xfail_selector] + + } + return [dg-process-target-1 $selector] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-supports.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-supports.exp new file mode 100644 index 0000000000000000000000000000000000000000..bd62a0d9e799fc703935d24c565ec1beb823a1d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-supports.exp @@ -0,0 +1,10364 @@ +# Copyright (C) 1999-2020 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 +# . + +# Please email any bugs, comments, and/or additions to this file to: +# gcc-patches@gcc.gnu.org + +# This file defines procs for determining features supported by the target. + +# Try to compile the code given by CONTENTS into an output file of +# type TYPE, where TYPE is as for target_compile. Return a list +# whose first element contains the compiler messages and whose +# second element is the name of the output file. +# +# BASENAME is a prefix to use for source and output files. +# If ARGS is not empty, its first element is a string that +# should be added to the command line. +# +# Assume by default that CONTENTS is C code. +# Otherwise, code should contain: +# "// C++" for c++, +# "// D" for D, +# "! Fortran" for Fortran code, +# "/* ObjC", for ObjC +# "// ObjC++" for ObjC++ +# and "// Go" for Go +# If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to +# allow for ObjC/ObjC++ specific flags. + +proc check_compile {basename type contents args} { + global tool + verbose "check_compile tool: $tool for $basename" + + # Save additional_sources to avoid compiling testsuite's sources + # against check_compile's source. + global additional_sources + if [info exists additional_sources] { + set tmp_additional_sources "$additional_sources" + set additional_sources "" + } + + if { [llength $args] > 0 } { + set options [list "additional_flags=[lindex $args 0]"] + } else { + set options "" + } + switch -glob -- $contents { + "*! Fortran*" { set src ${basename}[pid].f90 } + "*// C++*" { set src ${basename}[pid].cc } + "*// D*" { set src ${basename}[pid].d } + "*// ObjC++*" { set src ${basename}[pid].mm } + "*/* ObjC*" { set src ${basename}[pid].m } + "*// Go*" { set src ${basename}[pid].go } + default { + switch -- $tool { + "objc" { set src ${basename}[pid].m } + "obj-c++" { set src ${basename}[pid].mm } + default { set src ${basename}[pid].c } + } + } + } + + set compile_type $type + switch -glob $type { + assembly { set output ${basename}[pid].s } + object { set output ${basename}[pid].o } + executable { set output ${basename}[pid].exe } + "rtl-*" { + set output ${basename}[pid].s + lappend options "additional_flags=-fdump-$type" + set compile_type assembly + } + } + set f [open $src "w"] + puts $f $contents + close $f + set lines [${tool}_target_compile $src $output $compile_type "$options"] + file delete $src + + set scan_output $output + # Don't try folding this into the switch above; calling "glob" before the + # file is created won't work. + if [regexp "rtl-(.*)" $type dummy rtl_type] { + set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]" + file delete $output + } + + # Restore additional_sources. + if [info exists additional_sources] { + set additional_sources "$tmp_additional_sources" + } + + return [list $lines $scan_output] +} + +proc current_target_name { } { + global target_info + if [info exists target_info(target,name)] { + set answer $target_info(target,name) + } else { + set answer "" + } + return $answer +} + +# Implement an effective-target check for property PROP by invoking +# the Tcl command ARGS and seeing if it returns true. + +proc check_cached_effective_target { prop args } { + global et_cache + + set target [current_target_name] + if {![info exists et_cache($prop,$target)]} { + verbose "check_cached_effective_target $prop: checking $target" 2 + if {[string is true -strict $args] || [string is false -strict $args]} { + error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?} + } else { + set code [catch {uplevel eval $args} result] + if {$code != 0 && $code != 2} { + return -code $code $result + } + set et_cache($prop,$target) $result + } + } + set value $et_cache($prop,$target) + verbose "check_cached_effective_target $prop: returning $value for $target" 2 + return $value +} + +# Implements a version of check_cached_effective_target that also takes et_index +# into account when creating the key for the cache. +proc check_cached_effective_target_indexed { prop args } { + global et_index + set key "$et_index $prop" + verbose "check_cached_effective_target_index $prop: returning $key" 2 + + return [check_cached_effective_target $key [list uplevel eval $args]] +} + +# Clear effective-target cache. This is useful after testing +# effective-target features and overriding TEST_ALWAYS_FLAGS and/or +# ALWAYS_CXXFLAGS. +# If one changes ALWAYS_CXXFLAGS or TEST_ALWAYS_FLAGS then they should +# do a clear_effective_target_cache at the end as the target cache can +# make decisions based upon the flags, and those decisions need to be +# redone when the flags change. An example of this is the +# asan_init/asan_finish pair. + +proc clear_effective_target_cache { } { + global et_cache + array unset et_cache +} + +# Like check_compile, but delete the output file and return true if the +# compiler printed no messages. +proc check_no_compiler_messages_nocache {args} { + set result [eval check_compile $args] + set lines [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $output + return [string match "" $lines] +} + +# Like check_no_compiler_messages_nocache, but cache the result. +# PROP is the property we're checking, and doubles as a prefix for +# temporary filenames. +proc check_no_compiler_messages {prop args} { + return [check_cached_effective_target $prop { + eval [list check_no_compiler_messages_nocache $prop] $args + }] +} + +# Like check_compile, but return true if the compiler printed no +# messages and if the contents of the output file satisfy PATTERN. +# If PATTERN has the form "!REGEXP", the contents satisfy it if they +# don't match regular expression REGEXP, otherwise they satisfy it +# if they do match regular expression PATTERN. (PATTERN can start +# with something like "[!]" if the regular expression needs to match +# "!" as the first character.) +# +# Delete the output file before returning. The other arguments are +# as for check_compile. +proc check_no_messages_and_pattern_nocache {basename pattern args} { + global tool + + set result [eval [list check_compile $basename] $args] + set lines [lindex $result 0] + set output [lindex $result 1] + + set ok 0 + if { [string match "" $lines] } { + set chan [open "$output"] + set invert [regexp {^!(.*)} $pattern dummy pattern] + set ok [expr { [regexp $pattern [read $chan]] != $invert }] + close $chan + } + + remote_file build delete $output + return $ok +} + +# Like check_no_messages_and_pattern_nocache, but cache the result. +# PROP is the property we're checking, and doubles as a prefix for +# temporary filenames. +proc check_no_messages_and_pattern {prop pattern args} { + return [check_cached_effective_target $prop { + eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args + }] +} + +# Try to compile and run an executable from code CONTENTS. Return true +# if the compiler reports no messages and if execution "passes" in the +# usual DejaGNU sense. The arguments are as for check_compile, with +# TYPE implicitly being "executable". +proc check_runtime_nocache {basename contents args} { + global tool + + set result [eval [list check_compile $basename executable $contents] $args] + set lines [lindex $result 0] + set output [lindex $result 1] + + set ok 0 + if { [string match "" $lines] } { + # No error messages, everything is OK. + set result [remote_load target "./$output" "" ""] + set status [lindex $result 0] + verbose "check_runtime_nocache $basename: status is <$status>" 2 + if { $status == "pass" } { + set ok 1 + } + } + remote_file build delete $output + return $ok +} + +# Like check_runtime_nocache, but cache the result. PROP is the +# property we're checking, and doubles as a prefix for temporary +# filenames. +proc check_runtime {prop args} { + global tool + + return [check_cached_effective_target $prop { + eval [list check_runtime_nocache $prop] $args + }] +} + +# Return 1 if GCC was configured with $pattern. +proc check_configured_with { pattern } { + global tool + + set options [list "additional_flags=-v"] + set gcc_output [${tool}_target_compile "" "" "none" $options] + if { [ regexp "Configured with: \[^\n\]*$pattern" $gcc_output ] } { + verbose "Matched: $pattern" 2 + return 1 + } + + verbose "Failed to match: $pattern" 2 + return 0 +} + +############################### +# proc check_weak_available { } +############################### + +# weak symbols are only supported in some configs/object formats +# this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure + +proc check_weak_available { } { + global target_cpu + + # All mips targets should support it + + if { [ string first "mips" $target_cpu ] >= 0 } { + return 1 + } + + # All AIX targets should support it + + if { [istarget *-*-aix*] } { + return 1 + } + + # All solaris2 targets should support it + + if { [istarget *-*-solaris2*] } { + return 1 + } + + # Windows targets Cygwin and MingW32 support it + + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + return 1 + } + + # HP-UX 10.X doesn't support it + + if { [istarget hppa*-*-hpux10*] } { + return 0 + } + + # nvptx (nearly) supports it + + if { [istarget nvptx-*-*] } { + return 1 + } + + # pdp11 doesn't support it + + if { [istarget pdp11*-*-*] } { + return 0 + } + + # ELF and ECOFF support it. a.out does with gas/gld but may also with + # other linkers, so we should try it + + set objformat [gcc_target_object_format] + + switch $objformat { + elf { return 1 } + ecoff { return 1 } + a.out { return 1 } + mach-o { return 1 } + som { return 1 } + unknown { return -1 } + default { return 0 } + } +} + +# return 1 if weak undefined symbols are supported. + +proc check_effective_target_weak_undefined { } { + if { [istarget hppa*-*-hpux*] } { + return 0 + } + return [check_runtime weak_undefined { + extern void foo () __attribute__((weak)); + int main (void) { if (foo) return 1; return 0; } + } ""] +} + +############################### +# proc check_weak_override_available { } +############################### + +# Like check_weak_available, but return 0 if weak symbol definitions +# cannot be overridden. + +proc check_weak_override_available { } { + if { [istarget *-*-mingw*] } { + return 0 + } + return [check_weak_available] +} + +# The noinit attribute is only supported by some targets. +# This proc returns 1 if it's supported, 0 if it's not. + +proc check_effective_target_noinit { } { + if { [istarget arm*-*-eabi] + || [istarget msp430-*-*] } { + return 1 + } + + return 0 +} + +############################### +# proc check_visibility_available { what_kind } +############################### + +# The visibility attribute is only support in some object formats +# This proc returns 1 if it is supported, 0 if not. +# The argument is the kind of visibility, default/protected/hidden/internal. + +proc check_visibility_available { what_kind } { + if [string match "" $what_kind] { set what_kind "hidden" } + + return [check_no_compiler_messages visibility_available_$what_kind object " + void f() __attribute__((visibility(\"$what_kind\"))); + void f() {} + "] +} + +############################### +# proc check_alias_available { } +############################### + +# Determine if the target toolchain supports the alias attribute. + +# Returns 2 if the target supports aliases. Returns 1 if the target +# only supports weak aliased. Returns 0 if the target does not +# support aliases at all. Returns -1 if support for aliases could not +# be determined. + +proc check_alias_available { } { + global tool + + return [check_cached_effective_target alias_available { + set src alias[pid].c + set obj alias[pid].o + verbose "check_alias_available compiling testfile $src" 2 + set f [open $src "w"] + # Compile a small test program. The definition of "g" is + # necessary to keep the Solaris assembler from complaining + # about the program. + puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n" + puts $f "void g() {} void f() __attribute__((alias(\"g\")));" + close $f + set lines [${tool}_target_compile $src $obj object ""] + file delete $src + remote_file build delete $obj + + if [string match "" $lines] then { + # No error messages, everything is OK. + return 2 + } else { + if [regexp "alias definitions not supported" $lines] { + verbose "check_alias_available target does not support aliases" 2 + + set objformat [gcc_target_object_format] + + if { $objformat == "elf" } { + verbose "check_alias_available but target uses ELF format, so it ought to" 2 + return -1 + } else { + return 0 + } + } else { + if [regexp "only weak aliases are supported" $lines] { + verbose "check_alias_available target supports only weak aliases" 2 + return 1 + } else { + return -1 + } + } + } + }] +} + +# Returns 1 if the target toolchain supports strong aliases, 0 otherwise. + +proc check_effective_target_alias { } { + if { [check_alias_available] < 2 } { + return 0 + } else { + return 1 + } +} + +# Returns 1 if the target toolchain supports ifunc, 0 otherwise. + +proc check_ifunc_available { } { + return [check_no_compiler_messages ifunc_available object { + #ifdef __cplusplus + extern "C" { + #endif + extern void f_ (); + typedef void F (void); + F* g (void) { return &f_; } + void f () __attribute__ ((ifunc ("g"))); + #ifdef __cplusplus + } + #endif + }] +} + +# Returns true if --gc-sections is supported on the target. + +proc check_gc_sections_available { } { + global tool + + return [check_cached_effective_target gc_sections_available { + # Some targets don't support gc-sections despite whatever's + # advertised by ld's options. + if { [istarget alpha*-*-*] + || [istarget ia64-*-*] } { + return 0 + } + + # elf2flt uses -q (--emit-relocs), which is incompatible with + # --gc-sections. + if { [board_info target exists ldflags] + && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } { + return 0 + } + + # VxWorks kernel modules are relocatable objects linked with -r, + # while RTP executables are linked with -q (--emit-relocs). + # Both of these options are incompatible with --gc-sections. + if { [istarget *-*-vxworks*] } { + return 0 + } + + # Check if the ld used by gcc supports --gc-sections. + set options [list "additional_flags=-print-prog-name=ld"] + set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0] + set ld_output [remote_exec host "$gcc_ld" "--help"] + if { [ string first "--gc-sections" $ld_output ] >= 0 } { + return 1 + } else { + return 0 + } + }] +} + +# Returns 1 if "dot" is supported on the host. + +proc check_dot_available { } { + verbose "check_dot_available" 2 + + set status [remote_exec host "dot" "-V"] + verbose " status: $status" 2 + if { [lindex $status 0] != 0 } { + return 0 + } + return 1 +} + +# Return 1 if according to target_info struct and explicit target list +# target is supposed to support trampolines. + +proc check_effective_target_trampolines { } { + if [target_info exists gcc,no_trampolines] { + return 0 + } + if { [istarget avr-*-*] + || [istarget msp430-*-*] + || [istarget nvptx-*-*] + || [istarget hppa2.0w-hp-hpux11.23] + || [istarget hppa64-hp-hpux11.23] + || [istarget pru-*-*] + || [istarget bpf-*-*] } { + return 0; + } + return 1 +} + +# Return 1 if target has limited stack size. + +proc check_effective_target_stack_size { } { + if [target_info exists gcc,stack_size] { + return 1 + } + return 0 +} + +# Return the value attribute of an effective target, otherwise return 0. + +proc dg-effective-target-value { effective_target } { + if { "$effective_target" == "stack_size" } { + if [check_effective_target_stack_size] { + return [target_info gcc,stack_size] + } + } + + return 0 +} + +# Return 1 if signal.h is supported. + +proc check_effective_target_signal { } { + if [target_info exists gcc,signal_suppress] { + return 0 + } + return 1 +} + +# Return 1 if according to target_info struct and explicit target list +# target disables -fdelete-null-pointer-checks. Targets should return 0 +# if they simply default to -fno-delete-null-pointer-checks but obey +# -fdelete-null-pointer-checks when passed explicitly (and tests that +# depend on this option should do that). + +proc check_effective_target_keeps_null_pointer_checks { } { + if [target_info exists keeps_null_pointer_checks] { + return 1 + } + if { [istarget msp430-*-*] || [istarget cr16-*-*] } { + return 1; + } + return 0 +} + +# Return the autofdo profile wrapper + +# Linux by default allows 516KB of perf event buffers +# in /proc/sys/kernel/perf_event_mlock_kb +# Each individual perf tries to grab it +# This causes problems with parallel test suite runs. Instead +# limit us to 8 pages (32K), which should be good enough +# for the small test programs. With the default settings +# this allows parallelism of 16 and higher of parallel gcc-auto-profile +proc profopt-perf-wrapper { } { + global srcdir + return "$srcdir/../config/i386/gcc-auto-profile -o perf.data -m8 " +} + +# Return true if profiling is supported on the target. + +proc check_profiling_available { test_what } { + verbose "Profiling argument is <$test_what>" 1 + + # These conditions depend on the argument so examine them before + # looking at the cache variable. + + # Tree profiling requires TLS runtime support. + if { $test_what == "-fprofile-generate" } { + if { ![check_effective_target_tls_runtime] } { + return 0 + } + } + + if { $test_what == "-fauto-profile" } { + if { !([istarget i?86-*-linux*] || [istarget x86_64-*-linux*]) } { + verbose "autofdo only supported on linux" + return 0 + } + # not cross compiling? + if { ![isnative] } { + verbose "autofdo not supported for non native builds" + return 0 + } + set event [profopt-perf-wrapper] + if {$event == "" } { + verbose "autofdo not supported" + return 0 + } + global srcdir + set status [remote_exec host "$srcdir/../config/i386/gcc-auto-profile" "true -v >/dev/null"] + if { [lindex $status 0] != 0 } { + verbose "autofdo not supported because perf does not work" + return 0 + } + + # no good way to check this in advance -- check later instead. + #set status [remote_exec host "create_gcov" "2>/dev/null"] + #if { [lindex $status 0] != 255 } { + # verbose "autofdo not supported due to missing create_gcov" + # return 0 + #} + } + + # Support for -p on solaris2 relies on mcrt1.o which comes with the + # vendor compiler. We cannot reliably predict the directory where the + # vendor compiler (and thus mcrt1.o) is installed so we can't + # necessarily find mcrt1.o even if we have it. + if { [istarget *-*-solaris2*] && $test_what == "-p" } { + return 0 + } + + # We don't yet support profiling for MIPS16. + if { [istarget mips*-*-*] + && ![check_effective_target_nomips16] + && ($test_what == "-p" || $test_what == "-pg") } { + return 0 + } + + # MinGW does not support -p. + if { [istarget *-*-mingw*] && $test_what == "-p" } { + return 0 + } + + # cygwin does not support -p. + if { [istarget *-*-cygwin*] && $test_what == "-p" } { + return 0 + } + + # uClibc does not have gcrt1.o. + if { [check_effective_target_uclibc] + && ($test_what == "-p" || $test_what == "-pg") } { + return 0 + } + + # Now examine the cache variable. + set profiling_working \ + [check_cached_effective_target profiling_available { + # Some targets don't have any implementation of __bb_init_func or are + # missing other needed machinery. + if {[istarget aarch64*-*-elf] + || [istarget am3*-*-linux*] + || [istarget amdgcn-*-*] + || [istarget arm*-*-eabi*] + || [istarget arm*-*-elf] + || [istarget arm*-*-symbianelf*] + || [istarget avr-*-*] + || [istarget bfin-*-*] + || [istarget cris-*-*] + || [istarget crisv32-*-*] + || [istarget csky-*-elf] + || [istarget fido-*-elf] + || [istarget h8300-*-*] + || [istarget lm32-*-*] + || [istarget m32c-*-elf] + || [istarget m68k-*-elf] + || [istarget m68k-*-uclinux*] + || [istarget mips*-*-elf*] + || [istarget mmix-*-*] + || [istarget mn10300-*-elf*] + || [istarget moxie-*-elf*] + || [istarget msp430-*-*] + || [istarget nds32*-*-elf] + || [istarget nios2-*-elf] + || [istarget nvptx-*-*] + || [istarget powerpc-*-eabi*] + || [istarget powerpc-*-elf] + || [istarget pru-*-*] + || [istarget rx-*-*] + || [istarget tic6x-*-elf] + || [istarget visium-*-*] + || [istarget xstormy16-*] + || [istarget xtensa*-*-elf] + || [istarget *-*-rtems*] + || [istarget *-*-vxworks*] } { + return 0 + } else { + return 1 + } + }] + + # -pg link test result can't be cached since it may change between + # runs. + if { $profiling_working == 1 + && ![check_no_compiler_messages_nocache profiling executable { + int main() { return 0; } } "-pg"] } { + set profiling_working 0 + } + + return $profiling_working +} + +# Check to see if a target is "freestanding". This is as per the definition +# in Section 4 of C99 standard. Effectively, it is a target which supports no +# extra headers or libraries other than what is considered essential. +proc check_effective_target_freestanding { } { + if { [istarget nvptx-*-*] } { + return 1 + } + return 0 +} + +# Check to see that file I/O functions are available. +proc check_effective_target_fileio { } { + return [check_no_compiler_messages fileio_available executable { +#include +int main() { + char *n = tmpnam (NULL); + FILE *f = fopen (n, "w"); + fclose (f); + remove (n); + return 0; +} } ""] +} + +# Return 1 if target has packed layout of structure members by +# default, 0 otherwise. Note that this is slightly different than +# whether the target has "natural alignment": both attributes may be +# false. + +proc check_effective_target_default_packed { } { + return [check_no_compiler_messages default_packed assembly { + struct x { char a; long b; } c; + int s[sizeof (c) == sizeof (char) + sizeof (long) ? 1 : -1]; + }] +} + +# Return 1 if target has PCC_BITFIELD_TYPE_MATTERS defined. See +# documentation, where the test also comes from. + +proc check_effective_target_pcc_bitfield_type_matters { } { + # PCC_BITFIELD_TYPE_MATTERS isn't just about unnamed or empty + # bitfields, but let's stick to the example code from the docs. + return [check_no_compiler_messages pcc_bitfield_type_matters assembly { + struct foo1 { char x; char :0; char y; }; + struct foo2 { char x; int :0; char y; }; + int s[sizeof (struct foo1) != sizeof (struct foo2) ? 1 : -1]; + }] +} + +# Add to FLAGS all the target-specific flags needed to use thread-local storage. + +proc add_options_for_tls { flags } { + # On Solaris 9, __tls_get_addr/___tls_get_addr only lives in + # libthread, so always pass -pthread for native TLS. Same for AIX. + # Need to duplicate native TLS check from + # check_effective_target_tls_native to avoid recursion. + if { ([istarget powerpc-ibm-aix*]) && + [check_no_messages_and_pattern tls_native "!emutls" assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] } { + return "-pthread [g++_link_flags [get_multilibs "-pthread"] ] $flags " + } + return $flags +} + +# Return 1 if indirect jumps are supported, 0 otherwise. + +proc check_effective_target_indirect_jumps {} { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if nonlocal goto is supported, 0 otherwise. + +proc check_effective_target_nonlocal_goto {} { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if global constructors are supported, 0 otherwise. + +proc check_effective_target_global_constructor {} { + if { [istarget nvptx-*-*] + || [istarget amdgcn-*-*] + || [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if taking label values is supported, 0 otherwise. + +proc check_effective_target_label_values {} { + if { [istarget nvptx-*-*] || [target_info exists gcc,no_label_values] } { + return 0 + } + + return 1 +} + +# Return 1 if builtin_return_address and builtin_frame_address are +# supported, 0 otherwise. + +proc check_effective_target_return_address {} { + if { [istarget nvptx-*-*] } { + return 0 + } + # No notion of return address in eBPF. + if { [istarget bpf-*-*] } { + return 0 + } + # It could be supported on amdgcn, but isn't yet. + if { [istarget amdgcn*-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if the assembler does not verify function types against +# calls, 0 otherwise. Such verification will typically show up problems +# with K&R C function declarations. + +proc check_effective_target_untyped_assembly {} { + if { [istarget nvptx-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if alloca is supported, 0 otherwise. + +proc check_effective_target_alloca {} { + if { [istarget nvptx-*-*] } { + return [check_no_compiler_messages alloca assembly { + void f (void*); + void g (int n) { f (__builtin_alloca (n)); } + }] + } + return 1 +} + +# Return 1 if thread local storage (TLS) is supported, 0 otherwise. + +proc check_effective_target_tls {} { + return [check_no_compiler_messages tls assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] +} + +# Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise. + +proc check_effective_target_tls_native {} { + # VxWorks uses emulated TLS machinery, but with non-standard helper + # functions, so we fail to automatically detect it. + if { [istarget *-*-vxworks*] } { + return 0 + } + + return [check_no_messages_and_pattern tls_native "!emutls" assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] +} + +# Return 1 if *emulated* thread local storage (TLS) is supported, 0 otherwise. + +proc check_effective_target_tls_emulated {} { + # VxWorks uses emulated TLS machinery, but with non-standard helper + # functions, so we fail to automatically detect it. + if { [istarget *-*-vxworks*] } { + return 1 + } + + return [check_no_messages_and_pattern tls_emulated "emutls" assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] +} + +# Return 1 if TLS executables can run correctly, 0 otherwise. + +proc check_effective_target_tls_runtime {} { + return [check_runtime tls_runtime { + __thread int thr __attribute__((tls_model("global-dynamic"))) = 0; + int main (void) { return thr; } + } [add_options_for_tls ""]] +} + +# Return 1 if atomic compare-and-swap is supported on 'int' + +proc check_effective_target_cas_char {} { + return [check_no_compiler_messages cas_char assembly { + #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 + #error unsupported + #endif + } ""] +} + +proc check_effective_target_cas_int {} { + return [check_no_compiler_messages cas_int assembly { + #if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 + /* ok */ + #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + /* ok */ + #else + #error unsupported + #endif + } ""] +} + +# Return 1 if -ffunction-sections is supported, 0 otherwise. + +proc check_effective_target_function_sections {} { + # Darwin has its own scheme and silently accepts -ffunction-sections. + if { [istarget *-*-darwin*] } { + return 0 + } + + return [check_no_compiler_messages functionsections assembly { + void foo (void) { } + } "-ffunction-sections"] +} + +# Return 1 if instruction scheduling is available, 0 otherwise. + +proc check_effective_target_scheduling {} { + return [check_no_compiler_messages scheduling object { + void foo (void) { } + } "-fschedule-insns"] +} + +# Return 1 if trapping arithmetic is available, 0 otherwise. + +proc check_effective_target_trapping {} { + return [check_no_compiler_messages trapping object { + int add (int a, int b) { return a + b; } + } "-ftrapv"] +} + +# Return 1 if compilation with -fgraphite is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fgraphite {} { + return [check_no_compiler_messages fgraphite object { + void foo (void) { } + } "-O1 -fgraphite"] +} + +# Return 1 if compiled with --enable-offload-targets= +# This affects host compilation as ENABLE_OFFLOAD then evaluates to true. +proc check_effective_target_offloading_enabled {} { + return [check_configured_with "--enable-offload-targets"] +} + +# Return 1 if compilation with -fopenacc is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fopenacc {} { + # nvptx/amdgcn can be built with the device-side bits of openacc, but it + # does not make sense to test it as an openacc host. + if [istarget nvptx-*-*] { return 0 } + if [istarget amdgcn-*-*] { return 0 } + + return [check_no_compiler_messages fopenacc object { + void foo (void) { } + } "-fopenacc"] +} + +# Return 1 if compilation with -fopenmp is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fopenmp {} { + # nvptx/amdgcn can be built with the device-side bits of libgomp, but it + # does not make sense to test it as an openmp host. + if [istarget nvptx-*-*] { return 0 } + if [istarget amdgcn-*-*] { return 0 } + + return [check_no_compiler_messages fopenmp object { + void foo (void) { } + } "-fopenmp"] +} + +# Return 1 if compilation with -fgnu-tm is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fgnu_tm {} { + return [check_no_compiler_messages fgnu_tm object { + void foo (void) { } + } "-fgnu-tm"] +} + +# Return 1 if the target supports mmap, 0 otherwise. + +proc check_effective_target_mmap {} { + return [check_function_available "mmap"] +} + +# Return 1 if the target supports dlopen, 0 otherwise. +proc check_effective_target_dlopen {} { + return [check_no_compiler_messages dlopen executable { + #include + int main(void) { dlopen ("dummy.so", RTLD_NOW); } + } [add_options_for_dlopen ""]] +} + +proc add_options_for_dlopen { flags } { + return "$flags -ldl" +} + +# Return 1 if the target supports clone, 0 otherwise. +proc check_effective_target_clone {} { + return [check_function_available "clone"] +} + +# Return 1 if the target supports setrlimit, 0 otherwise. +proc check_effective_target_setrlimit {} { + # Darwin has non-posix compliant RLIMIT_AS + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_function_available "setrlimit"] +} + +# Return 1 if the target supports gettimeofday, 0 otherwise. +proc check_effective_target_gettimeofday {} { + return [check_function_available "gettimeofday"] +} + +# Return 1 if the target supports swapcontext, 0 otherwise. +proc check_effective_target_swapcontext {} { + return [check_no_compiler_messages swapcontext executable { + #include + int main (void) + { + ucontext_t orig_context,child_context; + if (swapcontext(&child_context, &orig_context) < 0) { } + } + }] +} + +# Return 1 if the target supports POSIX threads, 0 otherwise. +proc check_effective_target_pthread {} { + return [check_no_compiler_messages pthread object { + #include + void foo (void) { } + } "-pthread"] +} + +# Return 1 if compilation with -gstabs is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_stabs {} { + return [check_no_compiler_messages stabs object { + void foo (void) { } + } "-gstabs"] +} + +# Return 1 if compilation with -mpe-aligned-commons is error-free +# for trivial code, 0 otherwise. + +proc check_effective_target_pe_aligned_commons {} { + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + return [check_no_compiler_messages pe_aligned_commons object { + int foo; + } "-mpe-aligned-commons"] + } + return 0 +} + +# Return 1 if the target supports -static +proc check_effective_target_static {} { + if { [istarget arm*-*-uclinuxfdpiceabi] } { + return 0; + } + return [check_no_compiler_messages static executable { + int main (void) { return 0; } + } "-static"] +} + +# Return 1 if the target supports -fstack-protector +proc check_effective_target_fstack_protector {} { + return [check_runtime fstack_protector { + #include + int main (int argc, char *argv[]) { + char buf[64]; + return !strcpy (buf, strrchr (argv[0], '/')); + } + } "-fstack-protector"] +} + +# Return 1 if the target supports -fstack-check or -fstack-check=$stack_kind +proc check_stack_check_available { stack_kind } { + if [string match "" $stack_kind] then { + set stack_opt "-fstack-check" + } else { set stack_opt "-fstack-check=$stack_kind" } + + return [check_no_compiler_messages stack_check_$stack_kind executable { + int main (void) { return 0; } + } "$stack_opt"] +} + +# Return 1 if compilation with -freorder-blocks-and-partition is error-free +# for trivial code, 0 otherwise. As some targets (ARM for example) only +# warn when -fprofile-use is also supplied we test that combination too. + +proc check_effective_target_freorder {} { + if { [check_no_compiler_messages freorder object { + void foo (void) { } + } "-freorder-blocks-and-partition"] + && [check_no_compiler_messages fprofile_use_freorder object { + void foo (void) { } + } "-fprofile-use -freorder-blocks-and-partition -Wno-missing-profile"] } { + return 1 + } + return 0 +} + +# Return 1 if -fpic and -fPIC are supported, as in no warnings or errors +# emitted, 0 otherwise. Whether a shared library can actually be built is +# out of scope for this test. + +proc check_effective_target_fpic { } { + # Note that M68K has a multilib that supports -fpic but not + # -fPIC, so we need to check both. We test with a program that + # requires GOT references. + foreach arg {fpic fPIC} { + if [check_no_compiler_messages $arg object { + extern int foo (void); extern int bar; + int baz (void) { return foo () + bar; } + } "-$arg"] { + return 1 + } + } + return 0 +} + +# On AArch64, if -fpic is not supported, then we will fall back to -fPIC +# silently. So, we can't rely on above "check_effective_target_fpic" as it +# assumes compiler will give warning if -fpic not supported. Here we check +# whether binutils supports those new -fpic relocation modifiers, and assume +# -fpic is supported if there is binutils support. GCC configuration will +# enable -fpic for AArch64 in this case. +# +# "check_effective_target_aarch64_small_fpic" is dedicated for checking small +# memory model -fpic relocation types. + +proc check_effective_target_aarch64_small_fpic { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_small_fpic object { + void foo (void) { asm ("ldr x0, [x2, #:gotpage_lo15:globalsym]"); } + }] + } else { + return 0 + } +} + +# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize +# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported +# in binutils since 2015-03-04 as PR gas/17843. +# +# This test directive make sure binutils support all features needed by TLS LE +# under -mtls-size=32 on AArch64. + +proc check_effective_target_aarch64_tlsle32 { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_tlsle32 object { + void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); } + }] + } else { + return 0 + } +} + +# Return 1 if -shared is supported, as in no warnings or errors +# emitted, 0 otherwise. + +proc check_effective_target_shared { } { + # Note that M68K has a multilib that supports -fpic but not + # -fPIC, so we need to check both. We test with a program that + # requires GOT references. + return [check_no_compiler_messages shared executable { + extern int foo (void); extern int bar; + int baz (void) { return foo () + bar; } + } "-shared -fpic"] +} + +# Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise. + +proc check_effective_target_pie { } { + if { [istarget *-*-darwin\[912\]*] + || [istarget *-*-dragonfly*] + || [istarget *-*-freebsd*] + || [istarget *-*-linux*] + || [istarget arm*-*-uclinuxfdpiceabi] + || [istarget *-*-gnu*] + || [istarget *-*-amdhsa]} { + return 1; + } + if { [istarget *-*-solaris2.1\[1-9\]*] } { + # Full PIE support was added in Solaris 11.3, but gcc errors out + # if missing, so check for that. + return [check_no_compiler_messages pie executable { + int main (void) { return 0; } + } "-pie -fpie"] + } + return 0 +} + +# Return true if the target supports -mpaired-single (as used on MIPS). + +proc check_effective_target_mpaired_single { } { + return [check_no_compiler_messages mpaired_single object { + void foo (void) { } + } "-mpaired-single"] +} + +# Return true if the target has access to FPU instructions. + +proc check_effective_target_hard_float { } { + if { [istarget mips*-*-*] } { + return [check_no_compiler_messages hard_float assembly { + #if (defined __mips_soft_float || defined __mips16) + #error __mips_soft_float || __mips16 + #endif + }] + } + + # This proc is actually checking the availabilty of FPU + # support for doubles, so on the RX we must fail if the + # 64-bit double multilib has been selected. + if { [istarget rx-*-*] } { + return 0 + # return [check_no_compiler_messages hard_float assembly { + #if defined __RX_64_BIT_DOUBLES__ + #error __RX_64_BIT_DOUBLES__ + #endif + # }] + } + + # The generic test doesn't work for C-SKY because some cores have + # hard float for single precision only. + if { [istarget csky*-*-*] } { + return [check_no_compiler_messages hard_float assembly { + #if defined __csky_soft_float__ + #error __csky_soft_float__ + #endif + }] + } + + # The generic test equates hard_float with "no call for adding doubles". + return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand { + double a (double b, double c) { return b + c; } + }] +} + +# Return true if the target is a 64-bit MIPS target. + +proc check_effective_target_mips64 { } { + return [check_no_compiler_messages mips64 assembly { + #ifndef __mips64 + #error !__mips64 + #endif + }] +} + +# Return true if the target is a MIPS target that does not produce +# MIPS16 code. + +proc check_effective_target_nomips16 { } { + return [check_no_compiler_messages nomips16 object { + #ifndef __mips + #error !__mips + #else + /* A cheap way of testing for -mflip-mips16. */ + void foo (void) { asm ("addiu $20,$20,1"); } + void bar (void) { asm ("addiu $20,$20,1"); } + #endif + }] +} + +# Add the options needed for MIPS16 function attributes. At the moment, +# we don't support MIPS16 PIC. + +proc add_options_for_mips16_attribute { flags } { + return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))" +} + +# Return true if we can force a mode that allows MIPS16 code generation. +# We don't support MIPS16 PIC, and only support MIPS16 -mhard-float +# for o32 and o64. + +proc check_effective_target_mips16_attribute { } { + return [check_no_compiler_messages mips16_attribute assembly { + #ifdef PIC + #error PIC + #endif + #if defined __mips_hard_float \ + && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \ + && (!defined _ABIO64 || _MIPS_SIM != _ABIO64) + #error __mips_hard_float && (!_ABIO32 || !_ABIO64) + #endif + } [add_options_for_mips16_attribute ""]] +} + +# Return 1 if the target supports long double larger than double when +# using the new ABI, 0 otherwise. + +proc check_effective_target_mips_newabi_large_long_double { } { + return [check_no_compiler_messages mips_newabi_large_long_double object { + int dummy[sizeof(long double) > sizeof(double) ? 1 : -1]; + } "-mabi=64"] +} + +# Return true if the target is a MIPS target that has access +# to the LL and SC instructions. + +proc check_effective_target_mips_llsc { } { + if { ![istarget mips*-*-*] } { + return 0 + } + # Assume that these instructions are always implemented for + # non-elf* targets, via emulation if necessary. + if { ![istarget *-*-elf*] } { + return 1 + } + # Otherwise assume LL/SC support for everything but MIPS I. + return [check_no_compiler_messages mips_llsc assembly { + #if __mips == 1 + #error __mips == 1 + #endif + }] +} + +# Return true if the target is a MIPS target that uses in-place relocations. + +proc check_effective_target_mips_rel { } { + if { ![istarget mips*-*-*] } { + return 0 + } + return [check_no_compiler_messages mips_rel object { + #if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ + || (defined _ABI64 && _MIPS_SIM == _ABI64) + #error _ABIN32 && (_ABIN32 || _ABI64) + #endif + }] +} + +# Return true if the target is a MIPS target that uses the EABI. + +proc check_effective_target_mips_eabi { } { + if { ![istarget mips*-*-*] } { + return 0 + } + return [check_no_compiler_messages mips_eabi object { + #ifndef __mips_eabi + #error !__mips_eabi + #endif + }] +} + +# Return 1 if the current multilib does not generate PIC by default. + +proc check_effective_target_nonpic { } { + return [check_no_compiler_messages nonpic assembly { + #if __PIC__ + #error __PIC__ + #endif + }] +} + +# Return 1 if the current multilib generates PIE by default. + +proc check_effective_target_pie_enabled { } { + return [check_no_compiler_messages pie_enabled assembly { + #ifndef __PIE__ + #error unsupported + #endif + }] +} + +# Return 1 if the target generates -fstack-protector by default. + +proc check_effective_target_fstack_protector_enabled {} { + return [ check_no_compiler_messages fstack_protector_enabled assembly { + #if !defined(__SSP__) && !defined(__SSP_ALL__) && \ + !defined(__SSP_STRONG__) && !defined(__SSP_EXPICIT__) + #error unsupported + #endif + }] +} + +# Return 1 if the target does not use a status wrapper. + +proc check_effective_target_unwrapped { } { + if { [target_info needs_status_wrapper] != "" \ + && [target_info needs_status_wrapper] != "0" } { + return 0 + } + return 1 +} + +# Return true if iconv is supported on the target. In particular IBM1047. + +proc check_iconv_available { test_what } { + global libiconv + + # If the tool configuration file has not set libiconv, try "-liconv" + if { ![info exists libiconv] } { + set libiconv "-liconv" + } + set test_what [lindex $test_what 1] + return [check_runtime_nocache $test_what [subst { + #include + int main (void) + { + iconv_t cd; + + cd = iconv_open ("$test_what", "UTF-8"); + if (cd == (iconv_t) -1) + return 1; + return 0; + } + }] $libiconv] +} + +# Return true if the atomic library is supported on the target. +proc check_effective_target_libatomic_available { } { + return [check_no_compiler_messages libatomic_available executable { + int main (void) { return 0; } + } "-latomic"] +} + +# Return 1 if an ASCII locale is supported on this host, 0 otherwise. + +proc check_ascii_locale_available { } { + return 1 +} + +# Return true if named sections are supported on this target. + +proc check_named_sections_available { } { + return [check_no_compiler_messages named_sections assembly { + int __attribute__ ((section("whatever"))) foo; + }] +} + +# Return true if the "naked" function attribute is supported on this target. + +proc check_effective_target_naked_functions { } { + return [check_no_compiler_messages naked_functions assembly { + void f() __attribute__((naked)); + }] +} + +# Return 1 if the target supports Fortran real kinds larger than real(8), +# 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_large_real { } { + return [check_no_compiler_messages fortran_large_real executable { + ! Fortran + integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1) + real(kind=k) :: x + x = cos (x) + end + }] +} + +# Return 1 if the target supports Fortran real kind real(16), +# 0 otherwise. Contrary to check_effective_target_fortran_large_real +# this checks for Real(16) only; the other returned real(10) if +# both real(10) and real(16) are available. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_real_16 { } { + return [check_no_compiler_messages fortran_real_16 executable { + ! Fortran + real(kind=16) :: x + x = cos (x) + end + }] +} + +# Return 1 if the target supports Fortran real kind 10, +# 0 otherwise. Contrary to check_effective_target_fortran_large_real +# this checks for real(10) only. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_real_10 { } { + return [check_no_compiler_messages fortran_real_10 executable { + ! Fortran + real(kind=10) :: x + x = cos (x) + end + }] +} + +# Return 1 if the target supports Fortran's IEEE modules, +# 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_ieee { flags } { + return [check_no_compiler_messages fortran_ieee executable { + ! Fortran + use, intrinsic :: ieee_features + end + } $flags ] +} + + +# Return 1 if the target supports SQRT for the largest floating-point +# type. (Some targets lack the libm support for this FP type.) +# On most targets, this check effectively checks either whether sqrtl is +# available or on __float128 systems whether libquadmath is installed, +# which provides sqrtq. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_largest_fp_has_sqrt { } { + return [check_no_compiler_messages fortran_largest_fp_has_sqrt executable { + ! Fortran + use iso_fortran_env, only: real_kinds + integer,parameter:: maxFP = real_kinds(ubound(real_kinds,dim=1)) + real(kind=maxFP), volatile :: x + x = 2.0_maxFP + x = sqrt (x) + end + }] +} + + +# Return 1 if the target supports Fortran integer kinds larger than +# integer(8), 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_large_int { } { + return [check_no_compiler_messages fortran_large_int executable { + ! Fortran + integer,parameter :: k = selected_int_kind (range (0_8) + 1) + integer(kind=k) :: i + end + }] +} + +# Return 1 if the target supports Fortran integer(16), 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_integer_16 { } { + return [check_no_compiler_messages fortran_integer_16 executable { + ! Fortran + integer(16) :: i + end + }] +} + +# Return 1 if we can statically link libgfortran, 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_static_libgfortran { } { + return [check_no_compiler_messages static_libgfortran executable { + ! Fortran + print *, 'test' + end + } "-static"] +} + +# Return 1 if we can use the -rdynamic option, 0 otherwise. + +proc check_effective_target_rdynamic { } { + return [check_no_compiler_messages rdynamic executable { + int main() { return 0; } + } "-rdynamic"] +} + +proc check_linker_plugin_available { } { + return [check_no_compiler_messages_nocache linker_plugin executable { + int main() { return 0; } + } "-flto -fuse-linker-plugin"] +} + +# Return 1 if the target OS supports running SSE executables, 0 +# otherwise. Cache the result. + +proc check_sse_os_support_available { } { + return [check_cached_effective_target sse_os_support_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + expr 1 + } + }] +} + +# Return 1 if the target OS supports running AVX executables, 0 +# otherwise. Cache the result. + +proc check_avx_os_support_available { } { + return [check_cached_effective_target avx_os_support_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + # Check that OS has AVX and SSE saving enabled. + check_runtime_nocache avx_os_support_available { + int main () + { + unsigned int eax, edx; + + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + return (eax & 0x06) != 0x06; + } + } "" + } + }] +} + +# Return 1 if the target OS supports running AVX executables, 0 +# otherwise. Cache the result. + +proc check_avx512_os_support_available { } { + return [check_cached_effective_target avx512_os_support_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + # Check that OS has AVX512, AVX and SSE saving enabled. + check_runtime_nocache avx512_os_support_available { + int main () + { + unsigned int eax, edx; + + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + return (eax & 0xe6) != 0xe6; + } + } "" + } + }] +} + +# Return 1 if the target supports executing SSE instructions, 0 +# otherwise. Cache the result. + +proc check_sse_hw_available { } { + return [check_cached_effective_target sse_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache sse_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return !(edx & bit_SSE); + } + } "" + } + }] +} + +# Return 1 if the target supports executing SSE2 instructions, 0 +# otherwise. Cache the result. + +proc check_sse2_hw_available { } { + return [check_cached_effective_target sse2_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache sse2_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return !(edx & bit_SSE2); + } + } "" + } + }] +} + +# Return 1 if the target supports executing SSE4 instructions, 0 +# otherwise. Cache the result. + +proc check_sse4_hw_available { } { + return [check_cached_effective_target sse4_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache sse4_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return !(ecx & bit_SSE4_2); + } + } "" + } + }] +} + +# Return 1 if the target supports executing AVX instructions, 0 +# otherwise. Cache the result. + +proc check_avx_hw_available { } { + return [check_cached_effective_target avx_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache avx_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return ((ecx & (bit_AVX | bit_OSXSAVE)) + != (bit_AVX | bit_OSXSAVE)); + } + } "" + } + }] +} + +# Return 1 if the target supports executing AVX2 instructions, 0 +# otherwise. Cache the result. + +proc check_avx2_hw_available { } { + return [check_cached_effective_target avx2_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } { + expr 0 + } else { + check_runtime_nocache avx2_hw_available { + #include + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid_max (0, NULL) < 7) + return 1; + + __cpuid (1, eax, ebx, ecx, edx); + + if (!(ecx & bit_OSXSAVE)) + return 1; + + __cpuid_count (7, 0, eax, ebx, ecx, edx); + + return !(ebx & bit_AVX2); + } + } "" + } + }] +} + +# Return 1 if the target supports executing AVX512 foundation instructions, 0 +# otherwise. Cache the result. + +proc check_avx512f_hw_available { } { + return [check_cached_effective_target avx512f_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } { + expr 0 + } else { + check_runtime_nocache avx512f_hw_available { + #include + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid_max (0, NULL) < 7) + return 1; + + __cpuid (1, eax, ebx, ecx, edx); + + if (!(ecx & bit_OSXSAVE)) + return 1; + + __cpuid_count (7, 0, eax, ebx, ecx, edx); + + return !(ebx & bit_AVX512F); + } + } "" + } + }] +} + +# Return 1 if the target supports running SSE executables, 0 otherwise. + +proc check_effective_target_sse_runtime { } { + if { [check_effective_target_sse] + && [check_sse_hw_available] + && [check_sse_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running SSE2 executables, 0 otherwise. + +proc check_effective_target_sse2_runtime { } { + if { [check_effective_target_sse2] + && [check_sse2_hw_available] + && [check_sse_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running SSE4 executables, 0 otherwise. + +proc check_effective_target_sse4_runtime { } { + if { [check_effective_target_sse4] + && [check_sse4_hw_available] + && [check_sse_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running AVX executables, 0 otherwise. + +proc check_effective_target_avx_runtime { } { + if { [check_effective_target_avx] + && [check_avx_hw_available] + && [check_avx_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running AVX2 executables, 0 otherwise. + +proc check_effective_target_avx2_runtime { } { + if { [check_effective_target_avx2] + && [check_avx2_hw_available] + && [check_avx_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running AVX512f executables, 0 otherwise. + +proc check_effective_target_avx512f_runtime { } { + if { [check_effective_target_avx512f] + && [check_avx512f_hw_available] + && [check_avx512_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if bmi2 instructions can be compiled. +proc check_effective_target_bmi2 { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages bmi2 object { + unsigned int + _bzhi_u32 (unsigned int __X, unsigned int __Y) + { + return __builtin_ia32_bzhi_si (__X, __Y); + } + } "-mbmi2" ] +} + +# Return 1 if the target supports executing MIPS Paired-Single instructions, +# 0 otherwise. Cache the result. + +proc check_mpaired_single_hw_available { } { + return [check_cached_effective_target mpaired_single_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget mips*-*-*]) } { + expr 0 + } else { + check_runtime_nocache mpaired_single_hw_available { + int main() + { + asm volatile ("pll.ps $f2,$f4,$f6"); + return 0; + } + } "" + } + }] +} + +# Return 1 if the target supports executing Loongson vector instructions, +# 0 otherwise. Cache the result. + +proc check_mips_loongson_mmi_hw_available { } { + return [check_cached_effective_target mips_loongson_mmi_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget mips*-*-*]) } { + expr 0 + } else { + check_runtime_nocache mips_loongson_mmi_hw_available { + #include + int main() + { + asm volatile ("paddw $f2,$f4,$f6"); + return 0; + } + } "-mloongson-mmi" + } + }] +} + +# Return 1 if the target supports executing MIPS MSA instructions, 0 +# otherwise. Cache the result. + +proc check_mips_msa_hw_available { } { + return [check_cached_effective_target mips_msa_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget mips*-*-*]) } { + expr 0 + } else { + check_runtime_nocache mips_msa_hw_available { + #if !defined(__mips_msa) + #error "MSA NOT AVAIL" + #else + #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)) + #error "MSA NOT AVAIL FOR ISA REV < 2" + #endif + #if !defined(__mips_hard_float) + #error "MSA HARD_FLOAT REQUIRED" + #endif + #if __mips_fpr != 64 + #error "MSA 64-bit FPR REQUIRED" + #endif + #include + + int main() + { + v8i16 v = __builtin_msa_ldi_h (0); + v[0] = 0; + return v[0]; + } + #endif + } "-mmsa" + } + }] +} + +# Return 1 if the target supports running MIPS Paired-Single +# executables, 0 otherwise. + +proc check_effective_target_mpaired_single_runtime { } { + if { [check_effective_target_mpaired_single] + && [check_mpaired_single_hw_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running Loongson executables, 0 otherwise. + +proc check_effective_target_mips_loongson_mmi_runtime { } { + if { [check_effective_target_mips_loongson_mmi] + && [check_mips_loongson_mmi_hw_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running MIPS MSA executables, 0 otherwise. + +proc check_effective_target_mips_msa_runtime { } { + if { [check_effective_target_mips_msa] + && [check_mips_msa_hw_available] } { + return 1 + } + return 0 +} + +# Return 1 if we are compiling for 64-bit PowerPC but we do not use direct +# move instructions for moves from GPR to FPR. + +proc check_effective_target_powerpc64_no_dm { } { + # The "mulld" checks if we are generating PowerPC64 code. The "lfd" + # checks if we do not use direct moves, but use the old-fashioned + # slower move-via-the-stack. + return [check_no_messages_and_pattern powerpc64_no_dm \ + {\mmulld\M.*\mlfd} assembly { + double f(long long x) { return x*x; } + } {-O2}] +} + +# Return 1 if the target supports the __builtin_cpu_supports built-in, +# including having a new enough library to support the test. Cache the result. +# Require at least a power7 to run on. + +proc check_ppc_cpu_supports_hw_available { } { + return [check_cached_effective_target ppc_cpu_supports_hw_available { + # Some simulators are known to not support VSX/power8 instructions. + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mvsx" + check_runtime_nocache ppc_cpu_supports_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("xxlor vs0,vs0,vs0"); + #else + asm volatile ("xxlor 0,0,0"); + #endif + if (!__builtin_cpu_supports ("vsx")) + return 1; + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing 750CL paired-single instructions, 0 +# otherwise. Cache the result. + +proc check_750cl_hw_available { } { + return [check_cached_effective_target 750cl_hw_available { + # If this is not the right target then we can skip the test. + if { ![istarget powerpc-*paired*] } { + expr 0 + } else { + check_runtime_nocache 750cl_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("ps_mul v0,v0,v0"); + #else + asm volatile ("ps_mul 0,0,0"); + #endif + return 0; + } + } "-mpaired" + } + }] +} + +# Return 1 if the target supports executing power8 vector instructions, 0 +# otherwise. Cache the result. + +proc check_p8vector_hw_available { } { + return [check_cached_effective_target p8vector_hw_available { + # Some simulators are known to not support VSX/power8 instructions. + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mpower8-vector" + check_runtime_nocache p8vector_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("xxlorc vs0,vs0,vs0"); + #else + asm volatile ("xxlorc 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing power9 vector instructions, 0 +# otherwise. Cache the result. + +proc check_p9vector_hw_available { } { + return [check_cached_effective_target p9vector_hw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin. + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mpower9-vector" + check_runtime_nocache p9vector_hw_available { + int main() + { + long e = -1; + vector double v = (vector double) { 0.0, 0.0 }; + asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v)); + return e; + } + } $options + } + }] +} + +# Return 1 if the PowerPC target generates PC-relative instructions +# automatically for targets that support PC-relative instructions. +proc check_effective_target_powerpc_pcrel { } { + return [check_no_messages_and_pattern powerpc_pcrel \ + {\mpla\M} assembly { + static unsigned short s; + unsigned short *p_foo (void) { return &s; } + } {-O2 -mcpu=power10}] +} + +# Return 1 if the PowerPC target generates prefixed instructions automatically +# for targets that support prefixed instructions. +proc check_effective_target_powerpc_prefixed_addr { } { + return [check_no_messages_and_pattern powerpc_prefixed_addr \ + {\mplwz\M} assembly { + unsigned int foo (unsigned int *p) { return p[0x12345]; } + } {-O2 -mcpu=power10}] +} + +# Return 1 if the target supports executing power9 modulo instructions, 0 +# otherwise. Cache the result. + +proc check_p9modulo_hw_available { } { + return [check_cached_effective_target p9modulo_hw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin. + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mmodulo" + check_runtime_nocache p9modulo_hw_available { + int main() + { + int i = 5, j = 3, r = -1; + asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j)); + return (r == 2); + } + } $options + } + }] +} + + +# Return 1 if the target supports executing power10 instructions, 0 otherwise. +# Cache the result. It is assumed that if a simulator does not support the +# power10 instructions, that it will generate an error and this test will fail. + +proc check_power10_hw_available { } { + return [check_cached_effective_target power10_hw_available { + check_runtime_nocache power10_hw_available { + int main() + { + /* Set e first and use +r to check if pli actually works. */ + long e = -1; + asm ("pli %0,%1" : "+r" (e) : "n" (0x12345)); + if (e == 0x12345) + return 0; + return 1; + } + } "-mcpu=power10" + }] +} + +# Return 1 if the target supports executing MMA instructions, 0 otherwise. +# Cache the result. It is assumed that if a simulator does not support the +# MMA instructions, that it will generate an error and this test will fail. + +proc check_ppc_mma_hw_available { } { + return [check_cached_effective_target ppc_mma_hw_available { + check_runtime_nocache ppc_mma_hw_available { + #include + typedef double v4sf_t __attribute__ ((vector_size (16))); + + int main() + { + __vector_quad acc0; + v4sf_t result[4]; + result[0][0] = 1.0; + __builtin_mma_xxsetaccz (&acc0); + __builtin_mma_disassemble_acc (result, &acc0); + if (result[0][0] != 0.0) + return 1; + return 0; + } + } "-mcpu=power10" + }] +} + +# Return 1 if the target supports executing __float128 on PowerPC via software +# emulation, 0 otherwise. Cache the result. + +proc check_ppc_float128_sw_available { } { + return [check_cached_effective_target ppc_float128_sw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin. + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mfloat128 -mvsx" + check_runtime_nocache ppc_float128_sw_available { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() + { + __float128 z = x + y; + return (z != 3.0q); + } + } $options + } + }] +} + +# Return 1 if the target supports executing __float128 on PowerPC via power9 +# hardware instructions, 0 otherwise. Cache the result. + +proc check_ppc_float128_hw_available { } { + return [check_cached_effective_target ppc_float128_hw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin. + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mfloat128 -mvsx -mfloat128-hardware -mpower9-vector" + check_runtime_nocache ppc_float128_hw_available { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() + { + __float128 z = x + y; + __float128 w = -1.0q; + + __asm__ ("xsaddqp %0,%1,%2" : "+v" (w) : "v" (x), "v" (y)); + return ((z != 3.0q) || (z != w)); + } + } $options + } + }] +} + +# See if the __ieee128 keyword is understood. +proc check_effective_target_ppc_ieee128_ok { } { + return [check_cached_effective_target ppc_ieee128_ok { + # disable on AIX. + if { [istarget *-*-aix*] } { + expr 0 + } else { + set options "-mfloat128" + check_runtime_nocache ppc_ieee128_ok { + int main() + { + __ieee128 a; + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing VSX instructions, 0 +# otherwise. Cache the result. + +proc check_vsx_hw_available { } { + return [check_cached_effective_target vsx_hw_available { + # Some simulators are known to not support VSX instructions. + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mvsx" + check_runtime_nocache vsx_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("xxlor vs0,vs0,vs0"); + #else + asm volatile ("xxlor 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing AltiVec instructions, 0 +# otherwise. Cache the result. + +proc check_vmx_hw_available { } { + return [check_cached_effective_target vmx_hw_available { + # Some simulators are known to not support VMX instructions. + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } { + expr 0 + } else { + # Most targets don't require special flags for this test case, but + # Darwin does. Just to be sure, make sure VSX is not enabled for + # the altivec tests. + if { [istarget *-*-darwin*] + || [istarget *-*-aix*] } { + set options "-maltivec -mno-vsx" + } else { + set options "-mno-vsx" + } + check_runtime_nocache vmx_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("vor v0,v0,v0"); + #else + asm volatile ("vor 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +proc check_ppc_recip_hw_available { } { + return [check_cached_effective_target ppc_recip_hw_available { + # Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb" + check_runtime_nocache ppc_recip_hw_available { + volatile double d_recip, d_rsqrt, d_four = 4.0; + volatile float f_recip, f_rsqrt, f_four = 4.0f; + int main() + { + asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four)); + asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four)); + asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four)); + asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four)); + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing AltiVec and Cell PPU +# instructions, 0 otherwise. Cache the result. + +proc check_effective_target_cell_hw { } { + return [check_cached_effective_target cell_hw_available { + # Some simulators are known to not support VMX and PPU instructions. + if { [istarget powerpc-*-eabi*] } { + expr 0 + } else { + # Most targets don't require special flags for this test + # case, but Darwin and AIX do. + if { [istarget *-*-darwin*] + || [istarget *-*-aix*] } { + set options "-maltivec -mcpu=cell" + } else { + set options "-mcpu=cell" + } + check_runtime_nocache cell_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("vor v0,v0,v0"); + asm volatile ("lvlx v0,r0,r0"); + #else + asm volatile ("vor 0,0,0"); + asm volatile ("lvlx 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing 64-bit instructions, 0 +# otherwise. Cache the result. + +proc check_effective_target_powerpc64 { } { + global powerpc64_available_saved + global tool + + if [info exists powerpc64_available_saved] { + verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2 + } else { + set powerpc64_available_saved 0 + + # Some simulators are known to not support powerpc64 instructions. + if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } { + verbose "check_effective_target_powerpc64 returning 0" 2 + return $powerpc64_available_saved + } + + # Set up, compile, and execute a test program containing a 64-bit + # instruction. Include the current process ID in the file + # names to prevent conflicts with invocations for multiple + # testsuites. + set src ppc[pid].c + set exe ppc[pid].x + + set f [open $src "w"] + puts $f "int main() {" + puts $f "#ifdef __MACH__" + puts $f " asm volatile (\"extsw r0,r0\");" + puts $f "#else" + puts $f " asm volatile (\"extsw 0,0\");" + puts $f "#endif" + puts $f " return 0; }" + close $f + + set opts "additional_flags=-mcpu=G5" + + verbose "check_effective_target_powerpc64 compiling testfile $src" 2 + set lines [${tool}_target_compile $src $exe executable "$opts"] + file delete $src + + if [string match "" $lines] then { + # No error message, compilation succeeded. + set result [${tool}_load "./$exe" "" ""] + set status [lindex $result 0] + remote_file build delete $exe + verbose "check_effective_target_powerpc64 testfile status is <$status>" 2 + + if { $status == "pass" } then { + set powerpc64_available_saved 1 + } + } else { + verbose "check_effective_target_powerpc64 testfile compilation failed" 2 + } + } + + return $powerpc64_available_saved +} + +# GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing +# complex float arguments. This affects gfortran tests that call cabsf +# in libm built by an earlier compiler. Return 0 if libm uses the same +# argument passing as the compiler under test, 1 otherwise. + +proc check_effective_target_broken_cplxf_arg { } { + # Skip the work for targets known not to be affected. + if { ![istarget powerpc*-*-linux*] || ![is-effective-target lp64] } { + return 0 + } + + return [check_cached_effective_target broken_cplxf_arg { + check_runtime_nocache broken_cplxf_arg { + #include + extern void abort (void); + float fabsf (float); + float cabsf (_Complex float); + int main () + { + _Complex float cf; + float f; + cf = 3 + 4.0fi; + f = cabsf (cf); + if (fabsf (f - 5.0) > 0.0001) + /* Yes, it's broken. */ + return 0; + /* All fine, not broken. */ + return 1; + } + } "-lm" + }] +} + +# Return 1 is this is a TI C6X target supporting C67X instructions +proc check_effective_target_ti_c67x { } { + return [check_no_compiler_messages ti_c67x assembly { + #if !defined(_TMS320C6700) + #error !_TMS320C6700 + #endif + }] +} + +# Return 1 is this is a TI C6X target supporting C64X+ instructions +proc check_effective_target_ti_c64xp { } { + return [check_no_compiler_messages ti_c64xp assembly { + #if !defined(_TMS320C6400_PLUS) + #error !_TMS320C6400_PLUS + #endif + }] +} + +# Check if a -march=... option is given, as part of (earlier) options. +proc check_effective_target_march_option { } { + return [check-flags [list "" { *-*-* } { "-march=*" } { "" } ]] +} + +proc check_alpha_max_hw_available { } { + return [check_runtime alpha_max_hw_available { + int main() { return __builtin_alpha_amask(1<<8) != 0; } + }] +} + +# Returns true iff the FUNCTION is available on the target system. +# (This is essentially a Tcl implementation of Autoconf's +# AC_CHECK_FUNC.) + +proc check_function_available { function } { + return [check_no_compiler_messages ${function}_available \ + executable [subst { + #ifdef __cplusplus + extern "C" + #endif + char $function (); + int main () { $function (); } + }] "-fno-builtin" ] +} + +# Returns true iff "fork" is available on the target system. + +proc check_fork_available {} { + return [check_function_available "fork"] +} + +# Returns true iff "mkfifo" is available on the target system. + +proc check_mkfifo_available {} { + if { [istarget *-*-cygwin*] } { + # Cygwin has mkfifo, but support is incomplete. + return 0 + } + + return [check_function_available "mkfifo"] +} + +# Returns true iff "__cxa_atexit" is used on the target system. + +proc check_cxa_atexit_available { } { + return [check_cached_effective_target cxa_atexit_available { + if { [istarget hppa*-*-hpux10*] } { + # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes. + expr 0 + } elseif { [istarget *-*-vxworks] } { + # vxworks doesn't have __cxa_atexit but subsequent test passes. + expr 0 + } else { + check_runtime_nocache cxa_atexit_available { + // C++ + #include + static unsigned int count; + struct X + { + X() { count = 1; } + ~X() + { + if (count != 3) + exit(1); + count = 4; + } + }; + void f() + { + static X x; + } + struct Y + { + Y() { f(); count = 2; } + ~Y() + { + if (count != 2) + exit(1); + count = 3; + } + }; + Y y; + int main() { return 0; } + } + } + }] +} + +proc check_effective_target_objc2 { } { + return [check_no_compiler_messages objc2 object { + #ifdef __OBJC2__ + int dummy[1]; + #else + #error !__OBJC2__ + #endif + }] +} + +proc check_effective_target_next_runtime { } { + return [check_no_compiler_messages objc2 object { + #ifdef __NEXT_RUNTIME__ + int dummy[1]; + #else + #error !__NEXT_RUNTIME__ + #endif + }] +} + +# Return 1 if we're generating code for big-endian memory order. + +proc check_effective_target_be { } { + return [check_no_compiler_messages be object { + int dummy[__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? 1 : -1]; + }] +} + +# Return 1 if we're generating code for little-endian memory order. + +proc check_effective_target_le { } { + return [check_no_compiler_messages le object { + int dummy[__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? 1 : -1]; + }] +} + +# Return 1 if we're generating code for only power8 platforms. + +proc check_effective_target_p8 { } { + return [check_no_compiler_messages_nocache p8 assembly { + #if !(!defined(_ARCH_PWR9) && defined(_ARCH_PWR8)) + #error NO + #endif + } ""] +} + +# Return 1 if we're generating code for power9 or later platforms. + +proc check_effective_target_p9+ { } { + return [check_no_compiler_messages_nocache p9+ assembly { + #if !(defined(_ARCH_PWR9)) + #error NO + #endif + } ""] +} + +# Return 1 if we're generating 32-bit code using default options, 0 +# otherwise. + +proc check_effective_target_ilp32 { } { + return [check_no_compiler_messages ilp32 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 4 + && sizeof (long) == 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating ia32 code using default options, 0 +# otherwise. + +proc check_effective_target_ia32 { } { + return [check_no_compiler_messages ia32 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 4 + && sizeof (long) == 4 ? 1 : -1] = { __i386__ }; + }] +} + +# Return 1 if we're generating x32 code using default options, 0 +# otherwise. + +proc check_effective_target_x32 { } { + return [check_no_compiler_messages x32 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 4 + && sizeof (long) == 4 ? 1 : -1] = { __x86_64__ }; + }] +} + +# Return 1 if we're generating 32-bit integers using default +# options, 0 otherwise. + +proc check_effective_target_int32 { } { + return [check_no_compiler_messages int32 object { + int dummy[sizeof (int) == 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 32-bit or larger integers using default +# options, 0 otherwise. + +proc check_effective_target_int32plus { } { + return [check_no_compiler_messages int32plus object { + int dummy[sizeof (int) >= 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 64-bit long long using default options, +# 0 otherwise. + +proc check_effective_target_longlong64 { } { + return [check_no_compiler_messages longlong64 object { + int dummy[sizeof (long long) == 8 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 32-bit or larger pointers using default +# options, 0 otherwise. + +proc check_effective_target_ptr32plus { } { + # The msp430 has 16-bit or 20-bit pointers. The 20-bit pointer is stored + # in a 32-bit slot when in memory, so sizeof(void *) returns 4, but it + # cannot really hold a 32-bit address, so we always return false here. + if { [istarget msp430-*-*] } { + return 0 + } + + return [check_no_compiler_messages ptr32plus object { + int dummy[sizeof (void *) >= 4 ? 1 : -1]; + }] +} + +# Return 1 if we support 16-bit or larger array and structure sizes +# using default options, 0 otherwise. +# This implies at least a 20-bit address space, as no targets have an address +# space between 16 and 20 bits. + +proc check_effective_target_size20plus { } { + return [check_no_compiler_messages size20plus object { + char dummy[65537L]; + }] +} + +# Return 1 if target supports function pointers, 0 otherwise. + +proc check_effective_target_function_pointers { } { + if { [istarget pru-*-*] } { + return [check_no_compiler_messages func_ptr_avail assembly { + #ifdef __PRU_EABI_GNU__ + #error unsupported + #endif + }] + } + return 1 +} + +# Return 1 if target supports arbitrarily large return values, 0 otherwise. + +proc check_effective_target_large_return_values { } { + if { [istarget pru-*-*] } { + return [check_no_compiler_messages large_return_values assembly { + #ifdef __PRU_EABI_GNU__ + #error unsupported + #endif + }] + } + return 1 +} + +# Return 1 if we support 24-bit or larger array and structure sizes +# using default options, 0 otherwise. +# This implies at least a 32-bit address space, as no targets have an address +# space between 24 and 32 bits. + +proc check_effective_target_size32plus { } { + return [check_no_compiler_messages size32plus object { + char dummy[16777217L]; + }] +} + +# Returns 1 if we're generating 16-bit or smaller integers with the +# default options, 0 otherwise. + +proc check_effective_target_int16 { } { + return [check_no_compiler_messages int16 object { + int dummy[sizeof (int) < 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 64-bit code using default options, 0 +# otherwise. + +proc check_effective_target_lp64 { } { + return [check_no_compiler_messages lp64 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 8 + && sizeof (long) == 8 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 64-bit code using default llp64 options, +# 0 otherwise. + +proc check_effective_target_llp64 { } { + return [check_no_compiler_messages llp64 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 8 + && sizeof (long long) == 8 + && sizeof (long) == 4 ? 1 : -1]; + }] +} + +# Return 1 if long and int have different sizes, +# 0 otherwise. + +proc check_effective_target_long_neq_int { } { + return [check_no_compiler_messages long_ne_int object { + int dummy[sizeof (int) != sizeof (long) ? 1 : -1]; + }] +} + +# Return 1 if int size is equal to float size, +# 0 otherwise. + +proc check_effective_target_int_eq_float { } { + return [check_no_compiler_messages int_eq_float object { + int dummy[sizeof (int) >= sizeof (float) ? 1 : -1]; + }] +} + +# Return 1 if pointer size is equal to long size, +# 0 otherwise. + +proc check_effective_target_ptr_eq_long { } { + # sizeof (void *) == 4 for msp430-elf -mlarge which is equal to + # sizeof (long). Avoid false positive. + if { [istarget msp430-*-*] } { + return 0 + } + return [check_no_compiler_messages ptr_eq_long object { + int dummy[sizeof (void *) == sizeof (long) ? 1 : -1]; + }] +} + +# Return 1 if the target supports long double larger than double, +# 0 otherwise. + +proc check_effective_target_large_long_double { } { + return [check_no_compiler_messages large_long_double object { + int dummy[sizeof(long double) > sizeof(double) ? 1 : -1]; + }] +} + +# Return 1 if the target supports double larger than float, +# 0 otherwise. + +proc check_effective_target_large_double { } { + return [check_no_compiler_messages large_double object { + int dummy[sizeof(double) > sizeof(float) ? 1 : -1]; + }] +} + +# Return 1 if the target supports long double of 128 bits, +# 0 otherwise. + +proc check_effective_target_longdouble128 { } { + return [check_no_compiler_messages longdouble128 object { + int dummy[sizeof(long double) == 16 ? 1 : -1]; + }] +} + +# Return 1 if the target supports long double of 64 bits, +# 0 otherwise. + +proc check_effective_target_longdouble64 { } { + return [check_no_compiler_messages longdouble64 object { + int dummy[sizeof(long double) == 8 ? 1 : -1]; + }] +} + +# Return 1 if the target supports double of 64 bits, +# 0 otherwise. + +proc check_effective_target_double64 { } { + return [check_no_compiler_messages double64 object { + int dummy[sizeof(double) == 8 ? 1 : -1]; + }] +} + +# Return 1 if the target supports double of at least 64 bits, +# 0 otherwise. + +proc check_effective_target_double64plus { } { + return [check_no_compiler_messages double64plus object { + int dummy[sizeof(double) >= 8 ? 1 : -1]; + }] +} + +# Return 1 if the target supports 'w' suffix on floating constant +# 0 otherwise. + +proc check_effective_target_has_w_floating_suffix { } { + set opts "" + if [check_effective_target_c++] { + append opts "-std=gnu++03" + } + return [check_no_compiler_messages w_fp_suffix object { + float dummy = 1.0w; + } "$opts"] +} + +# Return 1 if the target supports 'q' suffix on floating constant +# 0 otherwise. + +proc check_effective_target_has_q_floating_suffix { } { + set opts "" + if [check_effective_target_c++] { + append opts "-std=gnu++03" + } + return [check_no_compiler_messages q_fp_suffix object { + float dummy = 1.0q; + } "$opts"] +} + +# Return 1 if the target supports the _FloatN / _FloatNx type +# indicated in the function name, 0 otherwise. + +proc check_effective_target_float16 {} { + return [check_no_compiler_messages_nocache float16 object { + _Float16 x; + } [add_options_for_float16 ""]] +} + +proc check_effective_target_float32 {} { + return [check_no_compiler_messages_nocache float32 object { + _Float32 x; + } [add_options_for_float32 ""]] +} + +proc check_effective_target_float64 {} { + return [check_no_compiler_messages_nocache float64 object { + _Float64 x; + } [add_options_for_float64 ""]] +} + +proc check_effective_target_float128 {} { + return [check_no_compiler_messages_nocache float128 object { + _Float128 x; + } [add_options_for_float128 ""]] +} + +proc check_effective_target_float32x {} { + return [check_no_compiler_messages_nocache float32x object { + _Float32x x; + } [add_options_for_float32x ""]] +} + +proc check_effective_target_float64x {} { + return [check_no_compiler_messages_nocache float64x object { + _Float64x x; + } [add_options_for_float64x ""]] +} + +proc check_effective_target_float128x {} { + return [check_no_compiler_messages_nocache float128x object { + _Float128x x; + } [add_options_for_float128x ""]] +} + +# Likewise, but runtime support for any special options used as well +# as compile-time support is required. + +proc check_effective_target_float16_runtime {} { + return [check_effective_target_float16] +} + +proc check_effective_target_float32_runtime {} { + return [check_effective_target_float32] +} + +proc check_effective_target_float64_runtime {} { + return [check_effective_target_float64] +} + +proc check_effective_target_float128_runtime {} { + if { ![check_effective_target_float128] } { + return 0 + } + if { [istarget powerpc*-*-*] } { + return [check_effective_target_base_quadfloat_support] + } + return 1 +} + +proc check_effective_target_float32x_runtime {} { + return [check_effective_target_float32x] +} + +proc check_effective_target_float64x_runtime {} { + if { ![check_effective_target_float64x] } { + return 0 + } + if { [istarget powerpc*-*-*] } { + return [check_effective_target_base_quadfloat_support] + } + return 1 +} + +proc check_effective_target_float128x_runtime {} { + return [check_effective_target_float128x] +} + +# Return 1 if the target hardware supports any options added for +# _FloatN and _FloatNx types, 0 otherwise. + +proc check_effective_target_floatn_nx_runtime {} { + if { [istarget powerpc*-*-aix*] } { + return 0 + } + if { [istarget powerpc*-*-*] } { + return [check_effective_target_base_quadfloat_support] + } + return 1 +} + +# Add options needed to use the _FloatN / _FloatNx type indicated in +# the function name. + +proc add_options_for_float16 { flags } { + if { [istarget arm*-*-*] } { + return "$flags -mfp16-format=ieee" + } + return "$flags" +} + +proc add_options_for_float32 { flags } { + return "$flags" +} + +proc add_options_for_float64 { flags } { + return "$flags" +} + +proc add_options_for_float128 { flags } { + return [add_options_for___float128 "$flags"] +} + +proc add_options_for_float32x { flags } { + return "$flags" +} + +proc add_options_for_float64x { flags } { + return [add_options_for___float128 "$flags"] +} + +proc add_options_for_float128x { flags } { + return "$flags" +} + +# Return 1 if the target supports __float128, +# 0 otherwise. + +proc check_effective_target___float128 { } { + if { [istarget powerpc*-*-*] } { + return [check_ppc_float128_sw_available] + } + if { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] } { + return 1 + } + return 0 +} + +proc add_options_for___float128 { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mfloat128 -mvsx" + } + return "$flags" +} + +# Return 1 if the target supports any special run-time requirements +# for __float128 or _Float128, +# 0 otherwise. + +proc check_effective_target_base_quadfloat_support { } { + if { [istarget powerpc*-*-*] } { + return [check_vsx_hw_available] + } + return 1 +} + +# Return 1 if the target supports all four forms of fused multiply-add +# (fma, fms, fnma, and fnms) for both float and double. + +proc check_effective_target_scalar_all_fma { } { + return [istarget aarch64*-*-*] +} + +# Return 1 if the target supports compiling fixed-point, +# 0 otherwise. + +proc check_effective_target_fixed_point { } { + return [check_no_compiler_messages fixed_point object { + _Sat _Fract x; _Sat _Accum y; + }] +} + +# Return 1 if the target supports compiling decimal floating point, +# 0 otherwise. + +proc check_effective_target_dfp_nocache { } { + verbose "check_effective_target_dfp_nocache: compiling source" 2 + set ret [check_no_compiler_messages_nocache dfp object { + float x __attribute__((mode(DD))); + }] + verbose "check_effective_target_dfp_nocache: returning $ret" 2 + return $ret +} + +proc check_effective_target_dfprt_nocache { } { + return [check_runtime_nocache dfprt { + typedef float d64 __attribute__((mode(DD))); + d64 x = 1.2df, y = 2.3dd, z; + int main () { z = x + y; return 0; } + }] +} + +# Return 1 if the target supports compiling Decimal Floating Point, +# 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_dfp { } { + return [check_cached_effective_target dfp { + check_effective_target_dfp_nocache + }] +} + +# Return 1 if the target supports linking and executing Decimal Floating +# Point, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_dfprt { } { + return [check_cached_effective_target dfprt { + check_effective_target_dfprt_nocache + }] +} + +# Return 1 iff target has unsigned plain 'char' by default. + +proc check_effective_target_unsigned_char {} { + return [check_no_compiler_messages unsigned_char assembly { + char ar[(char)-1]; + }] +} + +proc check_effective_target_powerpc_popcntb_ok { } { + return [check_cached_effective_target powerpc_popcntb_ok { + + # Disable on Darwin. + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + check_runtime_nocache powerpc_popcntb_ok { + volatile int r; + volatile int a = 0x12345678; + int main() + { + asm volatile ("popcntb %0,%1" : "=r" (r) : "r" (a)); + return 0; + } + } "-mcpu=power5" + } + }] +} + +# Return 1 if the target supports executing DFP hardware instructions, +# 0 otherwise. Cache the result. + +proc check_dfp_hw_available { } { + return [check_cached_effective_target dfp_hw_available { + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + check_runtime_nocache dfp_hw_available { + volatile _Decimal64 r; + volatile _Decimal64 a = 4.0DD; + volatile _Decimal64 b = 2.0DD; + int main() + { + asm volatile ("dadd %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + asm volatile ("dsub %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + asm volatile ("dmul %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + asm volatile ("ddiv %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + return 0; + } + } "-mcpu=power6 -mhard-float" + } + }] +} + +# Return 1 if the target supports compiling and assembling UCN, 0 otherwise. + +proc check_effective_target_ucn_nocache { } { + # -std=c99 is only valid for C + if [check_effective_target_c] { + set ucnopts "-std=c99" + } else { + set ucnopts "" + } + verbose "check_effective_target_ucn_nocache: compiling source" 2 + set ret [check_no_compiler_messages_nocache ucn object { + int \u00C0; + } $ucnopts] + verbose "check_effective_target_ucn_nocache: returning $ret" 2 + return $ret +} + +# Return 1 if the target supports compiling and assembling UCN, 0 otherwise. +# +# This won't change for different subtargets, so cache the result. + +proc check_effective_target_ucn { } { + return [check_cached_effective_target ucn { + check_effective_target_ucn_nocache + }] +} + +# Return 1 if the target needs a command line argument to enable a SIMD +# instruction set. + +proc check_effective_target_vect_cmdline_needed { } { + global et_vect_cmdline_needed_target_name + + if { ![info exists et_vect_cmdline_needed_target_name] } { + set et_vect_cmdline_needed_target_name "" + } + + # If the target has changed since we set the cached value, clear it. + set current_target [current_target_name] + if { $current_target != $et_vect_cmdline_needed_target_name } { + verbose "check_effective_target_vect_cmdline_needed: `$et_vect_cmdline_needed_target_name' `$current_target'" 2 + set et_vect_cmdline_needed_target_name $current_target + if { [info exists et_vect_cmdline_needed_saved] } { + verbose "check_effective_target_vect_cmdline_needed: removing cached result" 2 + unset et_vect_cmdline_needed_saved + } + } + + return [check_cached_effective_target vect_cmdline_needed { + if { [istarget alpha*-*-*] + || [istarget ia64-*-*] + || (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && ![is-effective-target ia32]) + || ([istarget powerpc*-*-*] + && ([check_effective_target_powerpc_spe] + || [check_effective_target_powerpc_altivec])) + || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis]) + || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) + || [istarget aarch64*-*-*] + || [istarget amdgcn*-*-*]} { + return 0 + } else { + return 1 + }}] +} + +# Return 1 if the target supports hardware vectors of int, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_int { } { + return [check_cached_effective_target_indexed vect_int { + expr { + [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget amdgcn-*-*] + || [istarget sparc*-*-*] + || [istarget alpha*-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_loongson_mmi] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + }}] +} + +# Return 1 if the target supports signed int->float conversion +# + +proc check_effective_target_vect_intfloat_cvt { } { + return [check_cached_effective_target_indexed vect_intfloat_cvt { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports signed double->int conversion +# + +proc check_effective_target_vect_doubleint_cvt { } { + return [check_cached_effective_target_indexed vect_doubleint_cvt { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_no_compiler_messages vect_doubleint_cvt assembly { + #ifdef __tune_atom__ + # error No double vectorizer support. + #endif + }]) + || [istarget aarch64*-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target supports signed int->double conversion +# + +proc check_effective_target_vect_intdouble_cvt { } { + return [check_cached_effective_target_indexed vect_intdouble_cvt { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_no_compiler_messages vect_intdouble_cvt assembly { + #ifdef __tune_atom__ + # error No double vectorizer support. + #endif + }]) + || [istarget aarch64*-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +#Return 1 if we're supporting __int128 for target, 0 otherwise. + +proc check_effective_target_int128 { } { + return [check_no_compiler_messages int128 object { + int dummy[ + #ifndef __SIZEOF_INT128__ + -1 + #else + 1 + #endif + ]; + }] +} + +# Return 1 if the target supports unsigned int->float conversion +# + +proc check_effective_target_vect_uintfloat_cvt { } { + return [check_cached_effective_target_indexed vect_uintfloat_cvt { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] }}] +} + + +# Return 1 if the target supports signed float->int conversion +# + +proc check_effective_target_vect_floatint_cvt { } { + return [check_cached_effective_target_indexed vect_floatint_cvt { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports unsigned float->int conversion +# + +proc check_effective_target_vect_floatuint_cvt { } { + return [check_cached_effective_target_indexed vect_floatuint_cvt { + expr { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if peeling for alignment might be profitable on the target +# + +proc check_effective_target_vect_peeling_profitable { } { + return [check_cached_effective_target_indexed vect_peeling_profitable { + expr { ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [check_effective_target_vect_element_align_preferred] }}] +} + +# Return 1 if the target supports #pragma omp declare simd, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_simd_clones { } { + # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx, + # avx2 and avx512f clone. Only the right clone for the + # specified arch will be chosen, but still we need to at least + # be able to assemble avx512f. + return [check_cached_effective_target_indexed vect_simd_clones { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_effective_target_avx512f]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if this is a AArch64 target supporting big endian +proc check_effective_target_aarch64_big_endian { } { + return [check_no_compiler_messages aarch64_big_endian assembly { + #if !defined(__aarch64__) || !defined(__AARCH64EB__) + #error !__aarch64__ || !__AARCH64EB__ + #endif + }] +} + +# Return 1 if this is a AArch64 target supporting little endian +proc check_effective_target_aarch64_little_endian { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + + return [check_no_compiler_messages aarch64_little_endian assembly { + #if !defined(__aarch64__) || defined(__AARCH64EB__) + #error FOO + #endif + }] +} + +# Return 1 if this is an AArch64 target supporting SVE. +proc check_effective_target_aarch64_sve { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_no_compiler_messages aarch64_sve assembly { + #if !defined (__ARM_FEATURE_SVE) + #error FOO + #endif + }] +} + +# Return 1 if this is an AArch64 target supporting SVE2. +proc check_effective_target_aarch64_sve2 { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_no_compiler_messages aarch64_sve2 assembly { + #if !defined (__ARM_FEATURE_SVE2) + #error FOO + #endif + }] +} + +# Return 1 if this is an AArch64 target only supporting SVE (not SVE2). +proc check_effective_target_aarch64_sve1_only { } { + return [expr { [check_effective_target_aarch64_sve] + && ![check_effective_target_aarch64_sve2] }] +} + +# Return the size in bits of an SVE vector, or 0 if the size is variable. +proc aarch64_sve_bits { } { + return [check_cached_effective_target aarch64_sve_bits { + global tool + + set src dummy[pid].c + set f [open $src "w"] + puts $f "int bits = __ARM_FEATURE_SVE_BITS;" + close $f + set output [${tool}_target_compile $src "" preprocess ""] + file delete $src + + regsub {.*bits = ([^;]*);.*} $output {\1} bits + expr { $bits } + }] +} + +# Return 1 if this is a compiler supporting ARC atomic operations +proc check_effective_target_arc_atomic { } { + return [check_no_compiler_messages arc_atomic assembly { + #if !defined(__ARC_ATOMIC__) + #error FOO + #endif + }] +} + +# Return 1 if this is an arm target using 32-bit instructions +proc check_effective_target_arm32 { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm32 assembly { + #if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__)) + #error !__arm || __thumb__ && !__thumb2__ + #endif + }] +} + +# Return 1 if this is an arm target not using Thumb +proc check_effective_target_arm_nothumb { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm_nothumb assembly { + #if !defined(__arm__) || (defined(__thumb__) || defined(__thumb2__)) + #error !__arm__ || __thumb || __thumb2__ + #endif + }] +} + +# Return 1 if this is a little-endian ARM target +proc check_effective_target_arm_little_endian { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm_little_endian assembly { + #if !defined(__arm__) || !defined(__ARMEL__) + #error !__arm__ || !__ARMEL__ + #endif + }] +} + +# Return 1 if this is an ARM target that only supports aligned vector accesses +proc check_effective_target_arm_vect_no_misalign { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm_vect_no_misalign assembly { + #if !defined(__arm__) \ + || (defined(__ARM_FEATURE_UNALIGNED) \ + && defined(__ARMEL__)) + #error !__arm__ || (__ARMEL__ && __ARM_FEATURE_UNALIGNED) + #endif + }] +} + + +# Return 1 if this is an ARM target supporting -mfloat-abi=soft. Some +# multilibs may be incompatible with this option. + +proc check_effective_target_arm_soft_ok { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_soft_ok executable { + int main() { return 0;} + } "-mfloat-abi=soft"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target supporting -mfpu=vfp with an +# appropriate abi. + +proc check_effective_target_arm_vfp_ok_nocache { } { + global et_arm_vfp_flags + set et_arm_vfp_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"-mfpu=vfp" "-mfpu=vfp -mfloat-abi=softfp" "-mfpu=vfp -mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_vfp_ok object { + #ifndef __ARM_FP + #error __ARM_FP not defined + #endif + } "$flags"] } { + set et_arm_vfp_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_vfp_ok { } { + return [check_cached_effective_target arm_vfp_ok \ + check_effective_target_arm_vfp_ok_nocache] +} + +# Add the options needed to compile code with -mfpu=vfp. We need either +# -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already +# specified by the multilib, use it. + +proc add_options_for_arm_vfp { flags } { + if { ! [check_effective_target_arm_vfp_ok] } { + return "$flags" + } + global et_arm_vfp_flags + return "$flags $et_arm_vfp_flags" +} + +# Return 1 if this is an ARM target supporting -mfpu=vfp3 +# -mfloat-abi=softfp. + +proc check_effective_target_arm_vfp3_ok { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_vfp3_ok object { + int dummy; + } "-mfpu=vfp3 -mfloat-abi=softfp"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target supporting -mfpu=fp-armv8 +# -mfloat-abi=softfp. +proc check_effective_target_arm_v8_vfp_ok {} { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_v8_vfp_ok object { + int foo (void) + { + __asm__ volatile ("vrinta.f32.f32 s0, s0"); + return 0; + } + } "-mfpu=fp-armv8 -mfloat-abi=softfp"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target supporting -mfpu=vfp +# -mfloat-abi=hard. Some multilibs may be incompatible with these +# options. + +proc check_effective_target_arm_hard_vfp_ok { } { + if { [check_effective_target_arm32] + && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } { + return [check_no_compiler_messages arm_hard_vfp_ok executable { + int main() { return 0;} + } "-mfpu=vfp -mfloat-abi=hard"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target defining __ARM_FP. We may need +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_fp_flags to the +# best options to add. + +proc check_effective_target_arm_fp_ok_nocache { } { + global et_arm_fp_flags + set et_arm_fp_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_fp_ok object { + #ifndef __ARM_FP + #error __ARM_FP not defined + #endif + } "$flags"] } { + set et_arm_fp_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp_ok { } { + return [check_cached_effective_target arm_fp_ok \ + check_effective_target_arm_fp_ok_nocache] +} + +# Add the options needed to define __ARM_FP. We need either +# -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already +# specified by the multilib, use it. + +proc add_options_for_arm_fp { flags } { + if { ! [check_effective_target_arm_fp_ok] } { + return "$flags" + } + global et_arm_fp_flags + return "$flags $et_arm_fp_flags" +} + +# Return 1 if this is an ARM target defining __ARM_FP with +# double-precision support. We may need -mfloat-abi=softfp or +# equivalent options. Some multilibs may be incompatible with these +# options. Also set et_arm_fp_dp_flags to the best options to add. + +proc check_effective_target_arm_fp_dp_ok_nocache { } { + global et_arm_fp_dp_flags + set et_arm_fp_dp_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_fp_dp_ok object { + #ifndef __ARM_FP + #error __ARM_FP not defined + #endif + #if ((__ARM_FP & 8) == 0) + #error __ARM_FP indicates that double-precision is not supported + #endif + } "$flags"] } { + set et_arm_fp_dp_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp_dp_ok { } { + return [check_cached_effective_target arm_fp_dp_ok \ + check_effective_target_arm_fp_dp_ok_nocache] +} + +# Add the options needed to define __ARM_FP with double-precision +# support. We need either -mfloat-abi=softfp or -mfloat-abi=hard, but +# if one is already specified by the multilib, use it. + +proc add_options_for_arm_fp_dp { flags } { + if { ! [check_effective_target_arm_fp_dp_ok] } { + return "$flags" + } + global et_arm_fp_dp_flags + return "$flags $et_arm_fp_dp_flags" +} + +# Return 1 if this is an ARM target that supports DSP multiply with +# current multilib flags. + +proc check_effective_target_arm_dsp { } { + return [check_no_compiler_messages arm_dsp assembly { + #ifndef __ARM_FEATURE_DSP + #error not DSP + #endif + #include + int i; + }] +} + +# Return 1 if this is an ARM target that supports unaligned word/halfword +# load/store instructions. + +proc check_effective_target_arm_unaligned { } { + return [check_no_compiler_messages arm_unaligned assembly { + #ifndef __ARM_FEATURE_UNALIGNED + #error no unaligned support + #endif + int i; + }] +} + +# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_crypto_flags to the +# best options to add. + +proc check_effective_target_arm_crypto_ok_nocache { } { + global et_arm_crypto_flags + set et_arm_crypto_flags "" + if { [check_effective_target_arm_v8_neon_ok] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache arm_crypto_ok object { + #include "arm_neon.h" + uint8x16_t + foo (uint8x16_t a, uint8x16_t b) + { + return vaeseq_u8 (a, b); + } + } "$flags"] } { + set et_arm_crypto_flags $flags + return 1 + } + } + } + + return 0 +} + +# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8 + +proc check_effective_target_arm_crypto_ok { } { + return [check_cached_effective_target arm_crypto_ok \ + check_effective_target_arm_crypto_ok_nocache] +} + +# Add options for crypto extensions. +proc add_options_for_arm_crypto { flags } { + if { ! [check_effective_target_arm_crypto_ok] } { + return "$flags" + } + global et_arm_crypto_flags + return "$flags $et_arm_crypto_flags" +} + +# Add the options needed for NEON. We need either -mfloat-abi=softfp +# or -mfloat-abi=hard, but if one is already specified by the +# multilib, use it. Similarly, if a -mfpu option already enables +# NEON, do not add -mfpu=neon. + +proc add_options_for_arm_neon { flags } { + if { ! [check_effective_target_arm_neon_ok] } { + return "$flags" + } + global et_arm_neon_flags + return "$flags $et_arm_neon_flags" +} + +proc add_options_for_arm_v8_vfp { flags } { + if { ! [check_effective_target_arm_v8_vfp_ok] } { + return "$flags" + } + return "$flags -mfpu=fp-armv8 -mfloat-abi=softfp" +} + +proc add_options_for_arm_v8_neon { flags } { + if { ! [check_effective_target_arm_v8_neon_ok] } { + return "$flags" + } + global et_arm_v8_neon_flags + return "$flags $et_arm_v8_neon_flags -march=armv8-a" +} + +# Add the options needed for ARMv8.1 Adv.SIMD. Also adds the ARMv8 NEON +# options for AArch64 and for ARM. + +proc add_options_for_arm_v8_1a_neon { flags } { + if { ! [check_effective_target_arm_v8_1a_neon_ok] } { + return "$flags" + } + global et_arm_v8_1a_neon_flags + return "$flags $et_arm_v8_1a_neon_flags" +} + +# Add the options needed for ARMv8.2 with the scalar FP16 extension. +# Also adds the ARMv8 FP options for ARM and for AArch64. + +proc add_options_for_arm_v8_2a_fp16_scalar { flags } { + if { ! [check_effective_target_arm_v8_2a_fp16_scalar_ok] } { + return "$flags" + } + global et_arm_v8_2a_fp16_scalar_flags + return "$flags $et_arm_v8_2a_fp16_scalar_flags" +} + +# Add the options needed for ARMv8.2 with the FP16 extension. Also adds +# the ARMv8 NEON options for ARM and for AArch64. + +proc add_options_for_arm_v8_2a_fp16_neon { flags } { + if { ! [check_effective_target_arm_v8_2a_fp16_neon_ok] } { + return "$flags" + } + global et_arm_v8_2a_fp16_neon_flags + return "$flags $et_arm_v8_2a_fp16_neon_flags" +} + +proc add_options_for_arm_crc { flags } { + if { ! [check_effective_target_arm_crc_ok] } { + return "$flags" + } + global et_arm_crc_flags + return "$flags $et_arm_crc_flags" +} + +# Add the options needed for NEON. We need either -mfloat-abi=softfp +# or -mfloat-abi=hard, but if one is already specified by the +# multilib, use it. Similarly, if a -mfpu option already enables +# NEON, do not add -mfpu=neon. + +proc add_options_for_arm_neonv2 { flags } { + if { ! [check_effective_target_arm_neonv2_ok] } { + return "$flags" + } + global et_arm_neonv2_flags + return "$flags $et_arm_neonv2_flags" +} + +# Add the options needed for vfp3. +proc add_options_for_arm_vfp3 { flags } { + if { ! [check_effective_target_arm_vfp3_ok] } { + return "$flags" + } + return "$flags -mfpu=vfp3 -mfloat-abi=softfp" +} + +# Return 1 if this is an ARM target supporting -mfpu=neon +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_neon_flags to the +# best options to add. + +proc check_effective_target_arm_neon_ok_nocache { } { + global et_arm_neon_flags + set et_arm_neon_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp" "-mfpu=neon -mfloat-abi=softfp -march=armv7-a" "-mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard -march=armv7-a"} { + if { [check_no_compiler_messages_nocache arm_neon_ok object { + #include + int dummy; + #ifndef __ARM_NEON__ + #error not NEON + #endif + /* Avoid the case where a test adds -mfpu=neon, but the toolchain is + configured for -mcpu=arm926ej-s, for example. */ + #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M' + #error Architecture does not support NEON. + #endif + } "$flags"] } { + set et_arm_neon_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_ok { } { + return [check_cached_effective_target arm_neon_ok \ + check_effective_target_arm_neon_ok_nocache] +} + + +# Return 1 if this is an ARM target supporting the SIMD32 intrinsics +# from arm_acle.h. Some multilibs may be incompatible with these options. +# Also set et_arm_simd32_flags to the best options to add. +# arm_acle.h includes stdint.h which can cause trouble with incompatible +# -mfloat-abi= options. + +proc check_effective_target_arm_simd32_ok_nocache { } { + global et_arm_simd32_flags + set et_arm_simd32_flags "" + foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_simd32_ok object { + #include + int dummy; + #ifndef __ARM_FEATURE_SIMD32 + #error not SIMD32 + #endif + } "$flags"] } { + set et_arm_simd32_flags $flags + return 1 + } + } + + return 0 +} + +proc check_effective_target_arm_simd32_ok { } { + return [check_cached_effective_target arm_simd32_ok \ + check_effective_target_arm_simd32_ok_nocache] +} + +proc add_options_for_arm_simd32 { flags } { + if { ! [check_effective_target_arm_simd32_ok] } { + return "$flags" + } + global et_arm_simd32_flags + return "$flags $et_arm_simd32_flags" +} + +# Return 1 if this is an ARM target supporting the saturation intrinsics +# from arm_acle.h. Some multilibs may be incompatible with these options. +# Also set et_arm_qbit_flags to the best options to add. +# arm_acle.h includes stdint.h which can cause trouble with incompatible +# -mfloat-abi= options. + +proc check_effective_target_arm_qbit_ok_nocache { } { + global et_arm_qbit_flags + set et_arm_qbit_flags "" + foreach flags {"" "-march=armv5te" "-march=armv5te -mfloat-abi=softfp" "-march=armv5te -mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache et_arm_qbit_flags object { + #include + int dummy; + #ifndef __ARM_FEATURE_QBIT + #error not QBIT + #endif + } "$flags"] } { + set et_arm_qbit_flags $flags + return 1 + } + } + + return 0 +} + +proc check_effective_target_arm_qbit_ok { } { + return [check_cached_effective_target et_arm_qbit_flags \ + check_effective_target_arm_qbit_ok_nocache] +} + +proc add_options_for_arm_qbit { flags } { + if { ! [check_effective_target_arm_qbit_ok] } { + return "$flags" + } + global et_arm_qbit_flags + return "$flags $et_arm_qbit_flags" +} + +# Return 1 if this is an ARM target supporting -mfpu=neon without any +# -mfloat-abi= option. Useful in tests where add_options is not +# supported (such as lto tests). + +proc check_effective_target_arm_neon_ok_no_float_abi_nocache { } { + if { [check_effective_target_arm32] } { + foreach flags {"-mfpu=neon"} { + if { [check_no_compiler_messages_nocache arm_neon_ok_no_float_abi object { + #include + int dummy; + #ifndef __ARM_NEON__ + #error not NEON + #endif + /* Avoid the case where a test adds -mfpu=neon, but the toolchain is + configured for -mcpu=arm926ej-s, for example. */ + #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M' + #error Architecture does not support NEON. + #endif + } "$flags"] } { + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_ok_no_float_abi { } { + return [check_cached_effective_target arm_neon_ok_no_float_abi \ + check_effective_target_arm_neon_ok_no_float_abi_nocache] +} + +proc check_effective_target_arm_crc_ok_nocache { } { + global et_arm_crc_flags + set et_arm_crc_flags "-march=armv8-a+crc" + return [check_no_compiler_messages_nocache arm_crc_ok object { + #if !defined (__ARM_FEATURE_CRC32) + #error FOO + #endif + #include + } "$et_arm_crc_flags"] +} + +proc check_effective_target_arm_crc_ok { } { + return [check_cached_effective_target arm_crc_ok \ + check_effective_target_arm_crc_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-fp16 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_neon_fp16_flags to +# the best options to add. + +proc check_effective_target_arm_neon_fp16_ok_nocache { } { + global et_arm_neon_fp16_flags + global et_arm_neon_flags + set et_arm_neon_fp16_flags "" + if { [check_effective_target_arm32] + && [check_effective_target_arm_neon_ok] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" + "-mfpu=neon-fp16 -mfloat-abi=softfp" + "-mfp16-format=ieee" + "-mfloat-abi=softfp -mfp16-format=ieee" + "-mfpu=neon-fp16 -mfp16-format=ieee" + "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} { + if { [check_no_compiler_messages_nocache arm_neon_fp16_ok object { + #include "arm_neon.h" + float16x4_t + foo (float32x4_t arg) + { + return vcvt_f16_f32 (arg); + } + } "$et_arm_neon_flags $flags"] } { + set et_arm_neon_fp16_flags [concat $et_arm_neon_flags $flags] + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_fp16_ok { } { + return [check_cached_effective_target arm_neon_fp16_ok \ + check_effective_target_arm_neon_fp16_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-fp16 +# and -mfloat-abi=softfp together. Some multilibs may be +# incompatible with these options. Also set et_arm_neon_softfp_fp16_flags to +# the best options to add. + +proc check_effective_target_arm_neon_softfp_fp16_ok_nocache { } { + global et_arm_neon_softfp_fp16_flags + global et_arm_neon_flags + set et_arm_neon_softfp_fp16_flags "" + if { [check_effective_target_arm32] + && [check_effective_target_arm_neon_ok] } { + foreach flags {"-mfpu=neon-fp16 -mfloat-abi=softfp" + "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} { + if { [check_no_compiler_messages_nocache arm_neon_softfp_fp16_ok object { + #include "arm_neon.h" + float16x4_t + foo (float32x4_t arg) + { + return vcvt_f16_f32 (arg); + } + } "$et_arm_neon_flags $flags"] } { + set et_arm_neon_softfp_fp16_flags [concat $et_arm_neon_flags $flags] + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_softfp_fp16_ok { } { + return [check_cached_effective_target arm_neon_softfp_fp16_ok \ + check_effective_target_arm_neon_softfp_fp16_ok_nocache] +} + + + +proc check_effective_target_arm_neon_fp16_hw { } { + if {! [check_effective_target_arm_neon_fp16_ok] } { + return 0 + } + global et_arm_neon_fp16_flags + check_runtime arm_neon_fp16_hw { + int + main (int argc, char **argv) + { + asm ("vcvt.f32.f16 q1, d0"); + return 0; + } + } $et_arm_neon_fp16_flags +} + +proc add_options_for_arm_neon_fp16 { flags } { + if { ! [check_effective_target_arm_neon_fp16_ok] } { + return "$flags" + } + global et_arm_neon_fp16_flags + return "$flags $et_arm_neon_fp16_flags" +} + +proc add_options_for_arm_neon_softfp_fp16 { flags } { + if { ! [check_effective_target_arm_neon_softfp_fp16_ok] } { + return "$flags" + } + global et_arm_neon_softfp_fp16_flags + return "$flags $et_arm_neon_softfp_fp16_flags" +} + +proc add_options_for_aarch64_sve { flags } { + if { ![istarget aarch64*-*-*] || [check_effective_target_aarch64_sve] } { + return "$flags" + } + return "$flags -march=armv8.2-a+sve" +} + +# Return 1 if this is an ARM target supporting the FP16 alternative +# format. Some multilibs may be incompatible with the options needed. Also +# set et_arm_neon_fp16_flags to the best options to add. + +proc check_effective_target_arm_fp16_alternative_ok_nocache { } { + global et_arm_neon_fp16_flags + set et_arm_neon_fp16_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" + "-mfpu=neon-fp16 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_fp16_alternative_ok object { + #if !defined (__ARM_FP16_FORMAT_ALTERNATIVE) + #error __ARM_FP16_FORMAT_ALTERNATIVE not defined + #endif + } "$flags -mfp16-format=alternative"] } { + set et_arm_neon_fp16_flags "$flags -mfp16-format=alternative" + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp16_alternative_ok { } { + return [check_cached_effective_target arm_fp16_alternative_ok \ + check_effective_target_arm_fp16_alternative_ok_nocache] +} + +# Return 1 if this is an ARM target supports specifying the FP16 none +# format. Some multilibs may be incompatible with the options needed. + +proc check_effective_target_arm_fp16_none_ok_nocache { } { + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" + "-mfpu=neon-fp16 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_fp16_none_ok object { + #if defined (__ARM_FP16_FORMAT_ALTERNATIVE) + #error __ARM_FP16_FORMAT_ALTERNATIVE defined + #endif + #if defined (__ARM_FP16_FORMAT_IEEE) + #error __ARM_FP16_FORMAT_IEEE defined + #endif + } "$flags -mfp16-format=none"] } { + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp16_none_ok { } { + return [check_cached_effective_target arm_fp16_none_ok \ + check_effective_target_arm_fp16_none_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_v8_neon_flags to the +# best options to add. + +proc check_effective_target_arm_v8_neon_ok_nocache { } { + global et_arm_v8_neon_flags + set et_arm_v8_neon_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache arm_v8_neon_ok object { + #if __ARM_ARCH < 8 + #error not armv8 or later + #endif + #include "arm_neon.h" + void + foo () + { + __asm__ volatile ("vrintn.f32 q0, q0"); + } + } "$flags -march=armv8-a"] } { + set et_arm_v8_neon_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_v8_neon_ok { } { + return [check_cached_effective_target arm_v8_neon_ok \ + check_effective_target_arm_v8_neon_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_neonv2_flags to the +# best options to add. + +proc check_effective_target_arm_neonv2_ok_nocache { } { + global et_arm_neonv2_flags + global et_arm_neon_flags + set et_arm_neonv2_flags "" + if { [check_effective_target_arm32] + && [check_effective_target_arm_neon_ok] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-vfpv4" "-mfpu=neon-vfpv4 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache arm_neonv2_ok object { + #include "arm_neon.h" + float32x2_t + foo (float32x2_t a, float32x2_t b, float32x2_t c) + { + return vfma_f32 (a, b, c); + } + } "$et_arm_neon_flags $flags"] } { + set et_arm_neonv2_flags [concat $et_arm_neon_flags $flags] + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neonv2_ok { } { + return [check_cached_effective_target arm_neonv2_ok \ + check_effective_target_arm_neonv2_ok_nocache] +} + +# Add the options needed for VFP FP16 support. We need either +# -mfloat-abi=softfp or -mfloat-abi=hard. If one is already specified by +# the multilib, use it. + +proc add_options_for_arm_fp16 { flags } { + if { ! [check_effective_target_arm_fp16_ok] } { + return "$flags" + } + global et_arm_fp16_flags + return "$flags $et_arm_fp16_flags" +} + +# Add the options needed to enable support for IEEE format +# half-precision support. This is valid for ARM targets. + +proc add_options_for_arm_fp16_ieee { flags } { + if { ! [check_effective_target_arm_fp16_ok] } { + return "$flags" + } + global et_arm_fp16_flags + return "$flags $et_arm_fp16_flags -mfp16-format=ieee" +} + +# Add the options needed to enable support for ARM Alternative format +# half-precision support. This is valid for ARM targets. + +proc add_options_for_arm_fp16_alternative { flags } { + if { ! [check_effective_target_arm_fp16_ok] } { + return "$flags" + } + global et_arm_fp16_flags + return "$flags $et_arm_fp16_flags -mfp16-format=alternative" +} + +# Return 1 if this is an ARM target that can support a VFP fp16 variant. +# Skip multilibs that are incompatible with these options and set +# et_arm_fp16_flags to the best options to add. This test is valid for +# ARM only. + +proc check_effective_target_arm_fp16_ok_nocache { } { + global et_arm_fp16_flags + set et_arm_fp16_flags "" + if { ! [check_effective_target_arm32] } { + return 0; + } + if [check-flags \ + [list "" { *-*-* } { "-mfpu=*" } \ + { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" \ + "-mfpu=*fpv[1-9][0-9]*" "-mfpu=*fp-armv8*" } ]] { + # Multilib flags would override -mfpu. + return 0 + } + if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] { + # Must generate floating-point instructions. + return 0 + } + if [check_effective_target_arm_hf_eabi] { + # Use existing float-abi and force an fpu which supports fp16 + set et_arm_fp16_flags "-mfpu=vfpv4" + return 1; + } + if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] { + # The existing -mfpu value is OK; use it, but add softfp. + set et_arm_fp16_flags "-mfloat-abi=softfp" + return 1; + } + # Add -mfpu for a VFP fp16 variant since there is no preprocessor + # macro to check for this support. + set flags "-mfpu=vfpv4 -mfloat-abi=softfp" + if { [check_no_compiler_messages_nocache arm_fp16_ok assembly { + int dummy; + } "$flags"] } { + set et_arm_fp16_flags "$flags" + return 1 + } + + return 0 +} + +proc check_effective_target_arm_fp16_ok { } { + return [check_cached_effective_target arm_fp16_ok \ + check_effective_target_arm_fp16_ok_nocache] +} + +# Return 1 if the target supports executing VFP FP16 instructions, 0 +# otherwise. This test is valid for ARM only. + +proc check_effective_target_arm_fp16_hw { } { + if {! [check_effective_target_arm_fp16_ok] } { + return 0 + } + global et_arm_fp16_flags + check_runtime arm_fp16_hw { + int + main (int argc, char **argv) + { + __fp16 a = 1.0; + float r; + asm ("vcvtb.f32.f16 %0, %1" + : "=w" (r) : "w" (a) + : /* No clobbers. */); + return (r == 1.0) ? 0 : 1; + } + } "$et_arm_fp16_flags -mfp16-format=ieee" +} + +# Creates a series of routines that return 1 if the given architecture +# can be selected and a routine to give the flags to select that architecture +# Note: Extra flags may be added to disable options from newer compilers +# (Thumb in particular - but others may be added in the future). +# Warning: Do not use check_effective_target_arm_arch_*_ok for architecture +# extension (eg. ARMv8.1-A) since there is no macro defined for them. See +# how only __ARM_ARCH_8A__ is checked for ARMv8.1-A. +# Usage: /* { dg-require-effective-target arm_arch_v5_ok } */ +# /* { dg-add-options arm_arch_v5t } */ +# /* { dg-require-effective-target arm_arch_v5t_multilib } */ +foreach { armfunc armflag armdefs } { + v4 "-march=armv4 -marm" __ARM_ARCH_4__ + v4t "-march=armv4t -mfloat-abi=softfp" __ARM_ARCH_4T__ + v4t_arm "-march=armv4t -marm" __ARM_ARCH_4T__ + v4t_thumb "-march=armv4t -mthumb -mfloat-abi=softfp" __ARM_ARCH_4T__ + v5t "-march=armv5t -mfloat-abi=softfp" __ARM_ARCH_5T__ + v5t_arm "-march=armv5t -marm" __ARM_ARCH_5T__ + v5t_thumb "-march=armv5t -mthumb -mfloat-abi=softfp" __ARM_ARCH_5T__ + v5te "-march=armv5te -mfloat-abi=softfp" __ARM_ARCH_5TE__ + v5te_arm "-march=armv5te -marm" __ARM_ARCH_5TE__ + v5te_thumb "-march=armv5te -mthumb -mfloat-abi=softfp" __ARM_ARCH_5TE__ + v6 "-march=armv6 -mfloat-abi=softfp" __ARM_ARCH_6__ + v6_arm "-march=armv6 -marm" __ARM_ARCH_6__ + v6_thumb "-march=armv6 -mthumb -mfloat-abi=softfp" __ARM_ARCH_6__ + v6k "-march=armv6k -mfloat-abi=softfp" __ARM_ARCH_6K__ + v6k_arm "-march=armv6k -marm" __ARM_ARCH_6K__ + v6k_thumb "-march=armv6k -mthumb -mfloat-abi=softfp" __ARM_ARCH_6K__ + v6t2 "-march=armv6t2" __ARM_ARCH_6T2__ + v6z "-march=armv6z -mfloat-abi=softfp" __ARM_ARCH_6Z__ + v6z_arm "-march=armv6z -marm" __ARM_ARCH_6Z__ + v6z_thumb "-march=armv6z -mthumb -mfloat-abi=softfp" __ARM_ARCH_6Z__ + v6m "-march=armv6-m -mthumb -mfloat-abi=soft" __ARM_ARCH_6M__ + v7a "-march=armv7-a" __ARM_ARCH_7A__ + v7r "-march=armv7-r" __ARM_ARCH_7R__ + v7m "-march=armv7-m -mthumb" __ARM_ARCH_7M__ + v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__ + v7ve "-march=armv7ve -marm" + "__ARM_ARCH_7A__ && __ARM_FEATURE_IDIV" + v8a "-march=armv8-a" __ARM_ARCH_8A__ + v8a_hard "-march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=hard" __ARM_ARCH_8A__ + v8_1a "-march=armv8.1-a" __ARM_ARCH_8A__ + v8_2a "-march=armv8.2-a" __ARM_ARCH_8A__ + v8r "-march=armv8-r" __ARM_ARCH_8R__ + v8m_base "-march=armv8-m.base -mthumb -mfloat-abi=soft" + __ARM_ARCH_8M_BASE__ + v8m_main "-march=armv8-m.main -mthumb" __ARM_ARCH_8M_MAIN__ + v8_1m_main "-march=armv8.1-m.main -mthumb" __ARM_ARCH_8M_MAIN__ } { + eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] { + proc check_effective_target_arm_arch_FUNC_ok { } { + return [check_no_compiler_messages arm_arch_FUNC_ok assembly { + #if !(DEFS) + #error !(DEFS) + #endif + int + main (void) + { + return 0; + } + } "FLAG" ] + } + + proc add_options_for_arm_arch_FUNC { flags } { + return "$flags FLAG" + } + + proc check_effective_target_arm_arch_FUNC_multilib { } { + return [check_runtime arm_arch_FUNC_multilib { + int + main (void) + { + return 0; + } + } [add_options_for_arm_arch_FUNC ""]] + } + }] +} + +# Return 1 if GCC was configured with --with-mode= +proc check_effective_target_default_mode { } { + + return [check_configured_with "with-mode="] +} + +# Return 1 if this is an ARM target where -marm causes ARM to be +# used (not Thumb) + +proc check_effective_target_arm_arm_ok { } { + return [check_no_compiler_messages arm_arm_ok assembly { + #if !defined (__arm__) || defined (__thumb__) || defined (__thumb2__) + #error !__arm__ || __thumb__ || __thumb2__ + #endif + } "-marm"] +} + + +# Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be +# used. + +proc check_effective_target_arm_thumb1_ok { } { + return [check_no_compiler_messages arm_thumb1_ok assembly { + #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__) + #error !__arm__ || !__thumb__ || __thumb2__ + #endif + int foo (int i) { return i; } + } "-mthumb"] +} + +# Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be +# used. + +proc check_effective_target_arm_thumb2_ok { } { + return [check_no_compiler_messages arm_thumb2_ok assembly { + #if !defined(__thumb2__) + #error !__thumb2__ + #endif + int foo (int i) { return i; } + } "-mthumb"] +} + +# Return 1 if this is an ARM target where Thumb-1 is used without options +# added by the test. + +proc check_effective_target_arm_thumb1 { } { + return [check_no_compiler_messages arm_thumb1 assembly { + #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__) + #error !__arm__ || !__thumb__ || __thumb2__ + #endif + int i; + } ""] +} + +# Return 1 if this is an ARM target where Thumb-2 is used without options +# added by the test. + +proc check_effective_target_arm_thumb2 { } { + return [check_no_compiler_messages arm_thumb2 assembly { + #if !defined(__thumb2__) + #error !__thumb2__ + #endif + int i; + } ""] +} + +# Return 1 if this is an ARM target where conditional execution is available. + +proc check_effective_target_arm_cond_exec { } { + return [check_no_compiler_messages arm_cond_exec assembly { + #if defined(__arm__) && defined(__thumb__) && !defined(__thumb2__) + #error FOO + #endif + int i; + } ""] +} + +# Return 1 if this is an ARM cortex-M profile cpu + +proc check_effective_target_arm_cortex_m { } { + if { ![istarget arm*-*-*] } { + return 0 + } + return [check_no_compiler_messages arm_cortex_m assembly { + #if defined(__ARM_ARCH_ISA_ARM) + #error __ARM_ARCH_ISA_ARM is defined + #endif + int i; + } "-mthumb"] +} + +# Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be +# used and MOVT/MOVW instructions to be available. + +proc check_effective_target_arm_thumb1_movt_ok {} { + if [check_effective_target_arm_thumb1_ok] { + return [check_no_compiler_messages arm_movt object { + int + foo (void) + { + asm ("movt r0, #42"); + } + } "-mthumb"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be +# used and CBZ and CBNZ instructions are available. + +proc check_effective_target_arm_thumb1_cbz_ok {} { + if [check_effective_target_arm_thumb1_ok] { + return [check_no_compiler_messages arm_movt object { + int + foo (void) + { + asm ("cbz r0, 2f\n2:"); + } + } "-mthumb"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target where ARMv8-M Security Extensions is +# available. + +proc check_effective_target_arm_cmse_ok {} { + return [check_no_compiler_messages arm_cmse object { + int + foo (void) + { + asm ("bxns r0"); + } + } "-mcmse"]; +} + +# Return 1 if the target supports executing MVE instructions, 0 +# otherwise. + +proc check_effective_target_arm_mve_hw {} { + return [check_runtime arm_mve_hw_available { + int + main (void) + { + long long a = 16; + int b = 3; + asm ("sqrshrl %Q1, %R1, #64, %2" + : "=l" (a) + : "0" (a), "r" (b)); + return (a != 2); + } + } ""] +} + +# Return 1 if this is an ARM target where ARMv8-M Security Extensions with +# clearing instructions (clrm, vscclrm, vstr/vldr with FPCXT) is available. + +proc check_effective_target_arm_cmse_clear_ok {} { + return [check_no_compiler_messages arm_cmse_clear object { + int + foo (void) + { + asm ("clrm {r1, r2}"); + } + } "-mcmse"]; +} + +# Return 1 if this compilation turns on string_ops_prefer_neon on. + +proc check_effective_target_arm_tune_string_ops_prefer_neon { } { + return [check_no_messages_and_pattern arm_tune_string_ops_prefer_neon "@string_ops_prefer_neon:\t1" assembly { + int foo (void) { return 0; } + } "-O2 -mprint-tune-info" ] +} + +# Return 1 if the target supports executing NEON instructions, 0 +# otherwise. Cache the result. + +proc check_effective_target_arm_neon_hw { } { + return [check_runtime arm_neon_hw_available { + int + main (void) + { + long long a = 0, b = 1; + asm ("vorr %P0, %P1, %P2" + : "=w" (a) + : "0" (a), "w" (b)); + return (a != 1); + } + } [add_options_for_arm_neon ""]] +} + +# Return true if this is an AArch64 target that can run SVE code. + +proc check_effective_target_aarch64_sve_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_sve_hw_available { + int + main (void) + { + asm volatile ("ptrue p0.b"); + return 0; + } + } [add_options_for_aarch64_sve ""]] +} + +# Return true if this is an AArch64 target that can run SVE2 code. + +proc check_effective_target_aarch64_sve2_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_sve2_hw_available { + int + main (void) + { + asm volatile ("addp z0.b, p0/m, z0.b, z1.b"); + return 0; + } + }] +} + +# Return true if this is an AArch64 target that can run SVE code and +# if its SVE vectors have exactly BITS bits. + +proc aarch64_sve_hw_bits { bits } { + if { ![check_effective_target_aarch64_sve_hw] } { + return 0 + } + return [check_runtime aarch64_sve${bits}_hw [subst { + int + main (void) + { + int res; + asm volatile ("cntd %0" : "=r" (res)); + if (res * 64 != $bits) + __builtin_abort (); + return 0; + } + }] [add_options_for_aarch64_sve ""]] +} + +# Return true if this is an AArch64 target that can run SVE code and +# if its SVE vectors have exactly 256 bits. + +foreach N { 128 256 512 1024 2048 } { + eval [string map [list N $N] { + proc check_effective_target_aarch64_sveN_hw { } { + return [aarch64_sve_hw_bits N] + } + }] +} + +proc check_effective_target_arm_neonv2_hw { } { + return [check_runtime arm_neon_hwv2_available { + #include "arm_neon.h" + int + main (void) + { + float32x2_t a, b, c; + asm ("vfma.f32 %P0, %P1, %P2" + : "=w" (a) + : "w" (b), "w" (c)); + return 0; + } + } [add_options_for_arm_neonv2 ""]] +} + +# ID_AA64PFR1_EL1.BT using bits[3:0] == 1 implies BTI implimented. +proc check_effective_target_aarch64_bti_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_bti_hw_available { + int + main (void) + { + int a; + asm volatile ("mrs %0, id_aa64pfr1_el1" : "=r" (a)); + return !((a & 0xf) == 1); + } + } "-O2" ] +} + +# Return 1 if the target supports executing the armv8.3-a FJCVTZS +# instruction. +proc check_effective_target_aarch64_fjcvtzs_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_fjcvtzs_hw_available { + int + main (void) + { + double in = 25.1; + int out; + asm volatile ("fjcvtzs %w0, %d1" + : "=r" (out) + : "w" (in) + : /* No clobbers. */); + return out != 25; + } + } "-march=armv8.3-a" ] +} + +# Return 1 if GCC was configured with --enable-standard-branch-protection +proc check_effective_target_default_branch_protection { } { + return [check_configured_with "enable-standard-branch-protection"] +} + +# Return 1 if this is an ARM target supporting -mfloat-abi=softfp. + +proc check_effective_target_arm_softfp_ok { } { + return [check_no_compiler_messages arm_softfp_ok object { + #include + int dummy; + int main (void) { return 0; } + } "-mfloat-abi=softfp"] +} + +# Return 1 if this is an ARM target supporting -mfloat-abi=hard. + +proc check_effective_target_arm_hard_ok { } { + return [check_no_compiler_messages arm_hard_ok object { + #include + int dummy; + int main (void) { return 0; } + } "-mfloat-abi=hard"] +} + +# Return 1 if the target supports ARMv8.1-M MVE with floating point +# instructions, 0 otherwise. The test is valid for ARM. +# Record the command line options needed. + +proc check_effective_target_arm_v8_1m_mve_fp_ok_nocache { } { + global et_arm_v8_1m_mve_fp_flags + set et_arm_v8_1m_mve_fp_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve.fp" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve.fp"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_1m_mve_fp_ok object { + #include + #if !(__ARM_FEATURE_MVE & 2) + #error "__ARM_FEATURE_MVE for floating point not defined" + #endif + #if __ARM_BIG_ENDIAN + #error "MVE intrinsics are not supported in Big-Endian mode." + #endif + } "$flags -mthumb"] } { + set et_arm_v8_1m_mve_fp_flags "$flags -mthumb --save-temps" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_1m_mve_fp_ok { } { + return [check_cached_effective_target arm_v8_1m_mve_fp_ok \ + check_effective_target_arm_v8_1m_mve_fp_ok_nocache] +} + +proc add_options_for_arm_v8_1m_mve_fp { flags } { + if { ! [check_effective_target_arm_v8_1m_mve_fp_ok] } { + return "$flags" + } + global et_arm_v8_1m_mve_fp_flags + return "$flags $et_arm_v8_1m_mve_fp_flags" +} + +# Return 1 if the target supports the ARMv8.1 Adv.SIMD extension, 0 +# otherwise. The test is valid for AArch64 and ARM. Record the command +# line options needed. + +proc check_effective_target_arm_v8_1a_neon_ok_nocache { } { + global et_arm_v8_1a_neon_flags + set et_arm_v8_1a_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. Start with the empty set + # since AArch64 only needs the -march setting. + foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \ + "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { + foreach arches { "-march=armv8-a+rdma" "-march=armv8.1-a" } { + if { [check_no_compiler_messages_nocache arm_v8_1a_neon_ok object { + #if !defined (__ARM_FEATURE_QRDMX) + #error "__ARM_FEATURE_QRDMX not defined" + #endif + } "$flags $arches"] } { + set et_arm_v8_1a_neon_flags "$flags $arches" + return 1 + } + } + } + + return 0; +} + +proc check_effective_target_arm_v8_1a_neon_ok { } { + return [check_cached_effective_target arm_v8_1a_neon_ok \ + check_effective_target_arm_v8_1a_neon_ok_nocache] +} + +# Return 1 if the target supports ARMv8.2 scalar FP16 arithmetic +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache { } { + global et_arm_v8_2a_fp16_scalar_flags + set et_arm_v8_2a_fp16_scalar_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfpu=fp-armv8" "-mfloat-abi=softfp" \ + "-mfpu=fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_fp16_scalar_ok object { + #if !defined (__ARM_FEATURE_FP16_SCALAR_ARITHMETIC) + #error "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC not defined" + #endif + } "$flags -march=armv8.2-a+fp16"] } { + set et_arm_v8_2a_fp16_scalar_flags "$flags -march=armv8.2-a+fp16" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_fp16_scalar_ok { } { + return [check_cached_effective_target arm_v8_2a_fp16_scalar_ok \ + check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache] +} + +# Return 1 if the target supports ARMv8.2 Adv.SIMD FP16 arithmetic +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } { + global et_arm_v8_2a_fp16_neon_flags + set et_arm_v8_2a_fp16_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \ + "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_fp16_neon_ok object { + #if !defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) + #error "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC not defined" + #endif + } "$flags -march=armv8.2-a+fp16"] } { + set et_arm_v8_2a_fp16_neon_flags "$flags -march=armv8.2-a+fp16" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_fp16_neon_ok { } { + return [check_cached_effective_target arm_v8_2a_fp16_neon_ok \ + check_effective_target_arm_v8_2a_fp16_neon_ok_nocache] +} + +# Return 1 if the target supports ARMv8.2 Adv.SIMD Dot Product +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache { } { + global et_arm_v8_2a_dotprod_neon_flags + set et_arm_v8_2a_dotprod_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_dotprod_neon_ok object { + #include + #if !defined (__ARM_FEATURE_DOTPROD) + #error "__ARM_FEATURE_DOTPROD not defined" + #endif + } "$flags -march=armv8.2-a+dotprod"] } { + set et_arm_v8_2a_dotprod_neon_flags "$flags -march=armv8.2-a+dotprod" + return 1 + } + } + + return 0; +} + +# Return 1 if the target supports ARMv8.1-M MVE +# instructions, 0 otherwise. The test is valid for ARM. +# Record the command line options needed. + +proc check_effective_target_arm_v8_1m_mve_ok_nocache { } { + global et_arm_v8_1m_mve_flags + set et_arm_v8_1m_mve_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_1m_mve_ok object { + #if !defined (__ARM_FEATURE_MVE) + #error "__ARM_FEATURE_MVE not defined" + #endif + #if __ARM_BIG_ENDIAN + #error "MVE intrinsics are not supported in Big-Endian mode." + #endif + #include + } "$flags -mthumb"] } { + set et_arm_v8_1m_mve_flags "$flags -mthumb --save-temps" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_1m_mve_ok { } { + return [check_cached_effective_target arm_v8_1m_mve_ok \ + check_effective_target_arm_v8_1m_mve_ok_nocache] +} + +proc add_options_for_arm_v8_1m_mve { flags } { + if { ! [check_effective_target_arm_v8_1m_mve_ok] } { + return "$flags" + } + global et_arm_v8_1m_mve_flags + return "$flags $et_arm_v8_1m_mve_flags" +} + +proc check_effective_target_arm_v8_2a_dotprod_neon_ok { } { + return [check_cached_effective_target arm_v8_2a_dotprod_neon_ok \ + check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache] +} + +proc add_options_for_arm_v8_2a_dotprod_neon { flags } { + if { ! [check_effective_target_arm_v8_2a_dotprod_neon_ok] } { + return "$flags" + } + global et_arm_v8_2a_dotprod_neon_flags + return "$flags $et_arm_v8_2a_dotprod_neon_flags" +} + +# Return 1 if the target supports ARMv8.2+i8mm Adv.SIMD Dot Product +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_i8mm_ok_nocache { } { + global et_arm_v8_2a_i8mm_flags + set et_arm_v8_2a_i8mm_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=hard -mfpu=neon-fp-armv8" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" } { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_i8mm_ok object { + #include + #if !defined (__ARM_FEATURE_MATMUL_INT8) + #error "__ARM_FEATURE_MATMUL_INT8 not defined" + #endif + } "$flags -march=armv8.2-a+i8mm"] } { + set et_arm_v8_2a_i8mm_flags "$flags -march=armv8.2-a+i8mm" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_i8mm_ok { } { + return [check_cached_effective_target arm_v8_2a_i8mm_ok \ + check_effective_target_arm_v8_2a_i8mm_ok_nocache] +} + +proc add_options_for_arm_v8_2a_i8mm { flags } { + if { ! [check_effective_target_arm_v8_2a_i8mm_ok] } { + return "$flags" + } + global et_arm_v8_2a_i8mm_flags + return "$flags $et_arm_v8_2a_i8mm_flags" +} + +# Return 1 if the target supports FP16 VFMAL and VFMSL +# instructions, 0 otherwise. +# Record the command line options needed. + +proc check_effective_target_arm_fp16fml_neon_ok_nocache { } { + global et_arm_fp16fml_neon_flags + set et_arm_fp16fml_neon_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} { + if { [check_no_compiler_messages_nocache \ + arm_fp16fml_neon_ok assembly { + #include + float32x2_t + foo (float32x2_t r, float16x4_t a, float16x4_t b) + { + return vfmlal_high_f16 (r, a, b); + } + } "$flags -march=armv8.2-a+fp16fml"] } { + set et_arm_fp16fml_neon_flags "$flags -march=armv8.2-a+fp16fml" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_fp16fml_neon_ok { } { + return [check_cached_effective_target arm_fp16fml_neon_ok \ + check_effective_target_arm_fp16fml_neon_ok_nocache] +} + +proc add_options_for_arm_fp16fml_neon { flags } { + if { ! [check_effective_target_arm_fp16fml_neon_ok] } { + return "$flags" + } + global et_arm_fp16fml_neon_flags + return "$flags $et_arm_fp16fml_neon_flags" +} + +# Return 1 if the target supports BFloat16 SIMD instructions, 0 otherwise. +# The test is valid for ARM and for AArch64. + +proc check_effective_target_arm_v8_2a_bf16_neon_ok_nocache { } { + global et_arm_v8_2a_bf16_neon_flags + set et_arm_v8_2a_bf16_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + foreach flags {"" "-mfloat-abi=hard -mfpu=neon-fp-armv8" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" } { + if { [check_no_compiler_messages_nocache arm_v8_2a_bf16_neon_ok object { + #include + #if !defined (__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) + #error "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC not defined" + #endif + } "$flags -march=armv8.2-a+bf16"] } { + set et_arm_v8_2a_bf16_neon_flags "$flags -march=armv8.2-a+bf16" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_bf16_neon_ok { } { + return [check_cached_effective_target arm_v8_2a_bf16_neon_ok \ + check_effective_target_arm_v8_2a_bf16_neon_ok_nocache] +} + +proc add_options_for_arm_v8_2a_bf16_neon { flags } { + if { ! [check_effective_target_arm_v8_2a_bf16_neon_ok] } { + return "$flags" + } + global et_arm_v8_2a_bf16_neon_flags + return "$flags $et_arm_v8_2a_bf16_neon_flags" +} + +# A series of routines are created to 1) check if a given architecture is +# effective (check_effective_target_*_ok) and then 2) give the corresponding +# flags that enable the architecture (add_options_for_*). +# The series includes: +# arm_v8m_main_cde: Armv8-m CDE (Custom Datapath Extension). +# arm_v8m_main_cde_fp: Armv8-m CDE with FP registers. +# arm_v8_1m_main_cde_mve: Armv8.1-m CDE with MVE. +# Usage: +# /* { dg-require-effective-target arm_v8m_main_cde_ok } */ +# /* { dg-add-options arm_v8m_main_cde } */ +# The tests are valid for Arm. + +foreach { armfunc armflag armdef arminc } { + arm_v8m_main_cde + "-march=armv8-m.main+cdecp0+cdecp6 -mthumb" + "defined (__ARM_FEATURE_CDE)" + "" + arm_v8m_main_cde_fp + "-march=armv8-m.main+fp+cdecp0+cdecp6 -mthumb -mfpu=auto" + "defined (__ARM_FEATURE_CDE) && defined (__ARM_FP)" + "" + arm_v8_1m_main_cde_mve + "-march=armv8.1-m.main+mve+cdecp0+cdecp6 -mthumb -mfpu=auto" + "defined (__ARM_FEATURE_CDE) && defined (__ARM_FEATURE_MVE)" + "#include " + arm_v8_1m_main_cde_mve_fp + "-march=armv8.1-m.main+mve.fp+cdecp0+cdecp6 -mthumb -mfpu=auto" + "defined (__ARM_FEATURE_CDE) || __ARM_FEATURE_MVE == 3" + "#include " + } { + eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef INC $arminc ] { + proc check_effective_target_FUNC_ok_nocache { } { + global et_FUNC_flags + set et_FUNC_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + if { [check_no_compiler_messages_nocache FUNC_ok assembly { + #if !(DEF) + #error "DEF failed" + #endif + #include + INC + } "FLAG"] } { + set et_FUNC_flags "FLAG" + return 1 + } + + return 0; + } + + proc check_effective_target_FUNC_ok { } { + return [check_cached_effective_target FUNC_ok \ + check_effective_target_FUNC_ok_nocache] + } + + proc add_options_for_FUNC { flags } { + if { ! [check_effective_target_FUNC_ok] } { + return "$flags" + } + global et_FUNC_flags + return "$flags $et_FUNC_flags" + } + }] +} + +# Return 1 if the target supports executing ARMv8 NEON instructions, 0 +# otherwise. + +proc check_effective_target_arm_v8_neon_hw { } { + return [check_runtime arm_v8_neon_hw_available { + #include "arm_neon.h" + int + main (void) + { + float32x2_t a = { 1.0f, 2.0f }; + #ifdef __ARM_ARCH_ISA_A64 + asm ("frinta %0.2s, %1.2s" + : "=w" (a) + : "w" (a)); + #else + asm ("vrinta.f32 %P0, %P1" + : "=w" (a) + : "0" (a)); + #endif + return a[0] == 2.0f; + } + } [add_options_for_arm_v8_neon ""]] +} + +# Return 1 if the target supports executing the ARMv8.1 Adv.SIMD extension, 0 +# otherwise. The test is valid for AArch64 and ARM. + +proc check_effective_target_arm_v8_1a_neon_hw { } { + if { ![check_effective_target_arm_v8_1a_neon_ok] } { + return 0; + } + return [check_runtime arm_v8_1a_neon_hw_available { + int + main (void) + { + #ifdef __ARM_ARCH_ISA_A64 + __Int32x2_t a = {0, 1}; + __Int32x2_t b = {0, 2}; + __Int32x2_t result; + + asm ("sqrdmlah %0.2s, %1.2s, %2.2s" + : "=w"(result) + : "w"(a), "w"(b) + : /* No clobbers. */); + + #else + + __simd64_int32_t a = {0, 1}; + __simd64_int32_t b = {0, 2}; + __simd64_int32_t result; + + asm ("vqrdmlah.s32 %P0, %P1, %P2" + : "=w"(result) + : "w"(a), "w"(b) + : /* No clobbers. */); + #endif + + return result[0]; + } + } [add_options_for_arm_v8_1a_neon ""]] +} + +# Return 1 if the target supports executing floating point instructions from +# ARMv8.2 with the FP16 extension, 0 otherwise. The test is valid for ARM and +# for AArch64. + +proc check_effective_target_arm_v8_2a_fp16_scalar_hw { } { + if { ![check_effective_target_arm_v8_2a_fp16_scalar_ok] } { + return 0; + } + return [check_runtime arm_v8_2a_fp16_scalar_hw_available { + int + main (void) + { + __fp16 a = 1.0; + __fp16 result; + + #ifdef __ARM_ARCH_ISA_A64 + + asm ("fabs %h0, %h1" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #else + + asm ("vabs.f16 %0, %1" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #endif + + return (result == 1.0) ? 0 : 1; + } + } [add_options_for_arm_v8_2a_fp16_scalar ""]] +} + +# Return 1 if the target supports executing Adv.SIMD instructions from ARMv8.2 +# with the FP16 extension, 0 otherwise. The test is valid for ARM and for +# AArch64. + +proc check_effective_target_arm_v8_2a_fp16_neon_hw { } { + if { ![check_effective_target_arm_v8_2a_fp16_neon_ok] } { + return 0; + } + return [check_runtime arm_v8_2a_fp16_neon_hw_available { + int + main (void) + { + #ifdef __ARM_ARCH_ISA_A64 + + __Float16x4_t a = {1.0, -1.0, 1.0, -1.0}; + __Float16x4_t result; + + asm ("fabs %0.4h, %1.4h" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #else + + __simd64_float16_t a = {1.0, -1.0, 1.0, -1.0}; + __simd64_float16_t result; + + asm ("vabs.f16 %P0, %P1" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #endif + + return (result[0] == 1.0) ? 0 : 1; + } + } [add_options_for_arm_v8_2a_fp16_neon ""]] +} + +# Return 1 if the target supports executing AdvSIMD instructions from ARMv8.2 +# with the Dot Product extension, 0 otherwise. The test is valid for ARM and for +# AArch64. + +proc check_effective_target_arm_v8_2a_dotprod_neon_hw { } { + if { ![check_effective_target_arm_v8_2a_dotprod_neon_ok] } { + return 0; + } + return [check_runtime arm_v8_2a_dotprod_neon_hw_available { + #include "arm_neon.h" + int + main (void) + { + + uint32x2_t results = {0,0}; + uint8x8_t a = {1,1,1,1,2,2,2,2}; + uint8x8_t b = {2,2,2,2,3,3,3,3}; + + #ifdef __ARM_ARCH_ISA_A64 + asm ("udot %0.2s, %1.8b, %2.8b" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + + #else + asm ("vudot.u8 %P0, %P1, %P2" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + #endif + + return (results[0] == 8 && results[1] == 24) ? 1 : 0; + } + } [add_options_for_arm_v8_2a_dotprod_neon ""]] +} + +# Return 1 if this is a ARM target with NEON enabled. + +proc check_effective_target_arm_neon { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_neon object { + #ifndef __ARM_NEON__ + #error not NEON + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +proc check_effective_target_arm_neonv2 { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_neon object { + #ifndef __ARM_NEON__ + #error not NEON + #else + #ifndef __ARM_FEATURE_FMA + #error not NEONv2 + #else + int dummy; + #endif + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target with load acquire and store release +# instructions for 8-, 16- and 32-bit types. + +proc check_effective_target_arm_acq_rel { } { + return [check_no_compiler_messages arm_acq_rel object { + void + load_acquire_store_release (void) + { + asm ("lda r0, [r1]\n\t" + "stl r0, [r1]\n\t" + "ldah r0, [r1]\n\t" + "stlh r0, [r1]\n\t" + "ldab r0, [r1]\n\t" + "stlb r0, [r1]" + : : : "r0", "memory"); + } + }] +} + +# Add the options needed for MIPS Paired-Single. + +proc add_options_for_mpaired_single { flags } { + if { ! [check_effective_target_mpaired_single] } { + return "$flags" + } + return "$flags -mpaired-single" +} + +# Add the options needed for MIPS SIMD Architecture. + +proc add_options_for_mips_msa { flags } { + if { ! [check_effective_target_mips_msa] } { + return "$flags" + } + return "$flags -mmsa" +} + +# Add the options needed for MIPS Loongson MMI Architecture. + +proc add_options_for_mips_loongson_mmi { flags } { + if { ! [check_effective_target_mips_loongson_mmi] } { + return "$flags" + } + return "$flags -mloongson-mmi" +} + + +# Return 1 if this a Loongson-2E or -2F target using an ABI that supports +# the Loongson vector modes. + +proc check_effective_target_mips_loongson_mmi { } { + return [check_no_compiler_messages loongson assembly { + #if !defined(__mips_loongson_mmi) + #error !__mips_loongson_mmi + #endif + #if !defined(__mips_loongson_vector_rev) + #error !__mips_loongson_vector_rev + #endif + }] +} + +# Return 1 if this is a MIPS target that supports the legacy NAN. + +proc check_effective_target_mips_nanlegacy { } { + return [check_no_compiler_messages nanlegacy assembly { + #include + int main () { return 0; } + } "-mnan=legacy"] +} + +# Return 1 if an MSA program can be compiled to object + +proc check_effective_target_mips_msa { } { + if ![check_effective_target_nomips16] { + return 0 + } + return [check_no_compiler_messages msa object { + #if !defined(__mips_msa) + #error "MSA NOT AVAIL" + #else + #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)) + #error "MSA NOT AVAIL FOR ISA REV < 2" + #endif + #if !defined(__mips_hard_float) + #error "MSA HARD_FLOAT REQUIRED" + #endif + #if __mips_fpr != 64 + #error "MSA 64-bit FPR REQUIRED" + #endif + #include + + int main() + { + v8i16 v = __builtin_msa_ldi_h (1); + + return v[0]; + } + #endif + } "-mmsa" ] +} + +# Return 1 if this is an ARM target that adheres to the ABI for the ARM +# Architecture. + +proc check_effective_target_arm_eabi { } { + return [check_no_compiler_messages arm_eabi object { + #ifndef __ARM_EABI__ + #error not EABI + #else + int dummy; + #endif + }] +} + +# Return 1 if this is an ARM target that adheres to the hard-float variant of +# the ABI for the ARM Architecture (e.g. -mfloat-abi=hard). + +proc check_effective_target_arm_hf_eabi { } { + return [check_no_compiler_messages arm_hf_eabi object { + #if !defined(__ARM_EABI__) || !defined(__ARM_PCS_VFP) + #error not hard-float EABI + #else + int dummy; + #endif + }] +} + +# Return 1 if this is an ARM target that uses the soft float ABI +# with no floating-point instructions at all (e.g. -mfloat-abi=soft). + +proc check_effective_target_arm_softfloat { } { + return [check_no_compiler_messages arm_softfloat object { + #if !defined(__SOFTFP__) + #error not soft-float EABI + #else + int dummy; + #endif + }] +} + +# Return 1 if this is an ARM target supporting -mcpu=iwmmxt. +# Some multilibs may be incompatible with this option. + +proc check_effective_target_arm_iwmmxt_ok { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_iwmmxt_ok object { + int dummy; + } "-mcpu=iwmmxt"] + } else { + return 0 + } +} + +# Return true if LDRD/STRD instructions are prefered over LDM/STM instructions +# for an ARM target. +proc check_effective_target_arm_prefer_ldrd_strd { } { + if { ![check_effective_target_arm32] } { + return 0; + } + + return [check_no_messages_and_pattern arm_prefer_ldrd_strd "strd\tr" assembly { + void foo (void) { __asm__ ("" ::: "r4", "r5"); } + } "-O2 -mthumb" ] +} + +# Return true if LDRD/STRD instructions are available on this target. +proc check_effective_target_arm_ldrd_strd_ok { } { + if { ![check_effective_target_arm32] } { + return 0; + } + + return [check_no_compiler_messages arm_ldrd_strd_ok object { + int main(void) + { + __UINT64_TYPE__ a = 1, b = 10; + __UINT64_TYPE__ *c = &b; + // `a` will be in a valid register since it's a DImode quantity. + asm ("ldrd %0, %1" + : "=r" (a) + : "m" (c)); + return a == 10; + } + }] +} + +# Return 1 if this is a PowerPC target supporting -meabi. + +proc check_effective_target_powerpc_eabi_ok { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_eabi_ok object { + int dummy; + } "-meabi"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with floating-point registers. + +proc check_effective_target_powerpc_fprs { } { + if { [istarget powerpc*-*-*] + || [istarget rs6000-*-*] } { + return [check_no_compiler_messages powerpc_fprs object { + #ifdef __NO_FPRS__ + #error no FPRs + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with hardware double-precision +# floating point. + +proc check_effective_target_powerpc_hard_double { } { + if { [istarget powerpc*-*-*] + || [istarget rs6000-*-*] } { + return [check_no_compiler_messages powerpc_hard_double object { + #ifdef _SOFT_DOUBLE + #error soft double + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -maltivec. + +proc check_effective_target_powerpc_altivec_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + return [check_no_compiler_messages powerpc_altivec_ok object { + int dummy; + } "-maltivec"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mpower8-vector + +proc check_effective_target_powerpc_p8vector_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't run on power8, so far. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_p8vector_ok object { + int main (void) { + asm volatile ("xxlorc 0,0,0"); + return 0; + } + } "-mpower8-vector"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mpower9-vector + +proc check_effective_target_powerpc_p9vector_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't run on power9, so far. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_p9vector_ok object { + int main (void) { + long e = -1; + vector double v = (vector double) { 0.0, 0.0 }; + asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v)); + return e; + } + } "-mpower9-vector"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mmodulo + +proc check_effective_target_powerpc_p9modulo_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + return [check_no_compiler_messages powerpc_p9modulo_ok object { + int main (void) { + int i = 5, j = 3, r = -1; + asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j)); + return (r == 2); + } + } "-mmodulo"] + } else { + return 0 + } +} + +# return 1 if our compiler returns the ARCH_PWR defines with the options +# as provided by the test. +proc check_effective_target_has_arch_pwr5 { } { + return [check_no_compiler_messages arch_pwr5 assembly { + #ifndef _ARCH_PWR5 + #error does not have power5 support. + #else + /* "has power5 support" */ + #endif + }] +} + +proc check_effective_target_has_arch_pwr6 { } { + return [check_no_compiler_messages arch_pwr6 assembly { + #ifndef _ARCH_PWR6 + #error does not have power6 support. + #else + /* "has power6 support" */ + #endif + }] +} + +proc check_effective_target_has_arch_pwr7 { } { + return [check_no_compiler_messages arch_pwr7 assembly { + #ifndef _ARCH_PWR7 + #error does not have power7 support. + #else + /* "has power7 support" */ + #endif + }] +} + +proc check_effective_target_has_arch_pwr8 { } { + return [check_no_compiler_messages arch_pwr8 assembly { + #ifndef _ARCH_PWR8 + #error does not have power8 support. + #else + /* "has power8 support" */ + #endif + }] +} + +proc check_effective_target_has_arch_pwr9 { } { + return [check_no_compiler_messages arch_pwr9 assembly { + #ifndef _ARCH_PWR9 + #error does not have power9 support. + #else + /* "has power9 support" */ + #endif + }] +} + +# Return 1 if this is a PowerPC target supporting -mcpu=power10. +# Limit this to 64-bit linux systems for now until other targets support +# power10. + +proc check_effective_target_power10_ok { } { + if { ([istarget powerpc64*-*-linux*]) } { + return [check_no_compiler_messages power10_ok object { + int main (void) { + long e; + asm ("pli %0,%1" : "=r" (e) : "n" (0x12345)); + return e; + } + } "-mcpu=power10"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mfloat128 via either +# software emulation on power7/power8 systems or hardware support on power9. + +proc check_effective_target_powerpc_float128_sw_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't have VSX, so no soft support for float128. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_float128_sw_ok object { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() { + __float128 z = x + y; + return (z == 3.0q); + } + } "-mfloat128 -mvsx"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mfloat128 via hardware +# support on power9. + +proc check_effective_target_powerpc_float128_hw_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't run on any machine with float128 h/w so far. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_float128_hw_ok object { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() { + __float128 z; + __asm__ ("xsaddqp %0,%1,%2" : "=v" (z) : "v" (x), "v" (y)); + return (z == 3.0q); + } + } "-mfloat128-hardware"] + } else { + return 0 + } +} + +# Return 1 if current options define float128, 0 otherwise. + +proc check_effective_target_ppc_float128 { } { + return [check_no_compiler_messages_nocache ppc_float128 object { + #ifndef __FLOAT128__ + nope no good + #endif + }] +} + +# Return 1 if current options generate float128 insns, 0 otherwise. + +proc check_effective_target_ppc_float128_insns { } { + return [check_no_compiler_messages_nocache ppc_float128 object { + #ifndef __FLOAT128_HARDWARE__ + nope no good + #endif + }] +} + +# Return 1 if current options generate VSX instructions, 0 otherwise. + +proc check_effective_target_powerpc_vsx { } { + return [check_no_compiler_messages_nocache powerpc_vsx object { + #ifndef __VSX__ + nope no vsx + #endif + }] +} + +# Return 1 if this is a PowerPC target supporting -mvsx + +proc check_effective_target_powerpc_vsx_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # VSX is not supported on AIX before 7.1. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5*] + || [istarget powerpc*-*-aix6*] } { + return 0 + } + # Darwin doesn't have VSX, even if it's used with an assembler + # which recognises the insns. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_vsx_ok object { + int main (void) { + asm volatile ("xxlor 0,0,0"); + return 0; + } + } "-mvsx"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mhtm + +proc check_effective_target_powerpc_htm_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # HTM is not supported on AIX yet. + if { [istarget powerpc*-*-aix*] } { + return 0 + } + return [check_no_compiler_messages powerpc_htm_ok object { + int main (void) { + asm volatile ("tbegin. 0"); + return 0; + } + } "-mhtm"] + } else { + return 0 + } +} + +# Return 1 if the target supports executing HTM hardware instructions, +# 0 otherwise. Cache the result. + +proc check_htm_hw_available { } { + return [check_cached_effective_target htm_hw_available { + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + check_runtime_nocache htm_hw_available { + int main() + { + __builtin_ttest (); + return 0; + } + } "-mhtm" + } + }] +} +# Return 1 if this is a PowerPC target supporting -mcpu=cell. + +proc check_effective_target_powerpc_ppu_ok { } { + if [check_effective_target_powerpc_altivec_ok] { + return [check_no_compiler_messages cell_asm_available object { + int main (void) { +#ifdef __MACH__ + asm volatile ("lvlx v0,v0,v0"); +#else + asm volatile ("lvlx 0,0,0"); +#endif + return 0; + } + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target that supports SPU. + +proc check_effective_target_powerpc_spu { } { + if { [istarget powerpc*-*-linux*] } { + return [check_effective_target_powerpc_altivec_ok] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC SPE target. The check includes options +# specified by dg-options for this test, so don't cache the result. + +proc check_effective_target_powerpc_spe_nocache { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages_nocache powerpc_spe object { + #ifndef __SPE__ + #error not SPE + #else + int dummy; + #endif + } [current_compiler_flags]] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with SPE enabled. + +proc check_effective_target_powerpc_spe { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_spe object { + #ifndef __SPE__ + #error not SPE + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with Altivec enabled. + +proc check_effective_target_powerpc_altivec { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_altivec object { + #ifndef __ALTIVEC__ + #error not Altivec + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC 405 target. The check includes options +# specified by dg-options for this test, so don't cache the result. + +proc check_effective_target_powerpc_405_nocache { } { + if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } { + return [check_no_compiler_messages_nocache powerpc_405 object { + #ifdef __PPC405__ + int dummy; + #else + #error not a PPC405 + #endif + } [current_compiler_flags]] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target using the ELFv2 ABI. + +proc check_effective_target_powerpc_elfv2 { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_elfv2 object { + #if _CALL_ELF != 2 + #error not ELF v2 ABI + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# The VxWorks SPARC simulator accepts only EM_SPARC executables and +# chokes on EM_SPARC32PLUS or EM_SPARCV9 executables. Return 1 if the +# test environment appears to run executables on such a simulator. + +proc check_effective_target_ultrasparc_hw { } { + return [check_runtime ultrasparc_hw { + int main() { return 0; } + } "-mcpu=ultrasparc"] +} + +# Return 1 if the test environment supports executing UltraSPARC VIS2 +# instructions. We check this by attempting: "bmask %g0, %g0, %g0" + +proc check_effective_target_ultrasparc_vis2_hw { } { + return [check_runtime ultrasparc_vis2_hw { + int main() { __asm__(".word 0x81b00320"); return 0; } + } "-mcpu=ultrasparc3"] +} + +# Return 1 if the test environment supports executing UltraSPARC VIS3 +# instructions. We check this by attempting: "addxc %g0, %g0, %g0" + +proc check_effective_target_ultrasparc_vis3_hw { } { + return [check_runtime ultrasparc_vis3_hw { + int main() { __asm__(".word 0x81b00220"); return 0; } + } "-mcpu=niagara3"] +} + +# Return 1 if this is a SPARC-V9 target. + +proc check_effective_target_sparc_v9 { } { + if { [istarget sparc*-*-*] } { + return [check_no_compiler_messages sparc_v9 object { + int main (void) { + asm volatile ("return %i7+8"); + return 0; + } + }] + } else { + return 0 + } +} + +# Return 1 if this is a SPARC target with VIS enabled. + +proc check_effective_target_sparc_vis { } { + if { [istarget sparc*-*-*] } { + return [check_no_compiler_messages sparc_vis object { + #ifndef __VIS__ + #error not VIS + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if the target supports hardware vector shift operation. + +proc check_effective_target_vect_shift { } { + return [check_cached_effective_target_indexed vect_shift { + expr {([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_msa] + || [et-is-effective-target mips_loongson_mmi])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports hardware vector shift by register operation. + +proc check_effective_target_vect_var_shift { } { + return [check_cached_effective_target_indexed vect_var_shift { + expr {(([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_avx2_available]) + }}] +} + +proc check_effective_target_whole_vector_shift { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [istarget powerpc64*-*-*] + || ([is-effective-target arm_neon] + && [check_effective_target_arm_little_endian]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_loongson_mmi]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] } { + set answer 1 + } else { + set answer 0 + } + + verbose "check_effective_target_vect_long: returning $answer" 2 + return $answer +} + +# Return 1 if the target supports vector bswap operations. + +proc check_effective_target_vect_bswap { } { + return [check_cached_effective_target_indexed vect_bswap { + expr { [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports comparison of bool vectors for at +# least one vector length. + +proc check_effective_target_vect_bool_cmp { } { + return [check_cached_effective_target_indexed vect_bool_cmp { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] }}] +} + +# Return 1 if the target supports addition of char vectors for at least +# one vector length. + +proc check_effective_target_vect_char_add { } { + return [check_cached_effective_target_indexed vect_char_add { + expr { + [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget amdgcn-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_loongson_mmi] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + }}] +} + +# Return 1 if the target supports hardware vector shift operation for char. + +proc check_effective_target_vect_shift_char { } { + return [check_cached_effective_target_indexed vect_shift_char { + expr { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports hardware vectors of long, 0 otherwise. +# +# This can change for different subtargets so do not cache the result. + +proc check_effective_target_vect_long { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || (([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + && [check_effective_target_ilp32]) + || [is-effective-target arm_neon] + || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] } { + set answer 1 + } else { + set answer 0 + } + + verbose "check_effective_target_vect_long: returning $answer" 2 + return $answer +} + +# Return 1 if the target supports hardware vectors of float when +# -funsafe-math-optimizations is enabled, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_float { } { + return [check_cached_effective_target_indexed vect_float { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] + || [istarget mips-sde-elf] + || [istarget mipsisa64*-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [is-effective-target arm_neon] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vxe]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports hardware vectors of float without +# -funsafe-math-optimizations being enabled, 0 otherwise. + +proc check_effective_target_vect_float_strict { } { + return [expr { [check_effective_target_vect_float] + && ![istarget arm*-*-*] }] +} + +# Return 1 if the target supports hardware vectors of double, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_double { } { + return [check_cached_effective_target_indexed vect_double { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_no_compiler_messages vect_double assembly { + #ifdef __tune_atom__ + # error No double vectorizer support. + #endif + }]) + || [istarget aarch64*-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*]} }] +} + +# Return 1 if the target supports conditional addition, subtraction, +# multiplication, division, minimum and maximum on vectors of double, +# via the cond_ optabs. Return 0 otherwise. + +proc check_effective_target_vect_double_cond_arith { } { + return [check_effective_target_aarch64_sve] +} + +# Return 1 if the target supports hardware vectors of long long, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_long_long { } { + return [check_cached_effective_target_indexed vect_long_long { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + + +# Return 1 if the target plus current options does not support a vector +# max instruction on "int", 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_int_min_max { } { + return [check_cached_effective_target_indexed vect_no_int_min_max { + expr { [istarget sparc*-*-*] + || [istarget alpha*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_loongson_mmi]) }}] +} + +# Return 1 if the target plus current options does not support a vector +# add instruction on "int", 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_int_add { } { + # Alpha only supports vector add on V8QI and V4HI. + return [check_cached_effective_target_indexed vect_no_int_add { + expr { [istarget alpha*-*-*] }}] +} + +# Return 1 if the target plus current options does not support vector +# bitwise instructions, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_bitwise { } { + return [check_cached_effective_target_indexed vect_no_bitwise { return 0 }] +} + +# Return 1 if the target plus current options supports vector permutation, +# 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_perm { } { + return [check_cached_effective_target_indexed vect_perm { + expr { [is-effective-target arm_neon] + || [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && ([et-is-effective-target mpaired_single] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if, for some VF: +# +# - the target's default vector size is VF * ELEMENT_BITS bits +# +# - it is possible to implement the equivalent of: +# +# int_t s1[COUNT][COUNT * VF], s2[COUNT * VF]; +# for (int i = 0; i < COUNT; ++i) +# for (int j = 0; j < COUNT * VF; ++j) +# s1[i][j] = s2[j - j % COUNT + i] +# +# using only a single 2-vector permute for each vector in s1. +# +# E.g. for COUNT == 3 and vector length 4, the two arrays would be: +# +# s2 | a0 a1 a2 a3 | b0 b1 b2 b3 | c0 c1 c2 c3 +# ------+-------------+-------------+------------ +# s1[0] | a0 a0 a0 a3 | a3 a3 b2 b2 | b2 c1 c1 c1 +# s1[1] | a1 a1 a1 b0 | b0 b0 b3 b3 | b3 c2 c2 c2 +# s1[2] | a2 a2 a2 b1 | b1 b1 c0 c0 | c0 c3 c3 c3 +# +# Each s1 permute requires only two of a, b and c. +# +# The distance between the start of vector n in s1[0] and the start +# of vector n in s2 is: +# +# A = (n * VF) % COUNT +# +# The corresponding value for the end of vector n is: +# +# B = (n * VF + VF - 1) % COUNT +# +# Subtracting i from each value gives the corresponding difference +# for s1[i]. The condition being tested by this function is false +# iff A - i > 0 and B - i < 0 for some i and n, such that the first +# element for s1[i] comes from vector n - 1 of s2 and the last element +# comes from vector n + 1 of s2. The condition is therefore true iff +# A <= B for all n. This is turn means the condition is true iff: +# +# (n * VF) % COUNT + (VF - 1) % COUNT < COUNT +# +# for all n. COUNT - (n * VF) % COUNT is bounded by gcd (VF, COUNT), +# and will be that value for at least one n in [0, COUNT), so we want: +# +# (VF - 1) % COUNT < gcd (VF, COUNT) + +proc vect_perm_supported { count element_bits } { + set vector_bits [lindex [available_vector_sizes] 0] + # The number of vectors has to be a power of 2 when permuting + # variable-length vectors. + if { $vector_bits <= 0 && ($count & -$count) != $count } { + return 0 + } + set vf [expr { $vector_bits / $element_bits }] + + # Compute gcd (VF, COUNT). + set gcd $vf + set temp1 $count + while { $temp1 > 0 } { + set temp2 [expr { $gcd % $temp1 }] + set gcd $temp1 + set temp1 $temp2 + } + return [expr { ($vf - 1) % $count < $gcd }] +} + +# Return 1 if the target supports SLP permutation of 3 vectors when each +# element has 32 bits. + +proc check_effective_target_vect_perm3_int { } { + return [expr { [check_effective_target_vect_perm] + && [vect_perm_supported 3 32] }] +} + +# Return 1 if the target plus current options supports vector permutation +# on byte-sized elements, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_perm_byte { } { + return [check_cached_effective_target_indexed vect_perm_byte { + expr { ([is-effective-target arm_neon] + && [is-effective-target arm_little_endian]) + || ([istarget aarch64*-*-*] + && [is-effective-target aarch64_little_endian]) + || [istarget powerpc*-*-*] + || ([istarget mips-*.*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports SLP permutation of 3 vectors when each +# element has 8 bits. + +proc check_effective_target_vect_perm3_byte { } { + return [expr { [check_effective_target_vect_perm_byte] + && [vect_perm_supported 3 8] }] +} + +# Return 1 if the target plus current options supports vector permutation +# on short-sized elements, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_perm_short { } { + return [check_cached_effective_target_indexed vect_perm_short { + expr { ([is-effective-target arm_neon] + && [is-effective-target arm_little_endian]) + || ([istarget aarch64*-*-*] + && [is-effective-target aarch64_little_endian]) + || [istarget powerpc*-*-*] + || (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_ssse3_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports SLP permutation of 3 vectors when each +# element has 16 bits. + +proc check_effective_target_vect_perm3_short { } { + return [expr { [check_effective_target_vect_perm_short] + && [vect_perm_supported 3 16] }] +} + +# Return 1 if the target plus current options supports folding of +# copysign into XORSIGN. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_xorsign { } { + return [check_cached_effective_target_indexed xorsign { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] || [istarget arm*-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *short* args into *int* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } { + return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si_pattern { + expr { [istarget powerpc*-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || [is-effective-target arm_neon] + || [istarget ia64-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *short* args into *int* result, 0 otherwise. +# A target can also support this widening summation if it can support +# promotion (unpacking) from shorts to ints. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_hi_to_si { } { + return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si { + expr { [check_effective_target_vect_unpack] + || [istarget powerpc*-*-*] + || [istarget ia64-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *char* args into *short* result, 0 otherwise. +# A target can also support this widening summation if it can support +# promotion (unpacking) from chars to shorts. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_qi_to_hi { } { + return [check_cached_effective_target_indexed vect_widen_sum_qi_to_hi { + expr { [check_effective_target_vect_unpack] + || [is-effective-target arm_neon] + || [istarget ia64-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *char* args into *int* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_qi_to_si { } { + return [check_cached_effective_target_indexed vect_widen_sum_qi_to_si { + expr { [istarget powerpc*-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *char* args into *short* result, 0 otherwise. +# A target can also support this widening multplication if it can support +# promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening +# multiplication of shorts). +# +# This won't change for different subtargets so cache the result. + + +proc check_effective_target_vect_widen_mult_qi_to_hi { } { + return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi { + expr { ([check_effective_target_vect_unpack] + && [check_effective_target_vect_short_mult]) + || ([istarget powerpc*-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || [is-effective-target arm_neon] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx])) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *short* args into *int* result, 0 otherwise. +# A target can also support this widening multplication if it can support +# promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening +# multiplication of ints). +# +# This won't change for different subtargets so cache the result. + + +proc check_effective_target_vect_widen_mult_hi_to_si { } { + return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si { + expr { ([check_effective_target_vect_unpack] + && [check_effective_target_vect_int_mult]) + || ([istarget powerpc*-*-*] + || [istarget ia64-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [is-effective-target arm_neon] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx])) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *char* args into *short* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } { + return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi_pattern { + expr { [istarget powerpc*-*-*] + || ([is-effective-target arm_neon] + && [check_effective_target_arm_little_endian]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *short* args into *int* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } { + return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si_pattern { + expr { [istarget powerpc*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([is-effective-target arm_neon] + && [check_effective_target_arm_little_endian]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *int* args into *long* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_mult_si_to_di_pattern { } { + return [check_cached_effective_target_indexed vect_widen_mult_si_to_di_pattern { + expr { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +# Return 1 if the target plus current options supports a vector +# widening shift, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_shift { } { + return [check_cached_effective_target_indexed vect_widen_shift { + expr { [is-effective-target arm_neon] }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product of signed chars, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_sdot_qi { } { + return [check_cached_effective_target_indexed vect_sdot_qi { + expr { [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [istarget arm*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product of unsigned chars, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_udot_qi { } { + return [check_cached_effective_target_indexed vect_udot_qi { + expr { [istarget powerpc*-*-*] + || [istarget aarch64*-*-*] + || [istarget arm*-*-*] + || [istarget ia64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product of signed shorts, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_sdot_hi { } { + return [check_cached_effective_target_indexed vect_sdot_hi { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product of unsigned shorts, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_udot_hi { } { + return [check_cached_effective_target_indexed vect_udot_hi { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# sad operation of unsigned chars, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_usad_char { } { + return [check_cached_effective_target_indexed vect_usad_char { + expr { [istarget i?86-*-*] + || [istarget x86_64-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || ([istarget powerpc*-*-*] + && [check_p9vector_hw_available])}}] +} + +# Return 1 if the target plus current options supports both signed +# and unsigned average operations on vectors of bytes. + +proc check_effective_target_vect_avg_qi {} { + return [expr { [istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve1_only] }] +} + +# Return 1 if the target plus current options supports both signed +# and unsigned multiply-high-with-round-and-scale operations +# on vectors of half-words. + +proc check_effective_target_vect_mulhrs_hi {} { + return [expr { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_sve2] }] +} + +# Return 1 if the target plus current options supports signed division +# by power-of-2 operations on vectors of 4-byte integers. + +proc check_effective_target_vect_sdiv_pow2_si {} { + return [expr { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_sve] }] +} + +# Return 1 if the target plus current options supports a vector +# demotion (packing) of shorts (to chars) and ints (to shorts) +# using modulo arithmetic, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_pack_trunc { } { + return [check_cached_effective_target_indexed vect_pack_trunc { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok] + && [check_effective_target_arm_little_endian]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn*-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_unpack { } { + return [check_cached_effective_target_indexed vect_unpack { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok] + && [check_effective_target_arm_little_endian]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn*-*-*] }}] +} + +# Return 1 if the target plus current options does not guarantee +# that its STACK_BOUNDARY is >= the reguired vector alignment. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_unaligned_stack { } { + return [check_cached_effective_target_indexed unaligned_stack { expr 0 }] +} + +# Return 1 if the target plus current options does not support a vector +# alignment mechanism, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_align { } { + return [check_cached_effective_target_indexed vect_no_align { + expr { [istarget mipsisa64*-*-*] + || [istarget mips-sde-elf] + || [istarget sparc*-*-*] + || [istarget ia64-*-*] + || [check_effective_target_arm_vect_no_misalign] + || ([istarget powerpc*-*-*] && [check_p8vector_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_loongson_mmi]) }}] +} + +# Return 1 if the target supports a vector misalign access, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_hw_misalign { } { + return [check_cached_effective_target_indexed vect_hw_misalign { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] && [check_p8vector_hw_available]) + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) } { + return 1 + } + if { [istarget arm*-*-*] + && ![check_effective_target_arm_vect_no_misalign] } { + return 1 + } + return 0 + }] +} + + +# Return 1 if arrays are aligned to the vector alignment +# boundary, 0 otherwise. + +proc check_effective_target_vect_aligned_arrays { } { + set et_vect_aligned_arrays 0 + if { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && !([is-effective-target ia32] + || ([check_avx_available] && ![check_prefer_avx128]))) } { + set et_vect_aligned_arrays 1 + } + + verbose "check_effective_target_vect_aligned_arrays:\ + returning $et_vect_aligned_arrays" 2 + return $et_vect_aligned_arrays +} + +# Return 1 if types of size 32 bit or less are naturally aligned +# (aligned to their type-size), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_natural_alignment_32 { } { + # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER. + # FIXME: m68k has -malign-int + return [check_cached_effective_target_indexed natural_alignment_32 { + if { ([istarget *-*-darwin*] && [is-effective-target lp64]) + || [istarget avr-*-*] + || [istarget m68k-*-linux*] + || [istarget pru-*-*] + || [istarget stormy16-*-*] + || [istarget rl78-*-*] + || [istarget pdp11-*-*] + || [istarget msp430-*-*] + || [istarget m32c-*-*] + || [istarget cris-*-*] } { + return 0 + } else { + return 1 + } + }] +} + +# Return 1 if types of size 64 bit or less are naturally aligned (aligned to their +# type-size), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_natural_alignment_64 { } { + return [check_cached_effective_target_indexed natural_alignment_64 { + expr { [is-effective-target natural_alignment_32] + && [is-effective-target lp64] && ![istarget *-*-darwin*] } + }] +} + +# Return 1 if all vector types are naturally aligned (aligned to their +# type-size), 0 otherwise. + +proc check_effective_target_vect_natural_alignment { } { + set et_vect_natural_alignment 1 + if { [check_effective_target_arm_eabi] + || [istarget nvptx-*-*] + || [istarget s390*-*-*] + || [istarget amdgcn-*-*] } { + set et_vect_natural_alignment 0 + } + verbose "check_effective_target_vect_natural_alignment:\ + returning $et_vect_natural_alignment" 2 + return $et_vect_natural_alignment +} + +# Return true if the target supports the check_raw_ptrs and check_war_ptrs +# optabs on vectors. + +proc check_effective_target_vect_check_ptrs { } { + return [check_effective_target_aarch64_sve2] +} + +# Return true if fully-masked loops are supported. + +proc check_effective_target_vect_fully_masked { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return 1 if the target doesn't prefer any alignment beyond element +# alignment during vectorization. + +proc check_effective_target_vect_element_align_preferred { } { + return [expr { [check_effective_target_aarch64_sve] + && [check_effective_target_vect_variable_length] }] +} + +# Return 1 if we can align stack data to the preferred vector alignment. + +proc check_effective_target_vect_align_stack_vars { } { + if { [check_effective_target_aarch64_sve] } { + return [check_effective_target_vect_variable_length] + } + return 1 +} + +# Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise. + +proc check_effective_target_vector_alignment_reachable { } { + set et_vector_alignment_reachable 0 + if { [check_effective_target_vect_aligned_arrays] + || [check_effective_target_natural_alignment_32] } { + set et_vector_alignment_reachable 1 + } + verbose "check_effective_target_vector_alignment_reachable:\ + returning $et_vector_alignment_reachable" 2 + return $et_vector_alignment_reachable +} + +# Return 1 if vector alignment for 64 bit is reachable, 0 otherwise. + +proc check_effective_target_vector_alignment_reachable_for_64bit { } { + set et_vector_alignment_reachable_for_64bit 0 + if { [check_effective_target_vect_aligned_arrays] + || [check_effective_target_natural_alignment_64] } { + set et_vector_alignment_reachable_for_64bit 1 + } + verbose "check_effective_target_vector_alignment_reachable_for_64bit:\ + returning $et_vector_alignment_reachable_for_64bit" 2 + return $et_vector_alignment_reachable_for_64bit +} + +# Return 1 if the target only requires element alignment for vector accesses + +proc check_effective_target_vect_element_align { } { + return [check_cached_effective_target_indexed vect_element_align { + expr { ([istarget arm*-*-*] + && ![check_effective_target_arm_vect_no_misalign]) + || [check_effective_target_vect_hw_misalign] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if we expect to see unaligned accesses in at least some +# vector dumps. + +proc check_effective_target_vect_unaligned_possible { } { + return [expr { ![check_effective_target_vect_element_align_preferred] + && (![check_effective_target_vect_no_align] + || [check_effective_target_vect_hw_misalign]) }] +} + +# Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise. + +proc check_effective_target_vect_load_lanes { } { + # We don't support load_lanes correctly on big-endian arm. + return [check_cached_effective_target vect_load_lanes { + expr { ([check_effective_target_arm_little_endian] + && [check_effective_target_arm_neon_ok]) + || [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector masked stores. + +proc check_effective_target_vect_masked_store { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return 1 if the target supports vector scatter stores. + +proc check_effective_target_vect_scatter_store { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return 1 if the target supports vector conditional operations, 0 otherwise. + +proc check_effective_target_vect_condition { } { + return [check_cached_effective_target_indexed vect_condition { + expr { [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget arm*-*-*] + && [check_effective_target_arm_neon_ok]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector conditional operations where +# the comparison has different type from the lhs, 0 otherwise. + +proc check_effective_target_vect_cond_mixed { } { + return [check_cached_effective_target_indexed vect_cond_mixed { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector char multiplication, 0 otherwise. + +proc check_effective_target_vect_char_mult { } { + return [check_cached_effective_target_indexed vect_char_mult { + expr { [istarget aarch64*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [check_effective_target_arm32] + || [check_effective_target_powerpc_altivec] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector short multiplication, 0 otherwise. + +proc check_effective_target_vect_short_mult { } { + return [check_cached_effective_target_indexed vect_short_mult { + expr { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] + || [istarget aarch64*-*-*] + || [check_effective_target_arm32] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_msa] + || [et-is-effective-target mips_loongson_mmi])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector int multiplication, 0 otherwise. + +proc check_effective_target_vect_int_mult { } { + return [check_cached_effective_target_indexed vect_int_mult { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [check_effective_target_arm32] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports 64 bit hardware vector +# multiplication of long operands with a long result, 0 otherwise. +# +# This can change for different subtargets so do not cache the result. + +proc check_effective_target_vect_long_mult { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || (([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + && [check_effective_target_ilp32]) + || [is-effective-target arm_neon] + || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) } { + set answer 1 + } else { + set answer 0 + } + + verbose "check_effective_target_vect_long_mult: returning $answer" 2 + return $answer +} + +# Return 1 if the target supports vector even/odd elements extraction, 0 otherwise. + +proc check_effective_target_vect_extract_even_odd { } { + return [check_cached_effective_target_indexed extract_even_odd { + expr { [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [is-effective-target arm_neon] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_msa] + || [et-is-effective-target mpaired_single])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +# Return 1 if the target supports vector interleaving, 0 otherwise. + +proc check_effective_target_vect_interleave { } { + return [check_cached_effective_target_indexed vect_interleave { + expr { [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [is-effective-target arm_neon] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || ([istarget mips*-*-*] + && ([et-is-effective-target mpaired_single] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +foreach N {2 3 4 8} { + eval [string map [list N $N] { + # Return 1 if the target supports 2-vector interleaving + proc check_effective_target_vect_stridedN { } { + return [check_cached_effective_target_indexed vect_stridedN { + if { (N & -N) == N + && [check_effective_target_vect_interleave] + && [check_effective_target_vect_extract_even_odd] } { + return 1 + } + if { ([istarget arm*-*-*] + || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } { + return 1 + } + if [check_effective_target_vect_fully_masked] { + return 1 + } + return 0 + }] + } + }] +} + +# Return the list of vector sizes (in bits) that each target supports. +# A vector length of "0" indicates variable-length vectors. + +proc available_vector_sizes { } { + set result {} + if { [istarget aarch64*-*-*] } { + if { [check_effective_target_aarch64_sve] } { + lappend result [aarch64_sve_bits] + } + lappend result 128 64 + } elseif { [istarget arm*-*-*] + && [check_effective_target_arm_neon_ok] } { + lappend result 128 64 + } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } { + if { [check_avx_available] && ![check_prefer_avx128] } { + lappend result 256 + } + lappend result 128 + if { ![is-effective-target ia32] } { + lappend result 64 + } + } elseif { [istarget sparc*-*-*] } { + lappend result 64 + } elseif { [istarget amdgcn*-*-*] } { + lappend result 4096 + } else { + # The traditional default asumption. + lappend result 128 + } + return $result +} + +# Return 1 if the target supports multiple vector sizes + +proc check_effective_target_vect_multiple_sizes { } { + return [expr { [llength [available_vector_sizes]] > 1 }] +} + +# Return true if variable-length vectors are supported. + +proc check_effective_target_vect_variable_length { } { + return [expr { [lindex [available_vector_sizes] 0] == 0 }] +} + +# Return 1 if the target supports vectors of 64 bits. + +proc check_effective_target_vect64 { } { + return [expr { [lsearch -exact [available_vector_sizes] 64] >= 0 }] +} + +# Return 1 if the target supports vector copysignf calls. + +proc check_effective_target_vect_call_copysignf { } { + return [check_cached_effective_target_indexed vect_call_copysignf { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] + || [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports hardware square root instructions. + +proc check_effective_target_sqrt_insn { } { + return [check_cached_effective_target sqrt_insn { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] + || [istarget aarch64*-*-*] + || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return any additional options to enable square root intructions. + +proc add_options_for_sqrt_insn { flags } { + if { [istarget amdgcn*-*-*] } { + return "$flags -ffast-math" + } + if { [istarget arm*-*-*] } { + return [add_options_for_arm_vfp "$flags"] + } + return $flags +} + +# Return 1 if the target supports vector sqrtf calls. + +proc check_effective_target_vect_call_sqrtf { } { + return [check_cached_effective_target_indexed vect_call_sqrtf { + expr { [istarget aarch64*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +# Return 1 if the target supports vector lrint calls. + +proc check_effective_target_vect_call_lrint { } { + set et_vect_call_lrint 0 + if { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_effective_target_ilp32]) + || [istarget amdgcn-*-*] } { + set et_vect_call_lrint 1 + } + + verbose "check_effective_target_vect_call_lrint: returning $et_vect_call_lrint" 2 + return $et_vect_call_lrint +} + +# Return 1 if the target supports vector btrunc calls. + +proc check_effective_target_vect_call_btrunc { } { + return [check_cached_effective_target_indexed vect_call_btrunc { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector btruncf calls. + +proc check_effective_target_vect_call_btruncf { } { + return [check_cached_effective_target_indexed vect_call_btruncf { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector ceil calls. + +proc check_effective_target_vect_call_ceil { } { + return [check_cached_effective_target_indexed vect_call_ceil { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector ceilf calls. + +proc check_effective_target_vect_call_ceilf { } { + return [check_cached_effective_target_indexed vect_call_ceilf { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector floor calls. + +proc check_effective_target_vect_call_floor { } { + return [check_cached_effective_target_indexed vect_call_floor { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector floorf calls. + +proc check_effective_target_vect_call_floorf { } { + return [check_cached_effective_target_indexed vect_call_floorf { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector lceil calls. + +proc check_effective_target_vect_call_lceil { } { + return [check_cached_effective_target_indexed vect_call_lceil { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector lfloor calls. + +proc check_effective_target_vect_call_lfloor { } { + return [check_cached_effective_target_indexed vect_call_lfloor { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector nearbyint calls. + +proc check_effective_target_vect_call_nearbyint { } { + return [check_cached_effective_target_indexed vect_call_nearbyint { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector nearbyintf calls. + +proc check_effective_target_vect_call_nearbyintf { } { + return [check_cached_effective_target_indexed vect_call_nearbyintf { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector round calls. + +proc check_effective_target_vect_call_round { } { + return [check_cached_effective_target_indexed vect_call_round { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector roundf calls. + +proc check_effective_target_vect_call_roundf { } { + return [check_cached_effective_target_indexed vect_call_roundf { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports AND, OR and XOR reduction. + +proc check_effective_target_vect_logical_reduc { } { + return [check_effective_target_aarch64_sve] +} + +# Return 1 if the target supports the fold_extract_last optab. + +proc check_effective_target_vect_fold_extract_last { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return 1 if the target supports section-anchors + +proc check_effective_target_section_anchors { } { + return [check_cached_effective_target section_anchors { + expr { [istarget powerpc*-*-*] + || [istarget arm*-*-*] + || [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports atomic operations on "int_128" values. + +proc check_effective_target_sync_int_128 { } { + return 0 +} + +# Return 1 if the target supports atomic operations on "int_128" values +# and can execute them. +# This requires support for both compare-and-swap and true atomic loads. + +proc check_effective_target_sync_int_128_runtime { } { + return 0 +} + +# Return 1 if the target supports atomic operations on "long long". +# +# Note: 32bit x86 targets require -march=pentium in dg-options. +# Note: 32bit s390 targets require -mzarch in dg-options. + +proc check_effective_target_sync_long_long { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*]) + || [istarget aarch64*-*-*] + || [istarget arm*-*-*] + || [istarget alpha*-*-*] + || ([istarget sparc*-*-*] && [check_effective_target_lp64]) + || [istarget s390*-*-*] } { + return 1 + } else { + return 0 + } +} + +# Return 1 if the target supports popcount on long. + +proc check_effective_target_popcountl { } { + return [check_no_messages_and_pattern popcountl "!\\(call" rtl-expand { + int foo (long b) + { + return __builtin_popcountl (b); + } + } "" ] +} + +# Return 1 if the target supports popcount on long long. + +proc check_effective_target_popcountll { } { + return [check_no_messages_and_pattern popcountll "!\\(call" rtl-expand { + int foo (long long b) + { + return __builtin_popcountll (b); + } + } "" ] +} + + +# Return 1 if the target supports popcount on int. + +proc check_effective_target_popcount { } { + return [check_no_messages_and_pattern popcount "!\\(call" rtl-expand { + int foo (int b) + { + return __builtin_popcount (b); + } + } "" ] +} + +# Return 1 if the target supports atomic operations on "long long" +# and can execute them. +# +# Note: 32bit x86 targets require -march=pentium in dg-options. + +proc check_effective_target_sync_long_long_runtime { } { + if { (([istarget x86_64-*-*] || [istarget i?86-*-*]) + && [check_cached_effective_target sync_long_long_available { + check_runtime_nocache sync_long_long_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return !(edx & bit_CMPXCHG8B); + return 1; + } + } "" + }]) + || [istarget aarch64*-*-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-linux-*] + && [check_runtime sync_longlong_runtime { + #include + int main () + { + long long l1; + + if (sizeof (long long) != 8) + exit (1); + + /* Just check for native; + checking for kernel fallback is tricky. */ + asm volatile ("ldrexd r0,r1, [%0]" + : : "r" (&l1) : "r0", "r1"); + exit (0); + } + } "" ]) + || [istarget alpha*-*-*] + || ([istarget sparc*-*-*] + && [check_effective_target_lp64] + && [check_effective_target_ultrasparc_hw]) + || ([istarget powerpc*-*-*] && [check_effective_target_lp64]) } { + return 1 + } else { + return 0 + } +} + +# Return 1 if the target supports byte swap instructions. + +proc check_effective_target_bswap { } { + return [check_cached_effective_target bswap { + expr { [istarget aarch64*-*-*] + || [istarget alpha*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget m68k-*-*] + || [istarget powerpc*-*-*] + || [istarget rs6000-*-*] + || [istarget s390*-*-*] + || ([istarget arm*-*-*] + && [check_no_compiler_messages_nocache arm_v6_or_later object { + #if __ARM_ARCH < 6 + #error not armv6 or later + #endif + int i; + } ""]) }}] +} + +# Return 1 if the target supports atomic operations on "int" and "long". + +proc check_effective_target_sync_int_long { } { +# This is intentionally powerpc but not rs6000, rs6000 doesn't have the +# load-reserved/store-conditional instructions. + return [check_cached_effective_target sync_int_long { + expr { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [istarget alpha*-*-*] + || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-*] + && [check_effective_target_arm_acq_rel]) + || [istarget bfin*-*linux*] + || [istarget hppa*-*linux*] + || [istarget s390*-*-*] + || [istarget powerpc*-*-*] + || [istarget crisv32-*-*] || [istarget cris-*-*] + || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9]) + || ([istarget arc*-*-*] && [check_effective_target_arc_atomic]) + || [check_effective_target_mips_llsc] }}] +} + +# Return 1 if the target supports atomic operations on "char" and "short". + +proc check_effective_target_sync_char_short { } { +# This is intentionally powerpc but not rs6000, rs6000 doesn't have the +# load-reserved/store-conditional instructions. + return [check_cached_effective_target sync_char_short { + expr { [istarget aarch64*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget alpha*-*-*] + || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-*] + && [check_effective_target_arm_acq_rel]) + || [istarget hppa*-*linux*] + || [istarget s390*-*-*] + || [istarget powerpc*-*-*] + || [istarget crisv32-*-*] || [istarget cris-*-*] + || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9]) + || ([istarget arc*-*-*] && [check_effective_target_arc_atomic]) + || [check_effective_target_mips_llsc] }}] +} + +# Return 1 if the target uses a ColdFire FPU. + +proc check_effective_target_coldfire_fpu { } { + return [check_no_compiler_messages coldfire_fpu assembly { + #ifndef __mcffpu__ + #error !__mcffpu__ + #endif + }] +} + +# Return true if this is a uClibc target. + +proc check_effective_target_uclibc {} { + return [check_no_compiler_messages uclibc object { + #include + #if !defined (__UCLIBC__) + #error !__UCLIBC__ + #endif + }] +} + +# Return true if this is a uclibc target and if the uclibc feature +# described by __$feature__ is not present. + +proc check_missing_uclibc_feature {feature} { + return [check_no_compiler_messages $feature object " + #include + #if !defined (__UCLIBC) || defined (__${feature}__) + #error FOO + #endif + "] +} + +# Return true if this is a Newlib target. + +proc check_effective_target_newlib {} { + return [check_no_compiler_messages newlib object { + #include + }] +} + +# Return true if GCC was configured with --enable-newlib-nano-formatted-io +proc check_effective_target_newlib_nano_io { } { + return [check_configured_with "--enable-newlib-nano-formatted-io"] +} + +# Some newlib versions don't provide a frexpl and instead depend +# on frexp to implement long double conversions in their printf-like +# functions. This leads to broken results. Detect such versions here. + +proc check_effective_target_newlib_broken_long_double_io {} { + if { [is-effective-target newlib] && ![is-effective-target frexpl] } { + return 1 + } + return 0 +} + +# Return true if this is NOT a Bionic target. + +proc check_effective_target_non_bionic {} { + return [check_no_compiler_messages non_bionic object { + #include + #if defined (__BIONIC__) + #error FOO + #endif + }] +} + +# Return true if this target has error.h header. + +proc check_effective_target_error_h {} { + return [check_no_compiler_messages error_h object { + #include + }] +} + +# Return true if this target has tgmath.h header. + +proc check_effective_target_tgmath_h {} { + return [check_no_compiler_messages tgmath_h object { + #include + }] +} + +# Return true if target's libc supports complex functions. + +proc check_effective_target_libc_has_complex_functions {} { + return [check_no_compiler_messages libc_has_complex_functions object { + #include + }] +} + +# Return 1 if +# (a) an error of a few ULP is expected in string to floating-point +# conversion functions; and +# (b) overflow is not always detected correctly by those functions. + +proc check_effective_target_lax_strtofp {} { + # By default, assume that all uClibc targets suffer from this. + return [check_effective_target_uclibc] +} + +# Return 1 if this is a target for which wcsftime is a dummy +# function that always returns 0. + +proc check_effective_target_dummy_wcsftime {} { + # By default, assume that all uClibc targets suffer from this. + return [check_effective_target_uclibc] +} + +# Return 1 if constructors with initialization priority arguments are +# supposed on this target. + +proc check_effective_target_init_priority {} { + return [check_no_compiler_messages init_priority assembly " + void f() __attribute__((constructor (1000))); + void f() \{\} + "] +} + +# Return 1 if the target matches the effective target 'arg', 0 otherwise. +# This can be used with any check_* proc that takes no argument and +# returns only 1 or 0. It could be used with check_* procs that take +# arguments with keywords that pass particular arguments. + +proc is-effective-target { arg } { + global et_index + set selected 0 + if { ![info exists et_index] } { + # Initialize the effective target index that is used in some + # check_effective_target_* procs. + set et_index 0 + } + if { [info procs check_effective_target_${arg}] != [list] } { + set selected [check_effective_target_${arg}] + } else { + switch $arg { + "vmx_hw" { set selected [check_vmx_hw_available] } + "vsx_hw" { set selected [check_vsx_hw_available] } + "p8vector_hw" { set selected [check_p8vector_hw_available] } + "p9vector_hw" { set selected [check_p9vector_hw_available] } + "p9modulo_hw" { set selected [check_p9modulo_hw_available] } + "power10_hw" { set selected [check_power10_hw_available] } + "ppc_float128_sw" { set selected [check_ppc_float128_sw_available] } + "ppc_float128_hw" { set selected [check_ppc_float128_hw_available] } + "ppc_recip_hw" { set selected [check_ppc_recip_hw_available] } + "ppc_cpu_supports_hw" { set selected [check_ppc_cpu_supports_hw_available] } + "ppc_mma_hw" { set selected [check_ppc_mma_hw_available] } + "dfp_hw" { set selected [check_dfp_hw_available] } + "htm_hw" { set selected [check_htm_hw_available] } + "named_sections" { set selected [check_named_sections_available] } + "gc_sections" { set selected [check_gc_sections_available] } + "cxa_atexit" { set selected [check_cxa_atexit_available] } + default { error "unknown effective target keyword `$arg'" } + } + } + + verbose "is-effective-target: $arg $selected" 2 + return $selected +} + +# Return 1 if the argument is an effective-target keyword, 0 otherwise. + +proc is-effective-target-keyword { arg } { + if { [info procs check_effective_target_${arg}] != [list] } { + return 1 + } else { + # These have different names for their check_* procs. + switch $arg { + "vmx_hw" { return 1 } + "vsx_hw" { return 1 } + "p8vector_hw" { return 1 } + "p9vector_hw" { return 1 } + "p9modulo_hw" { return 1 } + "power10_hw" { return 1 } + "ppc_float128_sw" { return 1 } + "ppc_float128_hw" { return 1 } + "ppc_recip_hw" { return 1 } + "ppc_mma_hw" { return 1 } + "dfp_hw" { return 1 } + "htm_hw" { return 1 } + "named_sections" { return 1 } + "gc_sections" { return 1 } + "cxa_atexit" { return 1 } + default { return 0 } + } + } +} + +# Execute tests for all targets in EFFECTIVE_TARGETS list. Set et_index to +# indicate what target is currently being processed. This is for +# the vectorizer tests, e.g. vect_int, to keep track what target supports +# a given feature. + +proc et-dg-runtest { runtest testcases flags default-extra-flags } { + global dg-do-what-default + global EFFECTIVE_TARGETS + global et_index + + if { [llength $EFFECTIVE_TARGETS] > 0 } { + foreach target $EFFECTIVE_TARGETS { + set target_flags $flags + set dg-do-what-default compile + set et_index [lsearch -exact $EFFECTIVE_TARGETS $target] + if { [info procs add_options_for_${target}] != [list] } { + set target_flags [add_options_for_${target} "$flags"] + } + if { [info procs check_effective_target_${target}_runtime] + != [list] && [check_effective_target_${target}_runtime] } { + set dg-do-what-default run + } + $runtest $testcases $target_flags ${default-extra-flags} + } + } else { + set et_index 0 + $runtest $testcases $flags ${default-extra-flags} + } +} + +# Return 1 if a target matches the target in EFFECTIVE_TARGETS at index +# et_index, 0 otherwise. + +proc et-is-effective-target { target } { + global EFFECTIVE_TARGETS + global et_index + + if { [llength $EFFECTIVE_TARGETS] > $et_index + && [lindex $EFFECTIVE_TARGETS $et_index] == $target } { + return 1 + } + return 0 +} + +# Return 1 if target default to short enums + +proc check_effective_target_short_enums { } { + return [check_no_compiler_messages short_enums assembly { + enum foo { bar }; + int s[sizeof (enum foo) == 1 ? 1 : -1]; + }] +} + +# Return 1 if target supports merging string constants at link time. + +proc check_effective_target_string_merging { } { + return [check_no_messages_and_pattern string_merging \ + "rodata\\.str" assembly { + const char *var = "String"; + } {-O2}] +} + +# Return 1 if target has the basic signed and unsigned types in +# , 0 otherwise. This will be obsolete when GCC ensures a +# working for all targets. + +proc check_effective_target_stdint_types { } { + return [check_no_compiler_messages stdint_types assembly { + #include + int8_t a; int16_t b; int32_t c; int64_t d; + uint8_t e; uint16_t f; uint32_t g; uint64_t h; + }] +} + +# Return 1 if target has the basic signed and unsigned types in +# , 0 otherwise. This is for tests that GCC's notions of +# these types agree with those in the header, as some systems have +# only . + +proc check_effective_target_inttypes_types { } { + return [check_no_compiler_messages inttypes_types assembly { + #include + int8_t a; int16_t b; int32_t c; int64_t d; + uint8_t e; uint16_t f; uint32_t g; uint64_t h; + }] +} + +# Return 1 if programs are intended to be run on a simulator +# (i.e. slowly) rather than hardware (i.e. fast). + +proc check_effective_target_simulator { } { + + # All "src/sim" simulators set this one. + if [board_info target exists is_simulator] { + return [board_info target is_simulator] + } + + # The "sid" simulators don't set that one, but at least they set + # this one. + if [board_info target exists slow_simulator] { + return [board_info target slow_simulator] + } + + return 0 +} + +# Return 1 if programs are intended to be run on hardware rather than +# on a simulator + +proc check_effective_target_hw { } { + + # All "src/sim" simulators set this one. + if [board_info target exists is_simulator] { + if [board_info target is_simulator] { + return 0 + } else { + return 1 + } + } + + # The "sid" simulators don't set that one, but at least they set + # this one. + if [board_info target exists slow_simulator] { + if [board_info target slow_simulator] { + return 0 + } else { + return 1 + } + } + + return 1 +} + +# Return 1 if the target is a VxWorks kernel. + +proc check_effective_target_vxworks_kernel { } { + return [check_no_compiler_messages vxworks_kernel assembly { + #if !defined __vxworks || defined __RTP__ + #error NO + #endif + }] +} + +# Return 1 if the target is a VxWorks RTP. + +proc check_effective_target_vxworks_rtp { } { + return [check_no_compiler_messages vxworks_rtp assembly { + #if !defined __vxworks || !defined __RTP__ + #error NO + #endif + }] +} + +# Return 1 if the target is expected to provide wide character support. + +proc check_effective_target_wchar { } { + if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} { + return 0 + } + return [check_no_compiler_messages wchar assembly { + #include + }] +} + +# Return 1 if the target has . + +proc check_effective_target_pthread_h { } { + return [check_no_compiler_messages pthread_h assembly { + #include + }] +} + +# Return 1 if the target can truncate a file from a file-descriptor, +# as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or +# chsize. We test for a trivially functional truncation; no stubs. +# As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a +# different function to be used. + +proc check_effective_target_fd_truncate { } { + set prog { + #define _FILE_OFFSET_BITS 64 + #include + #include + #include + #include + int main () + { + FILE *f = fopen ("tst.tmp", "wb"); + int fd; + const char t[] = "test writing more than ten characters"; + char s[11]; + int status = 0; + fd = fileno (f); + write (fd, t, sizeof (t) - 1); + lseek (fd, 0, 0); + if (ftruncate (fd, 10) != 0) + status = 1; + close (fd); + fclose (f); + if (status) + { + unlink ("tst.tmp"); + exit (status); + } + f = fopen ("tst.tmp", "rb"); + if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0) + status = 1; + fclose (f); + unlink ("tst.tmp"); + exit (status); + } + } + + if { [check_runtime ftruncate $prog] } { + return 1; + } + + regsub "ftruncate" $prog "chsize" prog + return [check_runtime chsize $prog] +} + +# Add to FLAGS all the target-specific flags needed to enable +# full IEEE compliance mode. + +proc add_options_for_ieee { flags } { + if { [istarget alpha*-*-*] + || [istarget sh*-*-*] } { + return "$flags -mieee" + } + if { [istarget rx-*-*] } { + return "$flags -mnofpu" + } + return $flags +} + +if {![info exists flags_to_postpone]} { + set flags_to_postpone "" +} + +# Add to FLAGS the flags needed to enable functions to bind locally +# when using pic/PIC passes in the testsuite. +proc add_options_for_bind_pic_locally { flags } { + global flags_to_postpone + + # Instead of returning 'flags' with the -fPIE or -fpie appended, we save it + # in 'flags_to_postpone' and append it later in gcc_target_compile procedure in + # order to make sure that the multilib_flags doesn't override this. + + if {[check_no_compiler_messages using_pic2 assembly { + #if __PIC__ != 2 + #error __PIC__ != 2 + #endif + }]} { + set flags_to_postpone "-fPIE" + return $flags + } + if {[check_no_compiler_messages using_pic1 assembly { + #if __PIC__ != 1 + #error __PIC__ != 1 + #endif + }]} { + set flags_to_postpone "-fpie" + return $flags + } + return $flags +} + +# Add to FLAGS the flags needed to enable 64-bit vectors. + +proc add_options_for_double_vectors { flags } { + if [is-effective-target arm_neon_ok] { + return "$flags -mvectorize-with-neon-double" + } + + return $flags +} + +# Add to FLAGS the flags needed to define the STACK_SIZE macro. + +proc add_options_for_stack_size { flags } { + if [is-effective-target stack_size] { + set stack_size [dg-effective-target-value stack_size] + return "$flags -DSTACK_SIZE=$stack_size" + } + + return $flags +} + +# Return 1 if the target provides a full C99 runtime. + +proc check_effective_target_c99_runtime { } { + return [check_cached_effective_target c99_runtime { + global srcdir + + set file [open "$srcdir/gcc.dg/builtins-config.h"] + set contents [read $file] + close $file + append contents { + #ifndef HAVE_C99_RUNTIME + #error !HAVE_C99_RUNTIME + #endif + } + check_no_compiler_messages_nocache c99_runtime assembly $contents + }] +} + +# Return 1 if the target provides the D runtime. + +proc check_effective_target_d_runtime { } { + return [check_no_compiler_messages d_runtime executable { + // D + module mod; + + extern(C) int main() { + return 0; + } + }] +} + +# Return 1 if the target provides the D standard library. + +proc check_effective_target_d_runtime_has_std_library { } { + return [check_no_compiler_messages d_runtime_has_std_library executable { + // D + module mod; + + extern(C) int main() { + import std.math; + real function(real) pcos = &cos; + return 0; + } + }] +} + +# Return 1 if target wchar_t is at least 4 bytes. + +proc check_effective_target_4byte_wchar_t { } { + return [check_no_compiler_messages 4byte_wchar_t object { + int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1]; + }] +} + +# Return 1 if the target supports automatic stack alignment. + +proc check_effective_target_automatic_stack_alignment { } { + # Ordinarily x86 supports automatic stack alignment ... + if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then { + if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } { + # ... except Win64 SEH doesn't. Succeed for Win32 though. + return [check_effective_target_ilp32]; + } + return 1; + } + return 0; +} + +# Return true if we are compiling for AVX target. + +proc check_avx_available { } { + if { [check_no_compiler_messages avx_available assembly { + #ifndef __AVX__ + #error unsupported + #endif + } ""] } { + return 1; + } + return 0; +} + +# Return true if we are compiling for AVX2 target. + +proc check_avx2_available { } { + if { [check_no_compiler_messages avx2_available assembly { + #ifndef __AVX2__ + #error unsupported + #endif + } ""] } { + return 1; + } + return 0; +} + +# Return true if we are compiling for SSSE3 target. + +proc check_ssse3_available { } { + if { [check_no_compiler_messages sse3a_available assembly { + #ifndef __SSSE3__ + #error unsupported + #endif + } ""] } { + return 1; + } + return 0; +} + +# Return true if 32- and 16-bytes vectors are available. + +proc check_effective_target_vect_sizes_32B_16B { } { + return [expr { [available_vector_sizes] == [list 256 128] }] +} + +# Return true if 16- and 8-bytes vectors are available. + +proc check_effective_target_vect_sizes_16B_8B { } { + if { [check_avx_available] + || [is-effective-target arm_neon] + || [istarget aarch64*-*-*] } { + return 1; + } else { + return 0; + } +} + + +# Return true if 128-bits vectors are preferred even if 256-bits vectors +# are available. + +proc check_prefer_avx128 { } { + if ![check_avx_available] { + return 0; + } + return [check_no_messages_and_pattern avx_explicit "xmm" assembly { + float a[1024],b[1024],c[1024]; + void foo (void) { int i; for (i = 0; i < 1024; i++) a[i]=b[i]+c[i];} + } "-O2 -ftree-vectorize"] +} + + +# Return 1 if avx512f instructions can be compiled. + +proc check_effective_target_avx512f { } { + return [check_no_compiler_messages avx512f object { + typedef double __m512d __attribute__ ((__vector_size__ (64))); + typedef double __m128d __attribute__ ((__vector_size__ (16))); + + __m512d _mm512_add (__m512d a) + { + return __builtin_ia32_addpd512_mask (a, a, a, 1, 4); + } + + __m128d _mm128_add (__m128d a) + { + return __builtin_ia32_addsd_round (a, a, 8); + } + + __m128d _mm128_getmant (__m128d a) + { + return __builtin_ia32_getmantsd_round (a, a, 0, 8); + } + } "-O2 -mavx512f" ] +} + +# Return 1 if avx instructions can be compiled. + +proc check_effective_target_avx { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages avx object { + void _mm256_zeroall (void) + { + __builtin_ia32_vzeroall (); + } + } "-O2 -mavx" ] +} + +# Return 1 if avx2 instructions can be compiled. +proc check_effective_target_avx2 { } { + return [check_no_compiler_messages avx2 object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + __v4di + mm256_is32_andnotsi256 (__v4di __X, __v4di __Y) + { + return __builtin_ia32_andnotsi256 (__X, __Y); + } + } "-O0 -mavx2" ] +} + +# Return 1 if sse instructions can be compiled. +proc check_effective_target_sse { } { + return [check_no_compiler_messages sse object { + int main () + { + __builtin_ia32_stmxcsr (); + return 0; + } + } "-O2 -msse" ] +} + +# Return 1 if sse2 instructions can be compiled. +proc check_effective_target_sse2 { } { + return [check_no_compiler_messages sse2 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + + __m128i _mm_srli_si128 (__m128i __A, int __N) + { + return (__m128i)__builtin_ia32_psrldqi128 (__A, 8); + } + } "-O2 -msse2" ] +} + +# Return 1 if sse4.1 instructions can be compiled. +proc check_effective_target_sse4 { } { + return [check_no_compiler_messages sse4.1 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_mullo_epi32 (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pmulld128 ((__v4si)__X, + (__v4si)__Y); + } + } "-O2 -msse4.1" ] +} + +# Return 1 if F16C instructions can be compiled. + +proc check_effective_target_f16c { } { + return [check_no_compiler_messages f16c object { + #include "immintrin.h" + float + foo (unsigned short val) + { + return _cvtsh_ss (val); + } + } "-O2 -mf16c" ] +} + +proc check_effective_target_ms_hook_prologue { } { + if { [check_no_compiler_messages ms_hook_prologue object { + void __attribute__ ((__ms_hook_prologue__)) foo (); + } ""] } { + return 1 + } else { + return 0 + } +} + +# Return 1 if 3dnow instructions can be compiled. +proc check_effective_target_3dnow { } { + return [check_no_compiler_messages 3dnow object { + typedef int __m64 __attribute__ ((__vector_size__ (8))); + typedef float __v2sf __attribute__ ((__vector_size__ (8))); + + __m64 _m_pfadd (__m64 __A, __m64 __B) + { + return (__m64) __builtin_ia32_pfadd ((__v2sf)__A, (__v2sf)__B); + } + } "-O2 -m3dnow" ] +} + +# Return 1 if sse3 instructions can be compiled. +proc check_effective_target_sse3 { } { + return [check_no_compiler_messages sse3 object { + typedef double __m128d __attribute__ ((__vector_size__ (16))); + typedef double __v2df __attribute__ ((__vector_size__ (16))); + + __m128d _mm_addsub_pd (__m128d __X, __m128d __Y) + { + return (__m128d) __builtin_ia32_addsubpd ((__v2df)__X, (__v2df)__Y); + } + } "-O2 -msse3" ] +} + +# Return 1 if ssse3 instructions can be compiled. +proc check_effective_target_ssse3 { } { + return [check_no_compiler_messages ssse3 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_abs_epi32 (__m128i __X) + { + return (__m128i) __builtin_ia32_pabsd128 ((__v4si)__X); + } + } "-O2 -mssse3" ] +} + +# Return 1 if aes instructions can be compiled. +proc check_effective_target_aes { } { + return [check_no_compiler_messages aes object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_aesimc_si128 (__m128i __X) + { + return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); + } + } "-O2 -maes" ] +} + +# Return 1 if vaes instructions can be compiled. +proc check_effective_target_vaes { } { + return [check_no_compiler_messages vaes object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_aesimc_si128 (__m128i __X) + { + return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); + } + } "-O2 -maes -mavx" ] +} + +# Return 1 if pclmul instructions can be compiled. +proc check_effective_target_pclmul { } { + return [check_no_compiler_messages pclmul object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i pclmulqdq_test (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, + (__v2di)__Y, + 1); + } + } "-O2 -mpclmul" ] +} + +# Return 1 if vpclmul instructions can be compiled. +proc check_effective_target_vpclmul { } { + return [check_no_compiler_messages vpclmul object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i pclmulqdq_test (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, + (__v2di)__Y, + 1); + } + } "-O2 -mpclmul -mavx" ] +} + +# Return 1 if sse4a instructions can be compiled. +proc check_effective_target_sse4a { } { + return [check_no_compiler_messages sse4a object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_insert_si64 (__m128i __X,__m128i __Y) + { + return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y); + } + } "-O2 -msse4a" ] +} + +# Return 1 if fma4 instructions can be compiled. +proc check_effective_target_fma4 { } { + return [check_no_compiler_messages fma4 object { + typedef float __m128 __attribute__ ((__vector_size__ (16))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) + { + return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, + (__v4sf)__B, + (__v4sf)__C); + } + } "-O2 -mfma4" ] +} + +# Return 1 if fma instructions can be compiled. +proc check_effective_target_fma { } { + return [check_no_compiler_messages fma object { + typedef float __m128 __attribute__ ((__vector_size__ (16))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) + { + return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, + (__v4sf)__B, + (__v4sf)__C); + } + } "-O2 -mfma" ] +} + +# Return 1 if xop instructions can be compiled. +proc check_effective_target_xop { } { + return [check_no_compiler_messages xop object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef short __v8hi __attribute__ ((__vector_size__ (16))); + __m128i _mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C) + { + return (__m128i) __builtin_ia32_vpmacssww ((__v8hi)__A, + (__v8hi)__B, + (__v8hi)__C); + } + } "-O2 -mxop" ] +} + +# Return 1 if lzcnt instruction can be compiled. +proc check_effective_target_lzcnt { } { + return [check_no_compiler_messages lzcnt object { + unsigned short _lzcnt (unsigned short __X) + { + return __builtin_clzs (__X); + } + } "-mlzcnt" ] +} + +# Return 1 if bmi instructions can be compiled. +proc check_effective_target_bmi { } { + return [check_no_compiler_messages bmi object { + unsigned int __bextr_u32 (unsigned int __X, unsigned int __Y) + { + return __builtin_ia32_bextr_u32 (__X, __Y); + } + } "-mbmi" ] +} + +# Return 1 if ADX instructions can be compiled. +proc check_effective_target_adx { } { + return [check_no_compiler_messages adx object { + unsigned char + _adxcarry_u32 (unsigned char __CF, unsigned int __X, + unsigned int __Y, unsigned int *__P) + { + return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P); + } + } "-madx" ] +} + +# Return 1 if rtm instructions can be compiled. +proc check_effective_target_rtm { } { + return [check_no_compiler_messages rtm object { + void + _rtm_xend (void) + { + return __builtin_ia32_xend (); + } + } "-mrtm" ] +} + +# Return 1 if avx512vl instructions can be compiled. +proc check_effective_target_avx512vl { } { + return [check_no_compiler_messages avx512vl object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + __v4di + mm256_and_epi64 (__v4di __X, __v4di __Y) + { + __v4di __W; + return __builtin_ia32_pandq256_mask (__X, __Y, __W, -1); + } + } "-mavx512vl" ] +} + +# Return 1 if avx512cd instructions can be compiled. +proc check_effective_target_avx512cd { } { + return [check_no_compiler_messages avx512cd_trans object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_conflict_epi64 (__v8di __W, __v8di __A) + { + return (__v8di) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A, + (__v8di) __W, + -1); + } + } "-Wno-psabi -mavx512cd" ] +} + +# Return 1 if avx512er instructions can be compiled. +proc check_effective_target_avx512er { } { + return [check_no_compiler_messages avx512er_trans object { + typedef float __v16sf __attribute__ ((__vector_size__ (64))); + __v16sf + mm512_exp2a23_ps (__v16sf __X) + { + return __builtin_ia32_exp2ps_mask (__X, __X, -1, 4); + } + } "-Wno-psabi -mavx512er" ] +} + +# Return 1 if sha instructions can be compiled. +proc check_effective_target_sha { } { + return [check_no_compiler_messages sha object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_sha1msg1_epu32 (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_sha1msg1 ((__v4si)__X, + (__v4si)__Y); + } + } "-O2 -msha" ] +} + +# Return 1 if avx512dq instructions can be compiled. +proc check_effective_target_avx512dq { } { + return [check_no_compiler_messages avx512dq object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_mask_mullo_epi64 (__v8di __W, __v8di __A, __v8di __B) + { + return (__v8di) __builtin_ia32_pmullq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) __W, + -1); + } + } "-mavx512dq" ] +} + +# Return 1 if avx512bw instructions can be compiled. +proc check_effective_target_avx512bw { } { + return [check_no_compiler_messages avx512bw object { + typedef short __v32hi __attribute__ ((__vector_size__ (64))); + __v32hi + _mm512_mask_mulhrs_epi16 (__v32hi __W, __v32hi __A, __v32hi __B) + { + return (__v32hi) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + -1); + } + } "-mavx512bw" ] +} + +# Return 1 if avx512vp2intersect instructions can be compiled. +proc check_effective_target_avx512vp2intersect { } { + return [check_no_compiler_messages avx512vp2intersect object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + typedef short __mmask16; + void + _mm512_2intersect_epi32 (__v16si __A, __v16si __B, __mmask16 *__U, + __mmask16 *__M) + { + __builtin_ia32_2intersectd512 (__U, __M, (__v16si) __A, (__v16si) __B); + } + } "-mavx512vp2intersect" ] +} + +# Return 1 if avx512ifma instructions can be compiled. +proc check_effective_target_avx512ifma { } { + return [check_no_compiler_messages avx512ifma object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_madd52lo_epu64 (__v8di __X, __v8di __Y, __v8di __Z) + { + return (__v8di) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X, + (__v8di) __Y, + (__v8di) __Z, + -1); + } + } "-mavx512ifma" ] +} + +# Return 1 if avx512vbmi instructions can be compiled. +proc check_effective_target_avx512vbmi { } { + return [check_no_compiler_messages avx512vbmi object { + typedef char __v64qi __attribute__ ((__vector_size__ (64))); + __v64qi + _mm512_multishift_epi64_epi8 (__v64qi __X, __v64qi __Y) + { + return (__v64qi) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X, + (__v64qi) __Y, + (__v64qi) __Y, + -1); + } + } "-mavx512vbmi" ] +} + +# Return 1 if avx512_4fmaps instructions can be compiled. +proc check_effective_target_avx5124fmaps { } { + return [check_no_compiler_messages avx5124fmaps object { + typedef float __v16sf __attribute__ ((__vector_size__ (64))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + + __v16sf + _mm512_mask_4fmadd_ps (__v16sf __DEST, __v16sf __A, __v16sf __B, __v16sf __C, + __v16sf __D, __v16sf __E, __v4sf *__F) + { + return (__v16sf) __builtin_ia32_4fmaddps_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__v16sf) __D, + (__v16sf) __E, + (const __v4sf *) __F, + (__v16sf) __DEST, + 0xffff); + } + } "-mavx5124fmaps" ] +} + +# Return 1 if avx512_4vnniw instructions can be compiled. +proc check_effective_target_avx5124vnniw { } { + return [check_no_compiler_messages avx5124vnniw object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __v16si + _mm512_4dpwssd_epi32 (__v16si __A, __v16si __B, __v16si __C, + __v16si __D, __v16si __E, __v4si *__F) + { + return (__v16si) __builtin_ia32_vp4dpwssd ((__v16si) __B, + (__v16si) __C, + (__v16si) __D, + (__v16si) __E, + (__v16si) __A, + (const __v4si *) __F); + } + } "-mavx5124vnniw" ] +} + +# Return 1 if avx512_vpopcntdq instructions can be compiled. +proc check_effective_target_avx512vpopcntdq { } { + return [check_no_compiler_messages avx512vpopcntdq object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v16si + _mm512_popcnt_epi32 (__v16si __A) + { + return (__v16si) __builtin_ia32_vpopcountd_v16si ((__v16si) __A); + } + } "-mavx512vpopcntdq" ] +} + +# Return 1 if 128 or 256-bit avx512_vpopcntdq instructions can be compiled. +proc check_effective_target_avx512vpopcntdqvl { } { + return [check_no_compiler_messages avx512vpopcntdqvl object { + typedef int __v8si __attribute__ ((__vector_size__ (32))); + + __v8si + _mm256_popcnt_epi32 (__v8si __A) + { + return (__v8si) __builtin_ia32_vpopcountd_v8si ((__v8si) __A); + } + } "-mavx512vpopcntdq -mavx512vl" ] +} + +# Return 1 if gfni instructions can be compiled. +proc check_effective_target_gfni { } { + return [check_no_compiler_messages gfni object { + typedef char __v16qi __attribute__ ((__vector_size__ (16))); + + __v16qi + _mm_gf2p8affineinv_epi64_epi8 (__v16qi __A, __v16qi __B, const int __C) + { + return (__v16qi) __builtin_ia32_vgf2p8affineinvqb_v16qi ((__v16qi) __A, + (__v16qi) __B, + 0); + } + } "-mgfni" ] +} + +# Return 1 if avx512vbmi2 instructions can be compiled. +proc check_effective_target_avx512vbmi2 { } { + return [check_no_compiler_messages avx512vbmi2 object { + typedef char __v16qi __attribute__ ((__vector_size__ (16))); + typedef unsigned long long __mmask16; + + __v16qi + _mm_mask_compress_epi8 (__v16qi __A, __mmask16 __B, __v16qi __C) + { + return (__v16qi) __builtin_ia32_compressqi128_mask((__v16qi)__C, + (__v16qi)__A, + (__mmask16)__B); + } + } "-mavx512vbmi2 -mavx512vl" ] +} + +# Return 1 if avx512vbmi2 instructions can be compiled. +proc check_effective_target_avx512vnni { } { + return [check_no_compiler_messages avx512vnni object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v16si + _mm_mask_compress_epi8 (__v16si __A, __v16si __B, __v16si __C) + { + return (__v16si) __builtin_ia32_vpdpbusd_v16si ((__v16si)__A, + (__v16si)__B, + (__v16si)__C); + } + } "-mavx512vnni -mavx512f" ] +} + +# Return 1 if vaes instructions can be compiled. +proc check_effective_target_avx512vaes { } { + return [check_no_compiler_messages avx512vaes object { + + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v32qi + _mm256_aesdec_epi128 (__v32qi __A, __v32qi __B) + { + return (__v32qi)__builtin_ia32_vaesdec_v32qi ((__v32qi) __A, (__v32qi) __B); + } + } "-mvaes" ] +} + +# Return 1 if vpclmulqdq instructions can be compiled. +proc check_effective_target_vpclmulqdq { } { + return [check_no_compiler_messages vpclmulqdq object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + + __v4di + _mm256_clmulepi64_epi128 (__v4di __A, __v4di __B) + { + return (__v4di) __builtin_ia32_vpclmulqdq_v4di (__A, __B, 0); + } + } "-mvpclmulqdq -mavx512vl" ] +} + +# Return 1 if avx512_bitalg instructions can be compiled. +proc check_effective_target_avx512bitalg { } { + return [check_no_compiler_messages avx512bitalg object { + typedef short int __v32hi __attribute__ ((__vector_size__ (64))); + + __v32hi + _mm512_popcnt_epi16 (__v32hi __A) + { + return (__v32hi) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A); + } + } "-mavx512bitalg" ] +} + +# Return 1 if C wchar_t type is compatible with char16_t. + +proc check_effective_target_wchar_t_char16_t_compatible { } { + return [check_no_compiler_messages wchar_t_char16_t object { + __WCHAR_TYPE__ wc; + __CHAR16_TYPE__ *p16 = &wc; + char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1]; + }] +} + +# Return 1 if C wchar_t type is compatible with char32_t. + +proc check_effective_target_wchar_t_char32_t_compatible { } { + return [check_no_compiler_messages wchar_t_char32_t object { + __WCHAR_TYPE__ wc; + __CHAR32_TYPE__ *p32 = &wc; + char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1]; + }] +} + +# Return 1 if pow10 function exists. + +proc check_effective_target_pow10 { } { + return [check_runtime pow10 { + #include + int main () { + double x; + x = pow10 (1); + return 0; + } + } "-lm" ] +} + +# Return 1 if frexpl function exists. + +proc check_effective_target_frexpl { } { + return [check_runtime frexpl { + #include + int main () { + long double x; + int y; + x = frexpl (5.0, &y); + return 0; + } + } "-lm" ] +} + + +# Return 1 if issignaling function exists. +proc check_effective_target_issignaling {} { + return [check_runtime issignaling { + #define _GNU_SOURCE + #include + int main () + { + return issignaling (0.0); + } + } "-lm" ] +} + +# Return 1 if current options generate DFP instructions, 0 otherwise. +proc check_effective_target_hard_dfp {} { + return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly { + typedef float d64 __attribute__((mode(DD))); + d64 x, y, z; + void foo (void) { z = x + y; } + }] +} + +# Return 1 if string.h and wchar.h headers provide C++ requires overloads +# for strchr etc. functions. + +proc check_effective_target_correct_iso_cpp_string_wchar_protos { } { + return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly { + #include + #include + #if !defined(__cplusplus) \ + || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \ + || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO) + ISO C++ correct string.h and wchar.h protos not supported. + #else + int i; + #endif + }] +} + +# Return 1 if GNU as is used. + +proc check_effective_target_gas { } { + global use_gas_saved + global tool + + if {![info exists use_gas_saved]} { + # Check if the as used by gcc is GNU as. + set options [list "additional_flags=-print-prog-name=as"] + set gcc_as [lindex [${tool}_target_compile "" "" "none" $options] 0] + # Provide /dev/null as input, otherwise gas times out reading from + # stdin. + set status [remote_exec host "$gcc_as" "-v /dev/null"] + set as_output [lindex $status 1] + if { [ string first "GNU" $as_output ] >= 0 } { + set use_gas_saved 1 + } else { + set use_gas_saved 0 + } + } + return $use_gas_saved +} + +# Return 1 if GNU ld is used. + +proc check_effective_target_gld { } { + global use_gld_saved + global tool + + if {![info exists use_gld_saved]} { + # Check if the ld used by gcc is GNU ld. + set options [list "additional_flags=-print-prog-name=ld"] + set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0] + set status [remote_exec host "$gcc_ld" "--version"] + set ld_output [lindex $status 1] + if { [ string first "GNU" $ld_output ] >= 0 } { + set use_gld_saved 1 + } else { + set use_gld_saved 0 + } + } + return $use_gld_saved +} + +# Return 1 if the compiler has been configure with link-time optimization +# (LTO) support. + +proc check_effective_target_lto { } { + if { [istarget nvptx-*-*] + || [istarget amdgcn-*-*] } { + return 0; + } + return [check_no_compiler_messages lto object { + void foo (void) { } + } "-flto"] +} + +# Return 1 if the compiler and linker support incremental link-time +# optimization. + +proc check_effective_target_lto_incremental { } { + if ![check_effective_target_lto] { + return 0 + } + return [check_no_compiler_messages lto_incremental executable { + int main () { return 0; } + } "-flto -r -nostdlib"] +} + +# Return 1 if the compiler has been configured with analyzer support. + +proc check_effective_target_analyzer { } { + return [check_no_compiler_messages analyzer object { + void foo (void) { } + } "-fanalyzer"] +} + +# Return 1 if -mx32 -maddress-mode=short can compile, 0 otherwise. + +proc check_effective_target_maybe_x32 { } { + return [check_no_compiler_messages maybe_x32 object { + void foo (void) {} + } "-mx32 -maddress-mode=short"] +} + +# Return 1 if this target supports the -fsplit-stack option, 0 +# otherwise. + +proc check_effective_target_split_stack {} { + return [check_no_compiler_messages split_stack object { + void foo (void) { } + } "-fsplit-stack"] +} + +# Return 1 if this target supports the -masm=intel option, 0 +# otherwise + +proc check_effective_target_masm_intel {} { + return [check_no_compiler_messages masm_intel object { + extern void abort (void); + } "-masm=intel"] +} + +# Return 1 if the language for the compiler under test is C. + +proc check_effective_target_c { } { + global tool + if [string match $tool "gcc"] { + return 1 + } + return 0 +} + +# Return 1 if the language for the compiler under test is C++. + +proc check_effective_target_c++ { } { + global tool + if { [string match $tool "g++"] || [string match $tool "libstdc++"] } { + return 1 + } + return 0 +} + +set cxx_default "c++14" +# Check whether the current active language standard supports the features +# of C++11/C++14 by checking for the presence of one of the -std flags. +# This assumes that the default for the compiler is $cxx_default, and that +# there will never be multiple -std= arguments on the command line. +proc check_effective_target_c++11_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }] { + return 1 + } + if { $cxx_default == "c++11" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} +proc check_effective_target_c++11 { } { + if [check_effective_target_c++11_only] { + return 1 + } + return [check_effective_target_c++14] +} +proc check_effective_target_c++11_down { } { + if ![check_effective_target_c++] { + return 0 + } + return [expr ![check_effective_target_c++14] ] +} + +proc check_effective_target_c++14_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++14 -std=gnu++14 -std=c++14 -std=gnu++14 } }] { + return 1 + } + if { $cxx_default == "c++14" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} + +proc check_effective_target_c++14 { } { + if [check_effective_target_c++14_only] { + return 1 + } + return [check_effective_target_c++17] +} +proc check_effective_target_c++14_down { } { + if ![check_effective_target_c++] { + return 0 + } + return [expr ![check_effective_target_c++17] ] +} + +proc check_effective_target_c++98_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++98 -std=gnu++98 -std=c++03 -std=gnu++03 } }] { + return 1 + } + if { $cxx_default == "c++98" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} + +proc check_effective_target_c++17_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++17 -std=gnu++17 -std=c++1z -std=gnu++1z } }] { + return 1 + } + if { $cxx_default == "c++17" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} + +proc check_effective_target_c++17 { } { + if [check_effective_target_c++17_only] { + return 1 + } + return [check_effective_target_c++2a] +} +proc check_effective_target_c++17_down { } { + if ![check_effective_target_c++] { + return 0 + } + return [expr ![check_effective_target_c++2a] ] +} + +proc check_effective_target_c++2a_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++2a -std=gnu++2a -std=c++20 -std=gnu++20 } }] { + return 1 + } + if { $cxx_default == "c++20" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} +proc check_effective_target_c++2a { } { + return [check_effective_target_c++2a_only] +} + +proc check_effective_target_c++20_only { } { + return [check_effective_target_c++2a_only] +} + +proc check_effective_target_c++20 { } { + return [check_effective_target_c++2a] +} + +# Check for C++ Concepts support, i.e. -fconcepts flag. +proc check_effective_target_concepts { } { + if [check_effective_target_c++2a] { + return 1 + } + return [check-flags { "" { } { -fconcepts } }] +} + +# Return 1 if expensive testcases should be run. + +proc check_effective_target_run_expensive_tests { } { + if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } { + return 1 + } + return 0 +} + +# Returns 1 if "mempcpy" is available on the target system. + +proc check_effective_target_mempcpy {} { + return [check_function_available "mempcpy"] +} + +# Returns 1 if "stpcpy" is available on the target system. + +proc check_effective_target_stpcpy {} { + return [check_function_available "stpcpy"] +} + +# Returns 1 if "sigsetjmp" is available on the target system. +# Also check if "__sigsetjmp" is defined since that's what glibc +# uses. + +proc check_effective_target_sigsetjmp {} { + if { [check_function_available "sigsetjmp"] + || [check_function_available "__sigsetjmp"] } { + return 1 + } + return 0 +} + +# Check whether the vectorizer tests are supported by the target and +# append additional target-dependent compile flags to DEFAULT_VECTCFLAGS. +# If a port wants to execute the tests more than once it should append +# the supported target to EFFECTIVE_TARGETS instead, and the compile flags +# will be added by a call to add_options_for_. +# Set dg-do-what-default to either compile or run, depending on target +# capabilities. Do not set this if the supported target is appended to +# EFFECTIVE_TARGETS. Flags and this variable will be set by et-dg-runtest +# automatically. Return the number of effective targets if vectorizer tests +# are supported, 0 otherwise. + +proc check_vect_support_and_set_flags { } { + global DEFAULT_VECTCFLAGS + global dg-do-what-default + global EFFECTIVE_TARGETS + + if [istarget powerpc-*paired*] { + lappend DEFAULT_VECTCFLAGS "-mpaired" + if [check_750cl_hw_available] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget powerpc*-*-*] { + # Skip targets not supporting -maltivec. + if ![is-effective-target powerpc_altivec_ok] { + return 0 + } + + lappend DEFAULT_VECTCFLAGS "-maltivec" + if [check_p9vector_hw_available] { + lappend DEFAULT_VECTCFLAGS "-mpower9-vector" + } elseif [check_p8vector_hw_available] { + lappend DEFAULT_VECTCFLAGS "-mpower8-vector" + } elseif [check_vsx_hw_available] { + lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign" + } + + if [check_vmx_hw_available] { + set dg-do-what-default run + } else { + if [is-effective-target ilp32] { + # Specify a cpu that supports VMX for compile-only tests. + lappend DEFAULT_VECTCFLAGS "-mcpu=970" + } + set dg-do-what-default compile + } + } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } { + lappend DEFAULT_VECTCFLAGS "-msse2" + if { [check_effective_target_sse2_runtime] } { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif { [istarget mips*-*-*] + && [check_effective_target_nomips16] } { + if { [check_effective_target_mpaired_single] } { + lappend EFFECTIVE_TARGETS mpaired_single + } + if { [check_effective_target_mips_loongson_mmi] } { + lappend EFFECTIVE_TARGETS mips_loongson_mmi + } + if { [check_effective_target_mips_msa] } { + lappend EFFECTIVE_TARGETS mips_msa + } + return [llength $EFFECTIVE_TARGETS] + } elseif [istarget sparc*-*-*] { + lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis" + if [check_effective_target_ultrasparc_hw] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget alpha*-*-*] { + # Alpha's vectorization capabilities are extremely limited. + # It's more effort than its worth disabling all of the tests + # that it cannot pass. But if you actually want to see what + # does work, command out the return. + return 0 + + lappend DEFAULT_VECTCFLAGS "-mmax" + if [check_alpha_max_hw_available] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget ia64-*-*] { + set dg-do-what-default run + } elseif [is-effective-target arm_neon_ok] { + eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""] + # NEON does not support denormals, so is not used for vectorization by + # default to avoid loss of precision. We must pass -ffast-math to test + # vectorization of float operations. + lappend DEFAULT_VECTCFLAGS "-ffast-math" + if [is-effective-target arm_neon_hw] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget "aarch64*-*-*"] { + set dg-do-what-default run + } elseif [istarget s390*-*-*] { + # The S/390 backend set a default of 2 for that value. + # Override it to have the same situation as with other + # targets. + lappend DEFAULT_VECTCFLAGS "--param" "min-vect-loop-bound=1" + lappend DEFAULT_VECTCFLAGS "--param" "max-unrolled-insns=200" + lappend DEFAULT_VECTCFLAGS "--param" "max-unroll-times=8" + lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peeled-insns=200" + lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peel-times=16" + if [check_effective_target_s390_vxe] { + lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch" + set dg-do-what-default run + } elseif [check_effective_target_s390_vx] { + lappend DEFAULT_VECTCFLAGS "-march=z13" "-mzarch" + set dg-do-what-default run + } else { + lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch" + set dg-do-what-default compile + } + } elseif [istarget amdgcn-*-*] { + set dg-do-what-default run + } else { + return 0 + } + + return 1 +} + +# Return 1 if the target does *not* require strict alignment. + +proc check_effective_target_non_strict_align {} { + + # On ARM, the default is to use STRICT_ALIGNMENT, but there + # are interfaces defined for misaligned access and thus + # depending on the architecture levels unaligned access is + # available. + if [istarget "arm*-*-*"] { + return [check_effective_target_arm_unaligned] + } + + return [check_no_compiler_messages non_strict_align assembly { + char *y; + typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c; + c *z; + void foo(void) { z = (c *) y; } + } "-Wcast-align"] +} + +# Return 1 if the target has . + +proc check_effective_target_ucontext_h { } { + return [check_no_compiler_messages ucontext_h assembly { + #include + }] +} + +proc check_effective_target_aarch64_tiny { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_tiny object { + #ifdef __AARCH64_CMODEL_TINY__ + int dummy; + #else + #error target not AArch64 tiny code model + #endif + }] + } else { + return 0 + } +} + +# Create functions to check that the AArch64 assembler supports the +# various architecture extensions via the .arch_extension pseudo-op. + +foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve" + "i8mm" "f32mm" "f64mm" "bf16" "sb" } { + eval [string map [list FUNC $aarch64_ext] { + proc check_effective_target_aarch64_asm_FUNC_ok { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_FUNC_assembler object { + __asm__ (".arch_extension FUNC"); + } "-march=armv8-a+FUNC"] + } else { + return 0 + } + } + }] +} + +proc check_effective_target_aarch64_small { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_small object { + #ifdef __AARCH64_CMODEL_SMALL__ + int dummy; + #else + #error target not AArch64 small code model + #endif + }] + } else { + return 0 + } +} + +proc check_effective_target_aarch64_large { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_large object { + #ifdef __AARCH64_CMODEL_LARGE__ + int dummy; + #else + #error target not AArch64 large code model + #endif + }] + } else { + return 0 + } +} + +# Return 1 if the assembler accepts the aarch64 .variant_pcs directive. + +proc check_effective_target_aarch64_variant_pcs { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_variant_pcs object { + __asm__ (".variant_pcs foo"); + }] + } else { + return 0 + } +} + +# Return 1 if this is a reduced AVR Tiny core. Such cores have different +# register set, instruction set, addressing capabilities and ABI. + +proc check_effective_target_avr_tiny { } { + if { [istarget avr*-*-*] } { + return [check_no_compiler_messages avr_tiny object { + #ifdef __AVR_TINY__ + int dummy; + #else + #error target not a reduced AVR Tiny core + #endif + }] + } else { + return 0 + } +} + +# Return 1 if is available. + +proc check_effective_target_fenv {} { + return [check_no_compiler_messages fenv object { + #include + } [add_options_for_ieee "-std=gnu99"]] +} + +# Return 1 if is available with all the standard IEEE +# exceptions and floating-point exceptions are raised by arithmetic +# operations. (If the target requires special options for "inexact" +# exceptions, those need to be specified in the testcases.) + +proc check_effective_target_fenv_exceptions {} { + return [check_runtime fenv_exceptions { + #include + #include + #ifndef FE_DIVBYZERO + # error Missing FE_DIVBYZERO + #endif + #ifndef FE_INEXACT + # error Missing FE_INEXACT + #endif + #ifndef FE_INVALID + # error Missing FE_INVALID + #endif + #ifndef FE_OVERFLOW + # error Missing FE_OVERFLOW + #endif + #ifndef FE_UNDERFLOW + # error Missing FE_UNDERFLOW + #endif + volatile float a = 0.0f, r; + int + main (void) + { + r = a / a; + if (fetestexcept (FE_INVALID)) + exit (0); + else + abort (); + } + } [add_options_for_ieee "-std=gnu99"]] +} + +# Return 1 if -fexceptions is supported. + +proc check_effective_target_exceptions {} { + if { [istarget amdgcn*-*-*] } { + return 0 + } + return 1 +} + +# Used to check if the testing configuration supports exceptions. +# Returns 0 if exceptions are unsupported or disabled (e.g. by passing +# -fno-exceptions). Returns 1 if exceptions are enabled. +proc check_effective_target_exceptions_enabled {} { + return [check_cached_effective_target exceptions_enabled { + if { [check_effective_target_exceptions] } { + return [check_no_compiler_messages exceptions_enabled assembly { + void foo (void) + { + throw 1; + } + }] + } else { + # If exceptions aren't supported, then they're not enabled. + return 0 + } + }] +} + +proc check_effective_target_tiny {} { + return [check_cached_effective_target tiny { + if { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_tiny] } { + return 1 + } + if { [istarget avr-*-*] + && [check_effective_target_avr_tiny] } { + return 1 + } + # PRU Program Counter is 16-bits, and trampolines are not supported. + # Hence directly declare as a tiny target. + if [istarget pru-*-*] { + return 1 + } + return 0 + }] +} + +# Return 1 if the target supports -mbranch-cost=N option. + +proc check_effective_target_branch_cost {} { + if { [ istarget arm*-*-*] + || [istarget avr*-*-*] + || [istarget csky*-*-*] + || [istarget epiphany*-*-*] + || [istarget frv*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget mips*-*-*] + || [istarget s390*-*-*] + || [istarget riscv*-*-*] + || [istarget sh*-*-*] } { + return 1 + } + return 0 +} + +# Record that dg-final test TEST requires convential compilation. + +proc force_conventional_output_for { test } { + if { [info proc $test] == "" } { + perror "$test does not exist" + exit 1 + } + proc ${test}_required_options {} { + global gcc_force_conventional_output + upvar 1 extra_tool_flags extra_tool_flags + if {[regexp -- "^scan-assembler" [info level 0]] + && ![string match "*-fident*" $extra_tool_flags]} { + # Do not let .ident confuse assembler scan tests + return [list $gcc_force_conventional_output "-fno-ident"] + } + return $gcc_force_conventional_output + } +} + +# Record that dg-final test scan-ltrans-tree-dump* requires -flto-partition=one +# in order to force a single partition, allowing scan-ltrans-tree-dump* to scan +# a dump file *.exe.ltrans0.*. + +proc scan-ltrans-tree-dump_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-times_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-not_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-dem_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-dem-not_required_options {} { + return "-flto-partition=one" +} + +# Return 1 if the x86-64 target supports PIE with copy reloc, 0 +# otherwise. Cache the result. + +proc check_effective_target_pie_copyreloc { } { + global tool + global GCC_UNDER_TEST + + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target pie_copyreloc { + # Set up and compile to see if linker supports PIE with copy + # reloc. Include the current process ID in the file names to + # prevent conflicts with invocations for multiple testsuites. + + 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_LD_PIE_COPYRELOC == 0" + puts $f "# error Linker does not support PIE with copy reloc." + puts $f "#endif" + close $f + + verbose "check_effective_target_pie_copyreloc 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_pie_copyreloc testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2 + return 0 + } + }] +} + +# Return 1 if the x86 target supports R_386_GOT32X relocation, 0 +# otherwise. Cache the result. + +proc check_effective_target_got32x_reloc { } { + global tool + global GCC_UNDER_TEST + + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target got32x_reloc { + # Include the current process ID in the file names to prevent + # conflicts with invocations for multiple testsuites. + + set src got32x[pid].c + set obj got32x[pid].o + + set f [open $src "w"] + puts $f "#include \"../../auto-host.h\"" + puts $f "#if HAVE_AS_IX86_GOT32X == 0" + puts $f "# error Assembler does not support R_386_GOT32X." + puts $f "#endif" + close $f + + verbose "check_effective_target_got32x_reloc 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_got32x_reloc testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_got32x_reloc testfile compilation failed" 2 + return 0 + } + }] + + return $got32x_reloc_available_saved +} + +# Return 1 if the x86 target supports calling ___tls_get_addr via GOT, +# 0 otherwise. Cache the result. + +proc check_effective_target_tls_get_addr_via_got { } { + global tool + global GCC_UNDER_TEST + + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target tls_get_addr_via_got { + # Include the current process ID in the file names to prevent + # conflicts with invocations for multiple testsuites. + + set src tls_get_addr_via_got[pid].c + set obj tls_get_addr_via_got[pid].o + + set f [open $src "w"] + puts $f "#include \"../../auto-host.h\"" + puts $f "#if HAVE_AS_IX86_TLS_GET_ADDR_GOT == 0" + puts $f "# error Assembler/linker do not support calling ___tls_get_addr via GOT." + puts $f "#endif" + close $f + + verbose "check_effective_target_tls_get_addr_via_got 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_tls_get_addr_via_got testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2 + return 0 + } + }] +} + +# Return 1 if the target uses comdat groups. + +proc check_effective_target_comdat_group {} { + return [check_no_messages_and_pattern comdat_group "\.section\[^\n\r]*,comdat|\.group\[^\n\r]*,#comdat" assembly { + // C++ + inline int foo () { return 1; } + int (*fn) () = foo; + }] +} + +# Return 1 if target supports __builtin_eh_return +proc check_effective_target_builtin_eh_return { } { + return [check_no_compiler_messages builtin_eh_return object { + void test (long l, void *p) + { + __builtin_eh_return (l, p); + } + } "" ] +} + +# Return 1 if the target supports max reduction for vectors. + +proc check_effective_target_vect_max_reduc { } { + if { [istarget aarch64*-*-*] || [is-effective-target arm_neon] } { + return 1 + } + return 0 +} + +# Return 1 if the compiler has been configured with hsa offloading. + +proc check_effective_target_offload_hsa { } { + return [check_no_compiler_messages offload_hsa assembly { + int main () {return 0;} + } "-foffload=hsa" ] +} + +# Return 1 if the compiler has been configured with hsa offloading. + +proc check_effective_target_offload_gcn { } { + return [check_no_compiler_messages offload_gcn assembly { + int main () {return 0;} + } "-foffload=amdgcn-amdhsa" ] +} + +# Return 1 if the target support -fprofile-update=atomic +proc check_effective_target_profile_update_atomic {} { + return [check_no_compiler_messages profile_update_atomic assembly { + int main (void) { return 0; } + } "-fprofile-update=atomic -fprofile-generate"] +} + +# Return 1 if vector (va - vector add) instructions are understood by +# the assembler and can be executed. This also covers checking for +# the VX kernel feature. A kernel without that feature does not +# enable the vector facility and the following check will die with a +# signal. +proc check_effective_target_s390_vx { } { + if ![istarget s390*-*-*] then { + return 0; + } + + return [check_runtime s390_check_vx { + int main (void) + { + asm ("va %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28"); + return 0; + } + } "-march=z13 -mzarch" ] +} + +# Same as above but for the z14 vector enhancement facility. Test +# is performed with the vector nand instruction. +proc check_effective_target_s390_vxe { } { + if ![istarget s390*-*-*] then { + return 0; + } + + return [check_runtime s390_check_vxe { + int main (void) + { + asm ("vnn %%v24, %%v26, %%v28" : : : "v24", "v26", "v28"); + return 0; + } + } "-march=z14 -mzarch" ] +} + +# Same as above but for the arch13 vector enhancement facility. Test +# is performed with the vector shift left double by bit instruction. +proc check_effective_target_s390_vxe2 { } { + if ![istarget s390*-*-*] then { + return 0; + } + + return [check_runtime s390_check_vxe2 { + int main (void) + { + asm ("vsld %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28"); + return 0; + } + } "-march=arch13 -mzarch" ] +} + +#For versions of ARM architectures that have hardware div insn, +#disable the divmod transform + +proc check_effective_target_arm_divmod_simode { } { + return [check_no_compiler_messages arm_divmod assembly { + #ifdef __ARM_ARCH_EXT_IDIV__ + #error has div insn + #endif + int i; + }] +} + +# Return 1 if target supports divmod hardware insn or divmod libcall. + +proc check_effective_target_divmod { } { + #TODO: Add checks for all targets that have either hardware divmod insn + # or define libfunc for divmod. + if { [istarget arm*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] } { + return 1 + } + return 0 +} + +# Return 1 if target supports divmod for SImode. The reason for +# separating this from check_effective_target_divmod is that +# some versions of ARM architecture define div instruction +# only for simode, and for these archs, we do not want to enable +# divmod transform for simode. + +proc check_effective_target_divmod_simode { } { + if { [istarget arm*-*-*] } { + return [check_effective_target_arm_divmod_simode] + } + + return [check_effective_target_divmod] +} + +# Return 1 if store merging optimization is applicable for target. +# Store merging is not profitable for targets like the avr which +# can load/store only one byte at a time. Use int size as a proxy +# for the number of bytes the target can write, and skip for targets +# with a smallish (< 32) size. + +proc check_effective_target_store_merge { } { + if { [is-effective-target non_strict_align ] && [is-effective-target int32plus] } { + return 1 + } + + return 0 +} + +# Return 1 if we're able to assemble rdrand + +proc check_effective_target_rdrand { } { + return [check_no_compiler_messages_nocache rdrand object { + unsigned int + __foo(void) + { + unsigned int val; + __builtin_ia32_rdrand32_step(&val); + return val; + } + } "-mrdrnd" ] +} + +# Return 1 if the target supports coprocessor instructions: cdp, ldc, ldcl, +# stc, stcl, mcr and mrc. +proc check_effective_target_arm_coproc1_ok_nocache { } { + if { ![istarget arm*-*-*] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc1_ok assembly { + #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 4 + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc1_ok { } { + return [check_cached_effective_target arm_coproc1_ok \ + check_effective_target_arm_coproc1_ok_nocache] +} + +# Return 1 if the target supports all coprocessor instructions checked by +# check_effective_target_arm_coproc1_ok in addition to the following: cdp2, +# ldc2, ldc2l, stc2, stc2l, mcr2 and mrc2. +proc check_effective_target_arm_coproc2_ok_nocache { } { + if { ![check_effective_target_arm_coproc1_ok] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc2_ok assembly { + #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 5 + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc2_ok { } { + return [check_cached_effective_target arm_coproc2_ok \ + check_effective_target_arm_coproc2_ok_nocache] +} + +# Return 1 if the target supports all coprocessor instructions checked by +# check_effective_target_arm_coproc2_ok in addition the following: mcrr and +# mrrc. +proc check_effective_target_arm_coproc3_ok_nocache { } { + if { ![check_effective_target_arm_coproc2_ok] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc3_ok assembly { + #if (__thumb__ && !__thumb2__) \ + || (__ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE__)) + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc3_ok { } { + return [check_cached_effective_target arm_coproc3_ok \ + check_effective_target_arm_coproc3_ok_nocache] +} + +# Return 1 if the target supports all coprocessor instructions checked by +# check_effective_target_arm_coproc3_ok in addition the following: mcrr2 and +# mrcc2. +proc check_effective_target_arm_coproc4_ok_nocache { } { + if { ![check_effective_target_arm_coproc3_ok] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc4_ok assembly { + #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 6 + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc4_ok { } { + return [check_cached_effective_target arm_coproc4_ok \ + check_effective_target_arm_coproc4_ok_nocache] +} + +# Return 1 if the target supports the auto_inc_dec optimization pass. +proc check_effective_target_autoincdec { } { + if { ![check_no_compiler_messages auto_incdec assembly { void f () { } + } "-O2 -fdump-rtl-auto_inc_dec" ] } { + return 0 + } + + set dumpfile [glob -nocomplain "auto_incdec[pid].c.\[0-9\]\[0-9\]\[0-9\]r.auto_inc_dec"] + if { [file exists $dumpfile ] } { + file delete $dumpfile + return 1 + } + return 0 +} + +# Return 1 if the target has support for stack probing designed +# to avoid stack-clash style attacks. +# +# This is used to restrict the stack-clash mitigation tests to +# just those targets that have been explicitly supported. +# +# In addition to the prologue work on those targets, each target's +# properties should be described in the functions below so that +# tests do not become a mess of unreadable target conditions. +# +proc check_effective_target_supports_stack_clash_protection { } { + + if { [istarget x86_64-*-*] || [istarget i?86-*-*] + || [istarget powerpc*-*-*] || [istarget rs6000*-*-*] + || [istarget aarch64*-**] || [istarget s390*-*-*] } { + return 1 + } + return 0 +} + +# Return 1 if the target creates a frame pointer for non-leaf functions +# Note we ignore cases where we apply tail call optimization here. +proc check_effective_target_frame_pointer_for_non_leaf { } { + # Solaris/x86 defaults to -fno-omit-frame-pointer. + if { [istarget i?86-*-solaris*] || [istarget x86_64-*-solaris*] } { + return 1 + } + + return 0 +} + +# Return 1 if the target's calling sequence or its ABI +# create implicit stack probes at or prior to function entry. +proc check_effective_target_caller_implicit_probes { } { + + # On x86/x86_64 the call instruction itself pushes the return + # address onto the stack. That is an implicit probe of *sp. + if { [istarget x86_64-*-*] || [istarget i?86-*-*] } { + return 1 + } + + # On PPC, the ABI mandates that the address of the outer + # frame be stored at *sp. Thus each allocation of stack + # space is itself an implicit probe of *sp. + if { [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } { + return 1 + } + + # s390's ABI has a register save area allocated by the + # caller for use by the callee. The mere existence does + # not constitute a probe by the caller, but when the slots + # used by the callee those stores are implicit probes. + if { [istarget s390*-*-*] } { + return 1 + } + + # Not strictly true on aarch64, but we have agreed that we will + # consider any function that pushes SP more than 3kbytes into + # the guard page as broken. This essentially means that we can + # consider the aarch64 as having a caller implicit probe at + # *(sp + 1k). + if { [istarget aarch64*-*-*] } { + return 1; + } + + return 0 +} + +# Targets that potentially realign the stack pointer often cause residual +# stack allocations and make it difficult to elimination loops or residual +# allocations for dynamic stack allocations +proc check_effective_target_callee_realigns_stack { } { + if { [istarget x86_64-*-*] || [istarget i?86-*-*] } { + return 1 + } + return 0 +} + +# Return 1 if CET instructions can be compiled. +proc check_effective_target_cet { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages cet object { + void foo (void) + { + asm ("setssbsy"); + } + } "-O2 -fcf-protection" ] +} + +# Return 1 if target supports floating point "infinite" +proc check_effective_target_inf { } { + return [check_no_compiler_messages supports_inf assembly { + const double pinf = __builtin_inf (); + }] +} + +# Return 1 if the target supports ARMv8.3 Adv.SIMD Complex instructions +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_3a_complex_neon_ok_nocache { } { + global et_arm_v8_3a_complex_neon_flags + set et_arm_v8_3a_complex_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=auto" "-mfloat-abi=hard -mfpu=auto"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_3a_complex_neon_ok object { + #if !defined (__ARM_FEATURE_COMPLEX) + #error "__ARM_FEATURE_COMPLEX not defined" + #endif + } "$flags -march=armv8.3-a"] } { + set et_arm_v8_3a_complex_neon_flags "$flags -march=armv8.3-a" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_3a_complex_neon_ok { } { + return [check_cached_effective_target arm_v8_3a_complex_neon_ok \ + check_effective_target_arm_v8_3a_complex_neon_ok_nocache] +} + +proc add_options_for_arm_v8_3a_complex_neon { flags } { + if { ! [check_effective_target_arm_v8_3a_complex_neon_ok] } { + return "$flags" + } + global et_arm_v8_3a_complex_neon_flags + return "$flags $et_arm_v8_3a_complex_neon_flags" +} + +# Return 1 if the target supports executing AdvSIMD instructions from ARMv8.3 +# with the complex instruction extension, 0 otherwise. The test is valid for +# ARM and for AArch64. + +proc check_effective_target_arm_v8_3a_complex_neon_hw { } { + if { ![check_effective_target_arm_v8_3a_complex_neon_ok] } { + return 0; + } + return [check_runtime arm_v8_3a_complex_neon_hw_available { + #include "arm_neon.h" + int + main (void) + { + + float32x2_t results = {-4.0,5.0}; + float32x2_t a = {1.0,3.0}; + float32x2_t b = {2.0,5.0}; + + #ifdef __ARM_ARCH_ISA_A64 + asm ("fcadd %0.2s, %1.2s, %2.2s, #90" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + + #else + asm ("vcadd.f32 %P0, %P1, %P2, #90" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + #endif + + return (results[0] == 8 && results[1] == 24) ? 1 : 0; + } + } [add_options_for_arm_v8_3a_complex_neon ""]] +} + +# Return 1 if the assembler supports assembling the Armv8.3 pointer authentication B key directive +proc check_effective_target_arm_v8_3a_bkey_directive { } { + return [check_no_compiler_messages cet object { + int main(void) { + asm (".cfi_b_key_frame"); + return 0; + } + }] +} + +# Returns 1 if the target is using glibc, 0 otherwise. + +proc check_effective_target_glibc { } { + return [check_no_compiler_messages glibc_object assembly { + #include + #if !defined(__GLIBC__) + #error undefined + #endif + }] +} + +# Return 1 if the target plus current options supports a vector +# complex addition with rotate of half and single float modes, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +foreach N {hf sf} { + eval [string map [list N $N] { + proc check_effective_target_vect_complex_rot_N { } { + return [check_cached_effective_target_indexed vect_complex_rot_N { + expr { [istarget aarch64*-*-*] + || [istarget arm*-*-*] }}] + } + }] +} + +# Return 1 if the target plus current options supports a vector +# complex addition with rotate of double float modes, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +foreach N {df} { + eval [string map [list N $N] { + proc check_effective_target_vect_complex_rot_N { } { + return [check_cached_effective_target_indexed vect_complex_rot_N { + expr { [istarget aarch64*-*-*] }}] + } + }] +} + +# Return 1 if this target uses an LLVM assembler and/or linker +proc check_effective_target_llvm_binutils { } { + return [check_cached_effective_target llvm_binutils { + expr { [istarget amdgcn*-*-*] + || [check_effective_target_offload_gcn] }}] +} + +# Return 1 if the compiler supports '-mfentry'. + +proc check_effective_target_mfentry { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages mfentry object { + void foo (void) { } + } "-mfentry"] +} + +# Return 1 if this target supports indirect calls +proc check_effective_target_indirect_calls { } { + if { [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if we're able to assemble movdiri and movdir64b + +proc check_effective_target_movdir { } { + return [check_no_compiler_messages movdir object { + void + foo (unsigned int *d, unsigned int s) + { + __builtin_ia32_directstoreu_u32 (d, s); + } + void + bar (void *d, const void *s) + { + __builtin_ia32_movdir64b (d, s); + } + } "-mmovdiri -mmovdir64b" ] +} + +# Return 1 if GCC was configured with --with-tune=cortex-a76 +proc check_effective_target_tune_cortex_a76 { } { + return [check_configured_with "with-tune=cortex-a76"] +} + +# Return 1 if target is not support address sanitize, 1 otherwise. + +proc check_effective_target_no_fsanitize_address {} { + if ![check_no_compiler_messages fsanitize_address executable { + int main (void) { return 0; } + }] { + return 1; + } + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-utils.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-utils.exp new file mode 100644 index 0000000000000000000000000000000000000000..18ccacd2cbd0298bd22a77a25f9b2b6c0b1485f7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/target-utils.exp @@ -0,0 +1,52 @@ +# Copyright (C) 2014-2020 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 +# . + +# +# ${tool}_check_unsupported_p -- Check the compiler(/assembler/linker) output +# for text indicating that the testcase should be marked as "unsupported" +# +# When dealing with a large number of tests, it's difficult to weed out the +# ones that are too big for a particular cpu (eg: 16 bit with a small amount +# of memory). There are various ways to deal with this. Here's one. +# Fortunately, all of the cases where this is likely to happen will be using +# gld so we can tell what the error text will look like. +# + +load_lib target-supports.exp + +proc ${tool}_check_unsupported_p { output } { + if [regexp "(^|\n)\[^\n\]*: region \[^\n\]* is full" $output] { + return "memory full" + } + if { [regexp "(^|\n)\[^\n\]*: relocation truncated to fit" $output] + && [check_effective_target_tiny] } { + return "memory full" + } + if { [regexp "(^|\n)\[^\n\]*: region \[^\n\]* overflowed" $output] + && [check_effective_target_tiny] } { + return "memory full" + } + + if { [string match "*error: function pointers not supported*" $output] + && ![check_effective_target_function_pointers] } { + return "function pointers not supported" + } + if { [string match "*error: large return values not supported*" $output] + && ![check_effective_target_large_return_values] } { + return "large return values not supported" + } + return "" +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/timeout-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/timeout-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..228204bb2dbf58e6acc23b1af57fb184b4c1bea2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/timeout-dg.exp @@ -0,0 +1,49 @@ +# Copyright (C) 2008-2020 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 +# . + +# +# dg-timeout -- Set the timout limit, in seconds, for a particular test +# + +proc dg-timeout { args } { + global individual_timeout + + set args [lreplace $args 0 0] + if { [llength $args] > 1 } { + if { [dg-process-target [lindex $args 1]] == "S" } { + set individual_timeout [lindex $args 0] + } + } else { + set individual_timeout [lindex $args 0] + } +} + +# +# dg-timeout-factor -- Scale the timeout limit for a particular test +# + +proc dg-timeout-factor { args } { + global timeout_factor + + set args [lreplace $args 0 0] + if { [llength $args] > 1 } { + if { [dg-process-target [lindex $args 1]] == "S" } { + set timeout_factor [lindex $args 0] + } + } else { + set timeout_factor [lindex $args 0] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/timeout.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/timeout.exp new file mode 100644 index 0000000000000000000000000000000000000000..856c2e3184122cbd1128116703fef5480ec8805e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/timeout.exp @@ -0,0 +1,83 @@ +# Copyright (C) 2008-2020 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 +# . + +# +# unset_timeout_vars -- Unset variables used for timeouts +# + +proc unset_timeout_vars { args } { + global individual_timeout + global timeout_factor + + if [info exists individual_timeout] { + unset individual_timeout + } + if [info exists timeout_factor] { + unset timeout_factor + } +} + +# +# timeout_value -- Return the integer timeout value to use for this test +# + +proc timeout_value { args } { + global tool_timeout + global individual_timeout + global timeout_factor + + # Find the current timeout limit, in seconds. + if [info exists individual_timeout] { + set val $individual_timeout + } elseif [info exists tool_timeout] { + set val $tool_timeout + } elseif [target_info exists gcc,timeout] { + set val [target_info gcc,timeout] + } elseif [board_info target exists gcc,timeout] { + set val [board_info target gcc,timeout] + } else { + # This is really, REALLY ugly, but this is the default from + # remote.exp deep within DejaGnu. + set val 300 + } + + # If the test specified a timeout factor, adjust by that. + if [info exists timeout_factor] { + set val [expr int([expr $val * $timeout_factor])] + } + + return $val +} + +# +# standard_wait -- Set the timeout value used by DejaGnu +# + +# Override standard_wait from DejaGnu to use timeout value specified by +# by the user or by the target board, possibly multiplied by a factor +# for a particular test. + +if { [info procs standard_wait] != [list] \ + && [info procs saved_standard_wait] == [list] } { + rename standard_wait saved_standard_wait + proc standard_wait { dest timeout } { + set val [timeout_value] + if { $val != 0 } { + set timeout $val + } + saved_standard_wait $dest $timeout + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/torture-options.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/torture-options.exp new file mode 100644 index 0000000000000000000000000000000000000000..4d7cb0c41b7c83bf8eadb0513b46eb688737549b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/torture-options.exp @@ -0,0 +1,120 @@ +# Copyright (C) 2008-2020 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 +# . + +# Prepare to use a new set of torture options. +# +# Letting options leak from one set of tests to another can be confusing. +# Make sure variables are not set at the time we're called, because that +# would mean they were set without being cleared. +proc torture-init { args } { + global torture_without_loops global_with_loops + + if [info exists torture_without_loops] { + error "torture-init: torture_without_loops is not empty as expected" + } + if [info exists torture_with_loops] { + error "torture-init: torture_with_loops is not empty as expected" + } +} + +# Return 1 if torture options have already been set, 0 otherwise. +proc torture-options-exist { args } { + global torture_with_loops + return [info exists torture_with_loops] +} + +# Return 1 if compiler option ARG only affects loops, 0 otherwise. +proc contains-loop-option-p { arg } { + switch -glob -- $arg { + "*loop*" { return 1 } + default { return 0 } + } +} + +# Set torture options variables for tests with and without loops. +# +# Argument 0 is the list to use as torture options +# Argument 1 is the list to combine with the torture options. +# Argument 2 is the list to be appended to the torture options after +# combining argument 0 and 1. +proc set-torture-options { args } { + global torture_with_loops torture_without_loops + + set torture_list [lindex $args 0] + + if { [llength $args] > 1 } { + set other_list [lindex $args 1] + } else { + set other_list [list {}] + } + + set torture_with_loops "" + set torture_without_loops "" + foreach torture_opts $torture_list { + foreach other_opts $other_list { + # Remove trailing space[s] to match previous output. + set torture_opts [string trimright $torture_opts] + if ![contains-loop-option-p $torture_opts] { + lappend torture_without_loops "$torture_opts $other_opts" + } + lappend torture_with_loops "$torture_opts $other_opts" + } + } + + if { [llength $args] > 2 } { + set append_list [lindex $args 2] + append torture_with_loops " $append_list" + append torture_without_loops " $append_list" + } +} + +# Finish up after using a set of torture options. +# +# Letting options leak from one set of tests to another can be confusing. +# Make sure variables are set at the time we're called, and then unset +# them to prevent interference with other sets of tests. +proc torture-finish { args } { + global torture_without_loops torture_with_loops + + if [info exists torture_without_loops] { + unset torture_without_loops + } else { + error "torture-finish: torture_without_loops is not defined" + } + + if [info exists torture_with_loops] { + unset torture_with_loops + } else { + error "torture-finish: torture_with_loops is not defined" + } +} + +# Useful for debugging .exp files. +proc dump-torture-options { args } { + global torture_without_loops torture_with_loops + + if [info exists torture_without_loops] { + verbose "torture_without_loops = \"${torture_without_loops}\"" 1 + } else { + verbose "torture_without_loops is not defined" 1 + } + + if [info exists torture_with_loops] { + verbose "torture_with_loops = \"${torture_with_loops}\"" 1 + } else { + verbose "torture_with_loops is not defined" 1 + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/tsan-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/tsan-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..b5631a79bcf7f07361b9faa6bdd37e6ccf7a6409 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/tsan-dg.exp @@ -0,0 +1,156 @@ +# Copyright (C) 2013-2020 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 +# . + +# Return 1 if compilation with -fsanitize=thread is error-free for trivial +# code, 0 otherwise. Also set what to do by default here, depending on the +# result of a runtime test. + +proc check_effective_target_fsanitize_thread {} { + global individual_timeout + global dg-do-what-default + + if ![check_no_compiler_messages fsanitize_thread executable { + int main (void) { return 0; } + }] { + return 0 + } + + # Lower timeout value in case test does not terminate properly. + set individual_timeout 20 + if [check_runtime_nocache tsan_works { + int main () { return 0; } + }] { + set dg-do-what-default run + } else { + set dg-do-what-default link + } + unset individual_timeout + + return 1 +} + +# +# tsan_link_flags -- compute library path and flags to find libtsan. +# (originally from g++.exp) +# + +proc tsan_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + global tsan_saved_library_path + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + set tsan_saved_library_path $ld_library_path + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/tsan/.libs/libtsan.a"] + || [file exists "${gccpath}/libsanitizer/tsan/.libs/libtsan.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/tsan/ " + append flags " -L${gccpath}/libsanitizer/tsan/.libs " + append ld_library_path ":${gccpath}/libsanitizer/tsan/.libs" + } + } else { + global tool_root_dir + + set libtsan [lookfor_file ${tool_root_dir} libtsan] + if { $libtsan != "" } { + append flags "-L${libtsan} " + append ld_library_path ":${libtsan}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# tsan_init -- called at the start of each subdir of tests +# + +proc tsan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global tsan_saved_TEST_ALWAYS_FLAGS + global tsan_saved_ALWAYS_CXXFLAGS + global dg-do-what-default + global tsan_saved_dg-do-what-default + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[tsan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[tsan_link_flags [get_multilibs]]" + } + } + + if [info exists dg-do-what-default] { + set tsan_saved_dg-do-what-default ${dg-do-what-default} + } + if [info exists TEST_ALWAYS_FLAGS] { + set tsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set tsan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=thread -g}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=thread -g $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=thread -g" + } + } +} + +# +# tsan_finish -- called at the end of each subdir of tests +# + +proc tsan_finish { args } { + global TEST_ALWAYS_FLAGS + global tsan_saved_TEST_ALWAYS_FLAGS + global tsan_saved_ALWAYS_CXXFLAGS + global dg-do-what-default + global tsan_saved_dg-do-what-default + global tsan_saved_library_path + global ld_library_path + + if [info exists tsan_saved_ALWAYS_CXXFLAGS ] { + set ALWAYS_CXXFLAGS $tsan_saved_ALWAYS_CXXFLAGS + } else { + if [info exists tsan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $tsan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + + if [info exists tsan_saved_dg-do-what-default] { + set dg-do-what-default ${tsan_saved_dg-do-what-default} + } else { + unset dg-do-what-default + } + set ld_library_path $tsan_saved_library_path + set_ld_library_path_env_vars + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/ubsan-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/ubsan-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..015601cd4049943a5d3d1937b468ff09bbc32d0e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/ubsan-dg.exp @@ -0,0 +1,125 @@ +# Copyright (C) 2013-2020 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 +# . + +# Return 1 if compilation with -fsanitize=undefined is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fsanitize_undefined {} { + return [check_runtime fsanitize_undefined { + int main (void) { return 0; } + } "-fsanitize=undefined"] +} + +# +# ubsan_link_flags -- compute library path and flags to find libubsan. +# (originally from g++.exp) +# + +proc ubsan_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + global ubsan_saved_library_path + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + set ubsan_saved_library_path $ld_library_path + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.a"] + || [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/ " + append flags " -B${gccpath}/libsanitizer/ubsan/ " + append flags " -L${gccpath}/libsanitizer/ubsan/.libs" + append ld_library_path ":${gccpath}/libsanitizer/ubsan/.libs" + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + } else { + global tool_root_dir + + set libubsan [lookfor_file ${tool_root_dir} libubsan] + if { $libubsan != "" } { + append flags "-L${libubsan} " + append ld_library_path ":${libubsan}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# ubsan_init -- called at the start of each subdir of tests +# + +proc ubsan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global ubsan_saved_TEST_ALWAYS_FLAGS + global ubsan_saved_ALWAYS_CXXFLAGS + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[ubsan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[ubsan_link_flags [get_multilibs]]" + } + } + + if [info exists TEST_ALWAYS_FLAGS] { + set ubsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set ubsan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags" + } + } +} + +# +# ubsan_finish -- called at the end of each subdir of tests +# + +proc ubsan_finish { args } { + global TEST_ALWAYS_FLAGS + global ubsan_saved_TEST_ALWAYS_FLAGS + global ubsan_saved_ALWAYS_CXXFLAGS + global ubsan_saved_library_path + global ld_library_path + + if [info exists ubsan_saved_ALWAYS_CXXFLAGS ] { + set ALWAYS_CXXFLAGS $ubsan_saved_ALWAYS_CXXFLAGS + } else { + if [info exists ubsan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $ubsan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + set ld_library_path $ubsan_saved_library_path + set_ld_library_path_env_vars + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/wrapper.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/wrapper.exp new file mode 100644 index 0000000000000000000000000000000000000000..3170ad5f20d14f02a403d5b82c6709f56dd11dc0 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/lib/wrapper.exp @@ -0,0 +1,48 @@ +# Copyright (C) 2004-2020 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 +# . + +# This file contains GCC-specifics for status wrappers for test programs. + +# ${tool}_maybe_build_wrapper -- Build wrapper object if the target +# needs it. FILENAME is the path to the wrapper file. If there are +# additional arguments, they are command-line options to provide to +# the compiler when compiling FILENAME. + +proc ${tool}_maybe_build_wrapper { filename args } { + global gluefile wrap_flags + + if { [target_info needs_status_wrapper] != "" \ + && [target_info needs_status_wrapper] != "0" \ + && ![info exists gluefile] } { + set_ld_library_path_env_vars + set saved_wrap_compile_flags [target_info wrap_compile_flags] + set flags [join $args " "] + # The wrapper code may contain code that gcc objects on. This + # became true for dejagnu-1.4.4. The set of warnings and code + # that gcc objects on may change, so just make sure -w is always + # passed to turn off all warnings. + unset_currtarget_info wrap_compile_flags + set_currtarget_info wrap_compile_flags \ + "$saved_wrap_compile_flags -w $flags" + set result [build_wrapper $filename] + unset_currtarget_info wrap_compile_flags + set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags" + if { $result != "" } { + set gluefile [lindex $result 0] + set wrap_flags [lindex $result 1] + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/site.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/site.exp new file mode 100644 index 0000000000000000000000000000000000000000..51a4ff73092cabbd0b631551a6e88e68e828558e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc10/site.exp @@ -0,0 +1,23 @@ +## these variables are automatically generated by make ## +# Do not edit here. If you wish to override these values +# add them to the last section +set host_triplet aarch64-openEuler-linux-gnu +set build_triplet aarch64-openEuler-linux-gnu +set target_triplet aarch64-openEuler-linux-gnu +set target_alias aarch64-linux-gnu +set libiconv "" +set CFLAGS "" +set CXXFLAGS "" +set HOSTCC "gcc" +set HOSTCXX "g++" +set HOSTCFLAGS "-g -O2" +set HOSTCXXFLAGS "-g -O2" +set TEST_ALWAYS_FLAGS "" +set TEST_GCC_EXEC_PREFIX "/usr" +set TESTING_IN_BUILD_TREE 1 +set HAVE_LIBSTDCXX_V3 1 +set ENABLE_PLUGIN 1 +set PLUGINCC "g++" +set PLUGINCFLAGS "-g " +set GMPINC "" +## All variables above are generated by configure. Do Not Edit ## diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/config/default.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/config/default.exp new file mode 100644 index 0000000000000000000000000000000000000000..90322d2c2aa37dfbdd8b43002d783f98fadab6b2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/config/default.exp @@ -0,0 +1,17 @@ +# Copyright (C) 1997-2022 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 +# . + +load_lib "standard.exp" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..23542ace87e94ff723dfd76cc160e6bfce3faf84 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/dg.exp @@ -0,0 +1,57 @@ +# Copyright (C) 2000-2022 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 +# . + +# G++ testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib g++-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors -Wno-long-long" +} + +# Initialize `dg'. +dg-init + +# Recursively find files in $dir and subdirs, do not walk into subdirs +# that contain their own .exp file. +proc find-cxx-tests { dir suffix } { + set tests [lsort [glob -nocomplain -directory $dir "*.$suffix" ]] + foreach subdir [lsort [glob -nocomplain -type d -directory $dir *]] { + if { [glob -nocomplain -directory $subdir *.exp] eq "" } { + eval lappend tests [find-cxx-tests $subdir $suffix] + } + } + return $tests +} + +set tests [find-cxx-tests $srcdir/$subdir {C}] + +# Main loop. +g++-dg-runtest $tests "" $DEFAULT_CXXFLAGS + +# C/C++ common tests. +g++-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/*.\[cSi\]]] \ + "" "" + +g++-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cpp/*.\[cS\]]] \ + "" "" + + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/no-body-function.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/no-body-function.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e56e73fcaedea15e944313cff4b6a009a0dcbb4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/no-body-function.cpp @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu++17 -Wno-builtin-declaration-mismatch -O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -S" } */ + +struct S { + int x; + double y; +}; +S f(); + +const auto [x0, y0] = f(); +const auto [x1, y1] = f(); + +static union { +int a; +double b; +}; + +const auto [x2, y2] = f(); diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-1.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ab71abe140f981e4b663a92df41742e8125bba9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-1.cpp @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -fdump-ipa-struct_reorg-details -S" } */ + +struct Foo { int foo; int a; }; +Foo& ignoreSetMutex = *(new Foo); + +struct Goo { int goo; int a; }; + +int main () +{ + Goo* a; + return a->goo = 90; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-2.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72b7db8a9cea780675adea2628cb6101adbd7c69 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-2.cpp @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -fdump-ipa-struct_reorg-details" } */ + +#include + +struct testg { + int b; + float c; +}; + +testg *testgvar; +int main () +{ + testgvar = (testg*) calloc(10, sizeof(testg)); + int b = testgvar->b; + return b; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-3.cpp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..771164a96e7091622d21e06e32e5f40c015fbdcc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg-3.cpp @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fipa-struct-reorg -fdump-ipa-struct_reorg-details" } */ + +#include + +struct testg { + int b; + float c; + double d; + double e; + double f; + double h; + double i; + double j; + int k; +}; + +testg *testgvar; +int main () +{ + testgvar = (testg*) calloc(10, sizeof(testg)); + int b = testgvar->b; + return b; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg.exp new file mode 100644 index 0000000000000000000000000000000000000000..e3ffe138819a340ae6ea0a292bc84a64d4568b0b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/struct/struct-reorg.exp @@ -0,0 +1,26 @@ +# Copyright (C) 2021-2023 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 +# . + +load_lib g++-dg.exp + +# Initialize `dg'. +dg-init + +g++-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cpp]] \ + "" "" + +# All done. +dg-finish \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/tree-ssa/mull64.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/tree-ssa/mull64.C new file mode 100644 index 0000000000000000000000000000000000000000..cad891e62a7fbe0ac848204877eb73b0b4ea68a5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.dg/tree-ssa/mull64.C @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fmerge-mull -Wno-psabi -fdump-tree-forwprop1-details -fdump-tree-forwprop4-details" } */ + +# define BN_BITS4 32 +# define BN_MASK2 (0xffffffffffffffffL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000L) +# define BN_MASK2h1 (0xffffffff80000000L) +# define LBITS(a) ((a)&BN_MASK2l) +# define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l) +# define L2HBITS(a) (((a)<. + +# GCC testsuite that uses the `g++.exp' driver. + +# Exit immediately if this isn't a x86 target. +if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { + return +} + +# Load support procs. +load_lib g++-dg.exp +load_lib clearcap.exp + +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors" +} + +# Initialize `dg'. +dg-init +clearcap-init + +# Main loop. +g++-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] \ + "" $DEFAULT_CXXFLAGS + +# All done. +clearcap-finish +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.target/i386/pr112443.C b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.target/i386/pr112443.C new file mode 100644 index 0000000000000000000000000000000000000000..ebfa9b4a753b711959bf3dd74f58da4dbb9f1bb9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/g++.target/i386/pr112443.C @@ -0,0 +1,108 @@ +/* { dg-do run } */ +/* { dg-require-effective-target avx512bw } */ +/* { dg-require-effective-target avx512vl } */ +/* { dg-options "-O2 -std=c++17 -mavx512bw -mavx512vl" } */ + +#include +#include +#include +#include + +#define AVX512BW +#define AVX512VL + +#include "avx512f-helper.h" + +struct TensorIteratorBase{ + char* in; + char* out; + + void for_each(std::function loop){ + loop(out, in, 32); + } +}; + +class Vectorized { +protected: + __m256i values; + + static inline __m256i invert(const __m256i& v) { + const auto ones = _mm256_set1_epi64x(-1); + return _mm256_xor_si256(ones, v); + } +public: + operator __m256i() const { + return values; + } + + static constexpr int size() { + return 32; + } + + Vectorized() {} + Vectorized(__m256i v) : values(v) {} + Vectorized(uint8_t v) { values = _mm256_set1_epi8(v); } + static Vectorized blendv(const Vectorized& a, const Vectorized& b, + const Vectorized& mask) { + return _mm256_blendv_epi8(a, b, mask); + } + static Vectorized loadu(const void* ptr) { + return _mm256_loadu_si256(reinterpret_cast(ptr)); + } + void store(void* ptr) const { + _mm256_storeu_si256(reinterpret_cast<__m256i*>(ptr), values); + } + + Vectorized operator<(const Vectorized& other) const { + __m256i max = _mm256_max_epu8(values, other); + return invert(_mm256_cmpeq_epi8(max, values)); + } + Vectorized operator-(const Vectorized& b) { + return _mm256_sub_epi8(values, b); + } +}; + +std::ostream& operator<<(std::ostream& stream, const Vectorized& vec) { + uint8_t buf[Vectorized::size()]; + vec.store(buf); + stream << "vec["; + for (int i = 0; i != Vectorized::size(); i++) { + if (i != 0) + stream << ", "; + stream << buf[i]*1; + } + stream << "]"; + return stream; +} + +void run(TensorIteratorBase iter){ + Vectorized zero_vec(0); + Vectorized one_vec(1); + + iter.for_each([=](char* out, char* in, int64_t size) { + for (int64_t i = 0; i <= size - Vectorized::size(); i += Vectorized::size()) { + auto self_vec = Vectorized::loadu(in + i); + auto left = Vectorized::blendv(zero_vec, one_vec, zero_vec < self_vec); + auto right = Vectorized::blendv(zero_vec, one_vec, self_vec < zero_vec); + auto outv = left - right; + outv.store(out + i); + } + }); +} + +void +test_256 (){ + char in[32]; + char out[32]; + for(auto& x: in) x = 1; + run(TensorIteratorBase{in, out}); + Vectorized::loadu (out); + for (int i = 0; i != 32; i++) + if (out[i] != 1) + __builtin_abort (); +} + +void +test_128 () +{ +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.c-torture/execute/execute.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.c-torture/execute/execute.exp new file mode 100644 index 0000000000000000000000000000000000000000..80524ada6def49204d7463cb6dd6b3d124e998ed --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.c-torture/execute/execute.exp @@ -0,0 +1,38 @@ +# Copyright (C) 1991-2022 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 +# . + +# This file was written by Rob Savoye. (rob@cygnus.com) +# Modified and maintained by Jeffrey Wheat (cassidy@cygnus.com) + +# +# These tests come from Torbjorn Granlund (tege@cygnus.com) +# C torture test suite. +# + +# Load support procs. +load_lib gcc-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +set saved-dg-do-what-default ${dg-do-what-default} +set dg-do-what-default "run" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" "-w" +set dg-do-what-default ${saved-dg-do-what-default} + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.c-torture/execute/ifcvt-renaming-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.c-torture/execute/ifcvt-renaming-1.c new file mode 100644 index 0000000000000000000000000000000000000000..65c4d4140dadcc5dffb323117bce160500ce6d5c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.c-torture/execute/ifcvt-renaming-1.c @@ -0,0 +1,35 @@ + +extern void abort(void); + +__attribute__ ((noinline)) +int foo (int x, int y, int z, int a, int b) +{ + if (a < 2) { + if (a == 0) { + if (x - y < 0) + x = x - y + z; + else + x = x - y; + } + else { + if (x + y >= z) + x = x + y - z; + else + x = x + y; + } + } + return x; +} + +int main(void) { + if (foo (5,10,7,0,1) != 2) // x - y + z = -5 + 7 = 2 + abort (); + if (foo (50,10,7,0,1) != 40) // x - y = 40 + abort (); + if (foo (5,10,7,1,1) != 8) // x + y - z = 5 + 10 - 7 = 8 + abort (); + if (foo (5,10,70,1,1) != 15) // x + y = 15 + abort (); + return 0; +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-cmlt.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-cmlt.c new file mode 100755 index 0000000000000000000000000000000000000000..b4c9a37ffe7795bba115f7e78e4d9a4e4f06f681 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-cmlt.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -mcmlt-arith" } */ + +/* The test checks usage of cmlt insns for arithmetic/logic calculations + * in foo (). It's inspired by sources of x264 codec. */ + +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; + +void foo( uint32_t *a, uint32_t *b) +{ + for (unsigned i = 0; i < 4; i++) + { + uint32_t s = ((a[i]>>((8 * sizeof(uint16_t))-1)) + &(((uint32_t)1<<(8 * sizeof(uint16_t)))+1))*((uint16_t)-1); + b[i] = (a[i]+s)^s; + } +} + +/* { dg-final { scan-assembler-times {cmlt\t} 1 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin-1.c new file mode 100644 index 0000000000000000000000000000000000000000..859ff7df8cb64bd4bfa635894325712797399472 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -fconvert-minmax" } */ + +#include + +__attribute__((noinline)) +void test (int32_t *restrict a, int32_t *restrict x) +{ + for (int i = 0; i < 4; i++) + a[i] = ((((-x[i]) >> 31) ^ x[i]) + & (-((int32_t)((x[i] & (~((1 << 8)-1))) == 0)))) ^ ((-x[i]) >> 31); +} + +/* { dg-final { scan-assembler-not {smax\t} } } */ +/* { dg-final { scan-assembler-not {smin\t} } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin-2.c new file mode 100644 index 0000000000000000000000000000000000000000..63d4d85b3f3983ab20741b5e9abe98f5c0dee0b4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -fconvert-minmax" } */ + +#include + +__attribute__((noinline)) +void test (int8_t *restrict a, int32_t *restrict x) +{ + for (int i = 0; i < 8; i++) + a[i] = ((x[i] & ~((1 << 9)-1)) ? (-x[i])>>31 & ((1 << 9)-1) : x[i]); +} + +/* { dg-final { scan-assembler-times {smax\t} 4 } } */ +/* { dg-final { scan-assembler-times {smin\t} 4 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin.c new file mode 100755 index 0000000000000000000000000000000000000000..5c0c9cc4917a526295d477084bb89c9c12132e3a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/combine-maxmin.c @@ -0,0 +1,55 @@ +/* { dg-do compile { target aarch64-*-* } } */ +/* { dg-options "-O3 -fconvert-minmax" } */ + +/* The test checks usage of smax/smin insns for clip evaluation and + * uzp1/uzp2 insns for vector element narrowing. It's inspired by + * sources of x264 codec. */ + +typedef unsigned char uint8_t; +typedef long int intptr_t; +typedef signed short int int16_t; + +static __attribute__((always_inline)) inline uint8_t clip (int x ) +{ + return ( (x & ~((1 << 8)-1)) ? (-x)>>31 & ((1 << 8)-1) : x ); +} + +void hf (uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, uint8_t *src, + intptr_t stride, int width, int height, int16_t *buf) +{ + const int pad = (8 > 9) ? (-10 * ((1 << 8)-1)) : 0; + for( int y = 0; y < height; y++ ) { + /* This loop is not being vectorized now. */ + for( int x = -2; x < width+3; x++ ) { + int v = ((src)[x-2*stride] + (src)[x+3*stride] - 5*((src)[x-stride] + + (src)[x+2*stride]) + 20*((src)[x] + (src)[x+stride])); + dstv[x] = clip ( (v + 16) >> 5 ); + buf[x+2] = v + pad; + } + + /* Produces two versions of the code: 3xUZP1/2xMAX/2xMIN + 1xUZP1/1xMAX/1xMIN. */ + for( int x = 0; x < width; x++ ) + dstc[x] = clip ((((buf+2)[x-2*1] + (buf+2)[x+3*1] - 5*((buf+2)[x-1] + + (buf+2)[x+2*1]) + 20*((buf+2)[x] + (buf+2)[x+1])) + - 32*pad + 512) >> 10); + + /* Priduces two versions of the code: 1xUZP1/2xMAX/2xMIN + 0xUZP1/1xMAX/1xMIN. */ + for( int x = 0; x < width; x++ ) + dsth[x] = clip ((((src)[x-2*1] + (src)[x+3*1] - 5*((src)[x-1] + + (src)[x+2*1]) + 20*((src)[x] + (src)[x+1])) + + 16) >> 5); + + dsth += stride; + dstv += stride; + dstc += stride; + src += stride; + } +} + +/* Max is performed on 0 from signed values, match smax exactly. */ +/* { dg-final { scan-assembler-times {smax\t} 6 } } */ +/* Min is performed on signed val>0 and a mask, min sign doesn't matter. */ +/* { dg-final { scan-assembler-times {[us]min\t} 6 } } */ +/* All of the vectorized patterns are expected to be matched. */ +/* { dg-final { scan-assembler-not {cmtst\t} } } */ +/* { dg-final { scan-assembler-times {uzp1\t} 2 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..9c8b0eac38ce748aa95f9b11c215e14b1ba88309 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/dg.exp @@ -0,0 +1,40 @@ +# Copyright (C) 1997-2022 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cSi\]]] \ + "" $DEFAULT_CFLAGS + +# C/C++ common tests. +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/*.\[cSi\]]] \ + " -Wc++-compat " "" + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/double_sized_mul-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/double_sized_mul-1.c new file mode 100644 index 0000000000000000000000000000000000000000..d32a25223c7267bdcf5f986216a15f1463796d77 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/double_sized_mul-1.c @@ -0,0 +1,141 @@ +/* { dg-do compile } */ +/* fif-conversion-gimple and fuaddsub-overflow-match-all are required for + proper overflow detection in some cases. */ +/* { dg-options "-O2 -fif-conversion-gimple -march=armv8.2-a -fuaddsub-overflow-match-all -fdump-tree-widening_mul-stats" } */ +#include + +typedef unsigned __int128 uint128_t; + +uint16_t mul16 (uint8_t a, uint8_t b) +{ + uint8_t a_lo = a & 0xF; + uint8_t b_lo = b & 0xF; + uint8_t a_hi = a >> 4; + uint8_t b_hi = b >> 4; + uint8_t lolo = a_lo * b_lo; + uint8_t lohi = a_lo * b_hi; + uint8_t hilo = a_hi * b_lo; + uint8_t hihi = a_hi * b_hi; + uint8_t middle = hilo + lohi; + uint8_t middle_hi = middle >> 4; + uint8_t middle_lo = middle << 4; + uint8_t res_lo = lolo + middle_lo; + uint8_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x10 : 0); + uint16_t res = ((uint16_t) res_hi) << 8; + res += res_lo; + return res; +} + +uint32_t mul32 (uint16_t a, uint16_t b) +{ + uint16_t a_lo = a & 0xFF; + uint16_t b_lo = b & 0xFF; + uint16_t a_hi = a >> 8; + uint16_t b_hi = b >> 8; + uint16_t lolo = a_lo * b_lo; + uint16_t lohi = a_lo * b_hi; + uint16_t hilo = a_hi * b_lo; + uint16_t hihi = a_hi * b_hi; + uint16_t middle = hilo + lohi; + uint16_t middle_hi = middle >> 8; + uint16_t middle_lo = middle << 8; + uint16_t res_lo = lolo + middle_lo; + uint16_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x100 : 0); + uint32_t res = ((uint32_t) res_hi) << 16; + res += res_lo; + return res; +} + +uint64_t mul64 (uint32_t a, uint32_t b) +{ + uint32_t a_lo = a & 0xFFFF; + uint32_t b_lo = b & 0xFFFF; + uint32_t a_hi = a >> 16; + uint32_t b_hi = b >> 16; + uint32_t lolo = a_lo * b_lo; + uint32_t lohi = a_lo * b_hi; + uint32_t hilo = a_hi * b_lo; + uint32_t hihi = a_hi * b_hi; + uint32_t middle = hilo + lohi; + uint32_t middle_hi = middle >> 16; + uint32_t middle_lo = middle << 16; + uint32_t res_lo = lolo + middle_lo; + uint32_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x10000 : 0); + uint64_t res = ((uint64_t) res_hi) << 32; + res += res_lo; + return res; +} + +uint128_t mul128 (uint64_t a, uint64_t b) +{ + uint64_t a_lo = a & 0xFFFFFFFF; + uint64_t b_lo = b & 0xFFFFFFFF; + uint64_t a_hi = a >> 32; + uint64_t b_hi = b >> 32; + uint64_t lolo = a_lo * b_lo; + uint64_t lohi = a_lo * b_hi; + uint64_t hilo = a_hi * b_lo; + uint64_t hihi = a_hi * b_hi; + uint64_t middle = hilo + lohi; + uint64_t middle_hi = middle >> 32; + uint64_t middle_lo = middle << 32; + uint64_t res_lo = lolo + middle_lo; + uint64_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x100000000 : 0); + uint128_t res = ((uint128_t) res_hi) << 64; + res += res_lo; + return res; +} + +uint64_t mul64_perm (uint32_t a, uint32_t b) +{ + uint32_t a_lo = a & 0xFFFF; + uint32_t b_lo = b & 0xFFFF; + uint32_t a_hi = a >> 16; + uint32_t b_hi = b >> 16; + uint32_t lolo = a_lo * b_lo; + uint32_t lohi = a_lo * b_hi; + uint32_t hilo = a_hi * b_lo; + uint32_t hihi = a_hi * b_hi; + uint32_t middle = hilo + lohi; + uint32_t middle_hi = middle >> 16; + uint32_t middle_lo = middle << 16; + uint32_t res_lo = lolo + middle_lo; + uint32_t res_hi = hihi + middle_hi; + res_hi = res_lo < middle_lo ? res_hi + 1 : res_hi; + res_hi = middle < hilo ? res_hi + 0x10000 : res_hi; + uint64_t res = ((uint64_t) res_hi) << 32; + res += res_lo; + return res; +} + +uint128_t mul128_perm (uint64_t a, uint64_t b) +{ + uint64_t a_lo = a & 0xFFFFFFFF; + uint64_t b_lo = b & 0xFFFFFFFF; + uint64_t a_hi = a >> 32; + uint64_t b_hi = b >> 32; + uint64_t lolo = a_lo * b_lo; + uint64_t lohi = a_lo * b_hi; + uint64_t hilo = a_hi * b_lo; + uint64_t hihi = a_hi * b_hi; + uint64_t middle = hilo + lohi; + uint64_t middle_hi = middle >> 32; + uint64_t middle_lo = middle << 32; + uint64_t res_lo = lolo + middle_lo; + uint64_t res_hi = hihi + middle_hi; + res_hi = res_lo < middle_lo ? res_hi + 1 : res_hi; + res_hi = middle < hilo ? res_hi + 0x100000000 : res_hi; + uint128_t res = ((uint128_t) res_hi) << 64; + res += res_lo; + return res; +} + +/* { dg-final { scan-tree-dump-times "double sized mul optimized: 1" 6 "widening_mul" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/double_sized_mul-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/double_sized_mul-2.c new file mode 100644 index 0000000000000000000000000000000000000000..ff35902b77f9f4b8c590c052b30a7838a0d73055 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/double_sized_mul-2.c @@ -0,0 +1,62 @@ +/* { dg-do compile } */ +/* fif-conversion-gimple is required for proper overflow detection + in some cases. */ +/* { dg-options "-O2 -fif-conversion-gimple -march=armv8.2-a -fuaddsub-overflow-match-all -fdump-tree-widening_mul-stats" } */ +#include + +typedef unsigned __int128 uint128_t; +typedef struct uint256_t +{ + uint128_t lo; + uint128_t hi; +} uint256_t; + +uint64_t mul64_double_use (uint32_t a, uint32_t b) +{ + uint32_t a_lo = a & 0xFFFF; + uint32_t b_lo = b & 0xFFFF; + uint32_t a_hi = a >> 16; + uint32_t b_hi = b >> 16; + uint32_t lolo = a_lo * b_lo; + uint32_t lohi = a_lo * b_hi; + uint32_t hilo = a_hi * b_lo; + uint32_t hihi = a_hi * b_hi; + uint32_t middle = hilo + lohi; + uint32_t middle_hi = middle >> 16; + uint32_t middle_lo = middle << 16; + uint32_t res_lo = lolo + middle_lo; + uint32_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + res_hi += (middle < hilo ? 0x10000 : 0); + uint64_t res = ((uint64_t) res_hi) << 32; + res += res_lo; + return res + lolo; +} + +uint256_t mul256 (uint128_t a, uint128_t b) +{ + uint128_t a_lo = a & 0xFFFFFFFFFFFFFFFF; + uint128_t b_lo = b & 0xFFFFFFFFFFFFFFFF; + uint128_t a_hi = a >> 64; + uint128_t b_hi = b >> 64; + uint128_t lolo = a_lo * b_lo; + uint128_t lohi = a_lo * b_hi; + uint128_t hilo = a_hi * b_lo; + uint128_t hihi = a_hi * b_hi; + uint128_t middle = hilo + lohi; + uint128_t middle_hi = middle >> 64; + uint128_t middle_lo = middle << 64; + uint128_t res_lo = lolo + middle_lo; + uint128_t res_hi = hihi + middle_hi; + res_hi += (res_lo < middle_lo ? 1 : 0); + /* Constant is to big warning WA */ + uint128_t overflow_tmp = (middle < hilo ? 1 : 0); + overflow_tmp <<= 64; + res_hi += overflow_tmp; + uint256_t res; + res.lo = res_lo; + res.hi = res_hi; + return res; +} + +/* { dg-final { scan-tree-dump-not "double sized mul optimized" "widening_mul" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp1.c new file mode 100644 index 0000000000000000000000000000000000000000..c2117f7385b322ae19226475205f6e813e68eeee --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp1.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp1.c.077i.icp" } */ + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; +} my_str; + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + my_str.myf2 = &bar; + func1 = &foo; + return foo(a); +} + +int main() { + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(4\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(2\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by: bar \\(3\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 3 candidates for indirect call promotion, 3 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp2.c new file mode 100644 index 0000000000000000000000000000000000000000..03d31d407767682f5e8c6515a6e1edadcd683c2f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp2.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp2.c.077i.icp" } */ + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; +} my_str; + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + my_str.myf2 = dummy ? (ftype2) &foo : &bar; + func1 = (ftype1) &bar; + return foo(a); +} + +int main() { + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump-not "The call is substituted by.*" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 3 candidates for indirect call promotion, 0 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp3.c new file mode 100644 index 0000000000000000000000000000000000000000..2a7d1e6f5f807459f99393f53ef3e2dca27d377a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp3.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp3.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef ftype1 (*ftype3) (ftype2); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} my_str; + +ftype1 boo(ftype2 a) { + printf ("Call boo\n"); + return (ftype1) a; +} + +int foo(int a) { + printf ("Call foo\n"); + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + printf("Call bar\n"); + my_str.myf2 = (ftype2) my_str.myf3((ftype2) foo); + func1 = &foo; + return foo(a); +} + +int main() { + my_str.myf3 = &boo; + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(4\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by:.*= foo \\(2\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "The call is substituted by: foo \\(3\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 4 candidates for indirect call promotion, 3 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp4.c new file mode 100644 index 0000000000000000000000000000000000000000..e3e1d5116b44a26419abfb5f94eb21abdee87ebf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp4.c @@ -0,0 +1,55 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp4.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef ftype1 (*ftype3) (ftype2); + +ftype1 func1; +ftype1 boo(ftype2 a); +int foo(int a); +float bar(int a); + +typedef struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} T; + +T my_str = {0, (int*) &dummy, (ftype1) &boo, (ftype2) &foo, (ftype3) &bar}; + +ftype1 boo(ftype2 a) { + printf ("Call boo\n"); + return (ftype1) a; +} + +int foo(int a) { + printf ("Call foo\n"); + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + printf("Call bar\n"); + my_str.myf2 = (ftype2) my_str.myf3((ftype2) foo); + func1 = &foo; + return foo(a); +} + +int main() { + my_str.myf3 = &boo; + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump-not "The call is substituted by.*" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 4 candidates for indirect call promotion, 0 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp5.c new file mode 100644 index 0000000000000000000000000000000000000000..c7709243cceab51f3c01f93a2a84a2f36cc6723f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp5.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp5.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef ftype1 (*ftype3) (ftype2); + +ftype1 func1; +ftype1 boo(ftype2 a); +int foo(int a); +float bar(int a); + +typedef struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} T; + +T my_str; + +typedef struct { + int a; + int* b; + ftype3 myf1; + ftype2 myf2; + ftype1 myf3; +} T1; + +T1 my1 = {0, &dummy, boo, &bar, &foo}; + +ftype1 boo(ftype2 a) { + printf("Call boo\n"); + return (ftype1) a; +} + +int foo(int a) { + printf("Call foo\n"); + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + printf("Call bar\n"); + my_str.myf2 = (ftype2) my_str.myf3((ftype2) foo); + func1 = &foo; + return foo(a); +} + +int main() { + my_str = *(T*)&my1; + my_str.myf3 = &boo; + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)) != 8; +} + +/* { dg-final { scan-ipa-dump-not "The call is substituted by.*" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 4 candidates for indirect call promotion, 0 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp6.c new file mode 100644 index 0000000000000000000000000000000000000000..5a9f15045935313bcf3d3ef77afac45dc1b72313 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp6.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp6.c.077i.icp -Wno-int-conversion -Wno-incompatible-pointer-types" } */ +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); +typedef int (*ftype3)(); +typedef int (*ftype4)(int a, int b); + +ftype1 func1; +ftype4 func2; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; + ftype3 myf3; +} my_str; + +int foo3(float a) { + return dummy; +} + +int foo4(int a, int b) { + return a*b; +} + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +int foo2(float a) { + func1 = (ftype1) &foo; + func2 = &foo4; + return dummy + foo3 (a); +} + +float bar2(int a) { + my_str.myf2 = (ftype2)(0x864213); + func2 = 0x65378; + return foo(a); +} + +float bar(int a) { + my_str.myf3 = &foo2; + my_str.myf2 = &bar; + func1 = (ftype1) &dummy; + func2 = (ftype4) &bar2; + return foo(a); +} + +int main() { + bar(1); + bar2(1); + bar(0); + my_str.myf2(3); + ((ftype1) my_str.myf3)(0.0); + int sum = func1(4); + return (sum + my_str.myf1(2) + func2(5, 6)) != 38; +} +/* { dg-final { scan-ipa-dump "The call is substituted by.*foo2 \\(0\\);" "icp" } } */ +/* { dg-final { scan-ipa-dump "STATS: 5 candidates for indirect call promotion, 1 substituted, 0 speculatively promoted, 0 cold" "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp7.c new file mode 100644 index 0000000000000000000000000000000000000000..fa52197f48fa782a3a519d3038dd16f232e6ad5c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/icp7.c @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -flto -ficp -fdump-ipa-icp=./icp7.c.077i.icp" } */ + +#include + +int dummy = 0; + +typedef int (*ftype1)(int a); +typedef float (*ftype2)(int a); + +ftype1 func1; + +struct { + int a; + int* b; + ftype1 myf1; + ftype2 myf2; +} my_str; + +int boo(int a, ...) { + va_list ap; + va_start(ap, a); + if (a == 0) + dummy += va_arg(ap, int); + va_end(ap); + return dummy; +} + +int foo(int a) { + my_str.myf1 = func1; + if (a % 2 == 0) + dummy += dummy % (dummy - a); + return a + 1; +} + +float bar(int a) { + my_str.myf2 = &bar; + func1 = (ftype1) &boo; + return foo(a); +} + +int main() { + bar(1); + my_str.myf2(3); + return (my_str.myf1(2) + func1(4)); +} + +/* { dg-final { scan-ipa-dump "Address taken function with varargs is found. Skip the optimization." "icp" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ifcvt-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ifcvt-6.c new file mode 100644 index 0000000000000000000000000000000000000000..be9a67b3fcf15dd94a18059ca01cf5b120039d3a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ifcvt-6.c @@ -0,0 +1,27 @@ +/* { dg-do compile { target { aarch64*-*-* } } } */ +/* { dg-options "-fdump-rtl-ce1 -O2 --param max-rtl-if-conversion-unpredictable-cost=100 --param max-rtl-if-conversion-predictable-cost=100 --param=ifcvt-allow-register-renaming=2 -fifcvt-allow-complicated-cmps" } */ + +typedef unsigned int uint16_t; + +uint16_t +foo (uint16_t x, uint16_t y, uint16_t z, uint16_t a, + uint16_t b, uint16_t c, uint16_t d) { + int i = 1; + int j = 1; + if (a > b) { + j = x; + if (b > c) + i = y; + else + i = z; + } + else { + j = y; + if (c > d) + i = z; + } + return i * j; +} + +/* { dg-final { scan-rtl-dump "7 true changes made" "ce1" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ifcvt-gimple.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ifcvt-gimple.c new file mode 100644 index 0000000000000000000000000000000000000000..0f7c87e5c5bed4c0ac81416a944e7c187391c90f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ifcvt-gimple.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fif-conversion-gimple -fdump-tree-optimized" } */ + +int test_int (int optimizable_int) { + if (optimizable_int > 5) + ++optimizable_int; + return optimizable_int; +} + +int test_int_pow2 (int optimizable_int_pow2) { + if (optimizable_int_pow2 <= 4) + optimizable_int_pow2 += 1024; + return optimizable_int_pow2; +} + +int test_int_non_pow2 (int not_optimizable_int_non_pow2) { + if (not_optimizable_int_non_pow2 == 1) + not_optimizable_int_non_pow2 += 513; + return not_optimizable_int_non_pow2; +} + +float test_float (float not_optimizable_float) { + if (not_optimizable_float > 5) + not_optimizable_float += 1; + return not_optimizable_float; +} + +/* Expecting if-else block in test_float and test_int_non_pow2 only. */ +/* { dg-final { scan-tree-dump-not "if \\(optimizable" "optimized" } } */ +/* { dg-final { scan-tree-dump "if \\(not_optimizable_int_non_pow2" "optimized" } } */ +/* { dg-final { scan-tree-dump "if \\(not_optimizable_float" "optimized" } } */ +/* { dg-final { scan-tree-dump-times "if " 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "else" 2 "optimized" } } */ + +/* Expecting shifted result only for optimizable_int_pow2. */ +/* { dg-final { scan-tree-dump-times " << " 1 "optimized" } } */ +/* { dg-final { scan-tree-dump " << 10;" "optimized" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/inlinehint-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/inlinehint-6.c new file mode 100644 index 0000000000000000000000000000000000000000..1f3be641c6d26c6f831b879ebb0224b72e0a0cd1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/inlinehint-6.c @@ -0,0 +1,47 @@ +/* { dg-options "-O3 -c -fdump-ipa-inline-details -fno-early-inlining -fno-ipa-cp" } */ +/* { dg-add-options bind_pic_locally } */ + +#define size_t long long int + +struct A +{ + size_t f1, f2, f3, f4; +}; +struct C +{ + struct A a; + size_t b; +}; +struct C x; + +__attribute__((hot)) struct C callee (struct A *a, struct C *c) +{ + c->a=(*a); + + if((c->b + 7) & 17) + { + c->a.f1 = c->a.f2 + c->a.f1; + c->a.f2 = c->a.f3 - c->a.f2; + c->a.f3 = c->a.f2 + c->a.f3; + c->a.f4 = c->a.f2 - c->a.f4; + c->b = c->a.f2; + + } + return *c; +} + +__attribute__((hot)) struct C caller (size_t d, size_t e, size_t f, size_t g, struct C *c) +{ + struct A a; + a.f1 = 1 + d; + a.f2 = e; + a.f3 = 12 + f; + a.f4 = 68 + g; + if (c->b > 0) + return callee (&a, c); + else + return *c; +} + +/* { dg-final { scan-ipa-dump "known_hot" "inline" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/ipa-prefetch-xz.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/ipa-prefetch-xz.c new file mode 100644 index 0000000000000000000000000000000000000000..bd4fb2bdc37924ab7b645a5c7ff361ae970b3955 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/ipa-prefetch-xz.c @@ -0,0 +1,1843 @@ +/* { dg-do link } */ +/* { dg-options "-O3 -fipa-ic -fipa-prefetch -flto -flto-partition=one -fdump-ipa-ipa_prefetch -fdump-ipa-icp" } */ +/* { dg-require-effective-target lto } */ + +/* Based on opensource xz code. */ + +#include +#include + +typedef long int ptrdiff_t; +typedef long unsigned int size_t; +typedef unsigned int wchar_t; + +typedef unsigned char __u_char; +typedef unsigned short int __u_short; +typedef unsigned int __u_int; +typedef unsigned long int __u_long; + +typedef signed char __int8_t; +typedef unsigned char __uint8_t; +typedef signed short int __int16_t; +typedef unsigned short int __uint16_t; +typedef signed int __int32_t; +typedef unsigned int __uint32_t; + +typedef signed long int __int64_t; +typedef unsigned long int __uint64_t; + +typedef __int8_t __int_least8_t; +typedef __uint8_t __uint_least8_t; +typedef __int16_t __int_least16_t; +typedef __uint16_t __uint_least16_t; +typedef __int32_t __int_least32_t; +typedef __uint32_t __uint_least32_t; +typedef __int64_t __int_least64_t; +typedef __uint64_t __uint_least64_t; + +typedef __int8_t int8_t; +typedef __int16_t int16_t; +typedef __int32_t int32_t; +typedef __int64_t int64_t; + +typedef __uint8_t uint8_t; +typedef __uint16_t uint16_t; +typedef __uint32_t uint32_t; +typedef __uint64_t uint64_t; + +typedef long int intptr_t; +typedef unsigned long int uintptr_t; + +static inline uint16_t +read16ne(const uint8_t *buf) +{ + uint16_t num; + memcpy(&num, buf, sizeof(num)); + return num; +} + +static inline uint32_t +read32ne(const uint8_t *buf) +{ + uint32_t num; + memcpy(&num, buf, sizeof(num)); + return num; +} + +static inline uint16_t +aligned_read16ne(const uint8_t *buf) +{ + uint16_t num; + memcpy(&num, __builtin_assume_aligned(buf, sizeof(num)), sizeof(num)); + return num; +} + + +static inline uint32_t +aligned_read32ne(const uint8_t *buf) +{ + uint32_t num; + memcpy(&num, __builtin_assume_aligned(buf, sizeof(num)), sizeof(num)); + return num; +} + +static inline uint64_t +aligned_read64ne(const uint8_t *buf) +{ + uint64_t num; + memcpy(&num, __builtin_assume_aligned(buf, sizeof(num)), sizeof(num)); + return num; +} + +typedef unsigned char lzma_bool; + +typedef enum { + LZMA_RESERVED_ENUM = 0 +} lzma_reserved_enum; + +typedef enum { + LZMA_OK = 0, + LZMA_STREAM_END = 1, + LZMA_NO_CHECK = 2, + LZMA_UNSUPPORTED_CHECK = 3, + LZMA_GET_CHECK = 4, + LZMA_MEM_ERROR = 5, + LZMA_MEMLIMIT_ERROR = 6, + LZMA_FORMAT_ERROR = 7, + LZMA_OPTIONS_ERROR = 8, + LZMA_DATA_ERROR = 9, + LZMA_BUF_ERROR = 10, + LZMA_PROG_ERROR = 11, +} lzma_ret; + +typedef enum { + LZMA_RUN = 0, + LZMA_SYNC_FLUSH = 1, + LZMA_FULL_FLUSH = 2, + LZMA_FULL_BARRIER = 4, + LZMA_FINISH = 3 +} lzma_action; + +typedef struct { + void *( *alloc)(void *opaque, size_t nmemb, size_t size); + + void ( *free)(void *opaque, void *ptr); + + void *opaque; +} lzma_allocator; + +typedef uint64_t lzma_vli; + +typedef enum { + LZMA_CHECK_NONE = 0, + LZMA_CHECK_CRC32 = 1, + LZMA_CHECK_CRC64 = 4, + LZMA_CHECK_SHA256 = 10 +} lzma_check; + +typedef struct { + lzma_vli id; + void *options; +} lzma_filter; + +typedef enum { + LZMA_MF_HC3 = 0x03, + LZMA_MF_HC4 = 0x04, + LZMA_MF_BT2 = 0x12, + LZMA_MF_BT3 = 0x13, + LZMA_MF_BT4 = 0x14 +} lzma_match_finder; + +typedef struct lzma_next_coder_s lzma_next_coder; + +typedef struct lzma_filter_info_s lzma_filter_info; + +typedef lzma_ret (*lzma_init_function)( + lzma_next_coder *next, const lzma_allocator *allocator, + const lzma_filter_info *filters); + +typedef lzma_ret (*lzma_code_function)( + void *coder, const lzma_allocator *allocator, + const uint8_t *restrict in, size_t *restrict in_pos, + size_t in_size, uint8_t *restrict out, + size_t *restrict out_pos, size_t out_size, + lzma_action action); + +typedef void (*lzma_end_function)( + void *coder, const lzma_allocator *allocator); + +struct lzma_filter_info_s { + lzma_vli id; + lzma_init_function init; + void *options; +}; + +struct lzma_next_coder_s { + void *coder; + lzma_vli id; + uintptr_t init; + + lzma_code_function code; + lzma_end_function end; + void (*get_progress)(void *coder, + uint64_t *progress_in, uint64_t *progress_out); + + lzma_check (*get_check)(const void *coder); + lzma_ret (*memconfig)(void *coder, uint64_t *memusage, + uint64_t *old_memlimit, uint64_t new_memlimit); + lzma_ret (*update)(void *coder, const lzma_allocator *allocator, + const lzma_filter *filters, const lzma_filter *reversed_filters); +}; + +typedef struct { + uint32_t len; + uint32_t dist; +} lzma_match; + +typedef struct lzma_mf_s lzma_mf; +struct lzma_mf_s { + uint8_t *buffer; + uint32_t size; + uint32_t keep_size_before; + uint32_t keep_size_after; + uint32_t offset; + uint32_t read_pos; + uint32_t read_ahead; + uint32_t read_limit; + uint32_t write_pos; + uint32_t pending; + uint32_t (*find)(lzma_mf *mf, lzma_match *matches); + void (*skip)(lzma_mf *mf, uint32_t num); + uint32_t *hash; + uint32_t *son; + uint32_t cyclic_pos; + uint32_t cyclic_size; + uint32_t hash_mask; + uint32_t depth; + uint32_t nice_len; + uint32_t match_len_max; + lzma_action action; + uint32_t hash_count; + uint32_t sons_count; +}; + +typedef struct { + size_t before_size; + size_t dict_size; + size_t after_size; + size_t match_len_max; + size_t nice_len; + lzma_match_finder match_finder; + uint32_t depth; + const uint8_t *preset_dict; + uint32_t preset_dict_size; +} lzma_lz_options; + +typedef struct { + void *coder; + lzma_ret (*code)(void *coder, + lzma_mf *restrict mf, uint8_t *restrict out, + size_t *restrict out_pos, size_t out_size); + void (*end)(void *coder, const lzma_allocator *allocator); + lzma_ret (*options_update)(void *coder, const lzma_filter *filter); +} lzma_lz_encoder; + +static inline const uint8_t * +mf_ptr(const lzma_mf *mf) +{ + return mf->buffer + mf->read_pos; +} + +static inline uint32_t +mf_avail(const lzma_mf *mf) +{ + return mf->write_pos - mf->read_pos; +} + +typedef struct { + uint32_t state[8]; + uint64_t size; +} lzma_sha256_state; + +typedef struct { + union { + uint8_t u8[64]; + uint32_t u32[16]; + uint64_t u64[8]; + } buffer; + union { + uint32_t crc32; + uint64_t crc64; + lzma_sha256_state sha256; + } state; +} lzma_check_state; + +// The table is constantly initialized in the original code. +// Skip it in the test. +const uint32_t lzma_crc32_table[8][256]; + +static inline uint32_t __attribute__((__always_inline__)) +lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, + uint32_t len, uint32_t limit) +{ + while (len < limit) { + uint32_t x = read32ne(buf1 + len) - read32ne(buf2 + len); + if (x != 0) { + if ((x & 0xFFFF) == 0) { + len += 2; + x >>= 16; + } + + if ((x & 0xFF) == 0) + ++len; + + return ((len) < (limit) ? (len) : (limit)); + } + + len += 4; + } + + return limit; +} + +extern uint32_t +lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches) +{ + const uint32_t count = mf->find(mf, matches); + uint32_t len_best = 0; + + if (count > 0) { + len_best = matches[count - 1].len; + if (len_best == mf->nice_len) { + uint32_t limit = mf_avail(mf) + 1; + if (limit > mf->match_len_max) + limit = mf->match_len_max; + const uint8_t *p1 = mf_ptr(mf) - 1; + const uint8_t *p2 = p1 - matches[count - 1].dist - 1; + len_best = lzma_memcmplen(p1, p2, len_best, limit); + } + } + + *count_ptr = count; + ++mf->read_ahead; + + return len_best; +} + +static void +normalize(lzma_mf *mf) +{ + const uint32_t subvalue = ((4294967295U) - mf->cyclic_size); + + for (uint32_t i = 0; i < mf->hash_count; ++i) { + if (mf->hash[i] <= subvalue) + mf->hash[i] = 0; + else + mf->hash[i] -= subvalue; + } + + for (uint32_t i = 0; i < mf->sons_count; ++i) { + if (mf->son[i] <= subvalue) + mf->son[i] = 0; + else + mf->son[i] -= subvalue; + } + + mf->offset -= subvalue; + return; +} + +static void +move_pos(lzma_mf *mf) +{ + if (++mf->cyclic_pos == mf->cyclic_size) + mf->cyclic_pos = 0; + ++mf->read_pos; + if (__builtin_expect(mf->read_pos + mf->offset == (4294967295U), 0 )) + normalize(mf); +} + +static void +move_pending(lzma_mf *mf) +{ + ++mf->read_pos; + ++mf->pending; +} + +static lzma_match * +hc_find_func( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size, + lzma_match *matches, + uint32_t len_best) +{ + son[cyclic_pos] = cur_match; + + while (1) { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) + return matches; + + const uint8_t *const pb = cur - delta; + cur_match = son[cyclic_pos - delta + + (delta > cyclic_pos ? cyclic_size : 0)]; + + if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) { + uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit); + + if (len_best < len) { + len_best = len; + matches->len = len; + matches->dist = delta - 1; + ++matches; + + if (len == len_limit) + return matches; + } + } + } +} + +extern uint32_t +lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (3)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t cur_match = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + uint32_t len_best = 2; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = lzma_memcmplen(cur - delta2, cur, len_best, len_limit); + + matches[0].len = len_best; + matches[0].dist = delta2 - 1; + matches_count = 1; + + if (len_best == len_limit) { + mf->son[mf->cyclic_pos] = cur_match; + move_pos(mf); + return 1; + } + } + + matches_count = hc_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount) +{ + do { + if (mf_avail(mf) < 3) { + move_pending(mf); + continue; + } + + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t cur_match + = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + do { mf->son[mf->cyclic_pos] = cur_match; move_pos(mf); } while (0); + + } while (--amount != 0); +} + +extern uint32_t +lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (4)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) + & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t delta3 + = pos - mf->hash[((1U << 10)) + hash_3_value]; + const uint32_t cur_match = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value ] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + uint32_t len_best = 1; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = 2; + matches[0].len = 2; + matches[0].dist = delta2 - 1; + matches_count = 1; + } + + if (delta2 != delta3 && delta3 < mf->cyclic_size + && *(cur - delta3) == *cur) { + len_best = 3; + matches[matches_count++].dist = delta3 - 1; + delta2 = delta3; + } + + if (matches_count != 0) { + len_best = lzma_memcmplen(cur - delta2, cur, + len_best, len_limit); + + matches[matches_count - 1].len = len_best; + + if (len_best == len_limit) { + mf->son[mf->cyclic_pos] = cur_match; move_pos(mf); + return matches_count; + } + } + + if (len_best < 3) + len_best = 3; + + matches_count = hc_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount) +{ + do { + if (mf_avail(mf) < 4) { + move_pending(mf); + continue; + } + + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + + const uint32_t cur_match + = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + mf->son[mf->cyclic_pos] = cur_match; + move_pos(mf); + } while (--amount != 0); +} + +static lzma_match * +bt_find_func( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size, + lzma_match *matches, + uint32_t len_best) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (1) { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) { + *ptr0 = 0; + *ptr1 = 0; + return matches; + } + + uint32_t *const pair = son + ((cyclic_pos - delta + + (delta > cyclic_pos ? cyclic_size : 0)) + << 1); + + const uint8_t *const pb = cur - delta; + uint32_t len = ((len0) < (len1) ? (len0) : (len1)); + + if (pb[len] == cur[len]) { + len = lzma_memcmplen(pb, cur, len + 1, len_limit); + + if (len_best < len) { + len_best = len; + matches->len = len; + matches->dist = delta - 1; + ++matches; + + if (len == len_limit) { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return matches; + } + } + } + + if (pb[len] < cur[len]) { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } else { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} + + +static void +bt_skip_func( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (1) { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) { + *ptr0 = 0; + *ptr1 = 0; + return; + } + + uint32_t *pair = son + ((cyclic_pos - delta + + (delta > cyclic_pos ? cyclic_size : 0)) + << 1); + const uint8_t *pb = cur - delta; + uint32_t len = ((len0) < (len1) ? (len0) : (len1)); + + if (pb[len] == cur[len]) { + len = lzma_memcmplen(pb, cur, len + 1, len_limit); + + if (len == len_limit) { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + + if (pb[len] < cur[len]) { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } else { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} + +extern uint32_t +lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (2) || (mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + const uint32_t hash_value = read16ne(cur); + const uint32_t cur_match = mf->hash[hash_value]; + mf->hash[hash_value] = pos; + + matches_count = bt_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, 1) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount) +{ + do { + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (2) || (mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + continue; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t hash_value = read16ne(cur); + const uint32_t cur_match = mf->hash[hash_value]; + mf->hash[hash_value] = pos; + + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + } while (--amount != 0); +} + +extern uint32_t +lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (3) || (1 && mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + return 0; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t cur_match = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + uint32_t len_best = 2; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = lzma_memcmplen( + cur, cur - delta2, len_best, len_limit); + + matches[0].len = len_best; + matches[0].dist = delta2 - 1; + matches_count = 1; + + if (len_best == len_limit) { + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + return 1; + } + } + + matches_count = bt_find_func(len_limit, pos, cur, cur_match, mf->depth, + mf->son, mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + + +extern void +lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount) +{ + do { + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; } + else if (len_limit < (3) || (1 && mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + continue; + } + const uint8_t *cur = mf_ptr(mf); + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask; + + const uint32_t cur_match = mf->hash[((1U << 10)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_value] = pos; + + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + } while (--amount != 0); +} + +extern uint32_t +lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches) +{ + uint32_t len_limit = mf->write_pos - mf->read_pos; + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (4) || (mf->action == LZMA_SYNC_FLUSH)) { + ++mf->read_pos; + ++mf->pending; + return 0; + } + + const uint8_t *cur = mf->buffer + mf->read_pos; + const uint32_t pos = mf->read_pos + mf->offset; + uint32_t matches_count = 0; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + + uint32_t delta2 = pos - mf->hash[hash_2_value]; + const uint32_t delta3 = pos - mf->hash[((1U << 10)) + hash_3_value]; + const uint32_t cur_match = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + uint32_t len_best = 1; + + if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { + len_best = 2; + matches[0].len = 2; + matches[0].dist = delta2 - 1; + matches_count = 1; + } + + if (delta2 != delta3 && delta3 < mf->cyclic_size && *(cur - delta3) == *cur) { + len_best = 3; + matches[matches_count++].dist = delta3 - 1; + delta2 = delta3; + } + + if (matches_count != 0) { + len_best = lzma_memcmplen(cur, cur - delta2, len_best, len_limit); + + matches[matches_count - 1].len = len_best; + + if (len_best == len_limit) { + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + return matches_count; + } + } + + if (len_best < 3) + len_best = 3; + + matches_count = bt_find_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size, + matches + matches_count, len_best) - matches; + move_pos(mf); + return matches_count; +} + +extern void +lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount) +{ + do { + uint32_t len_limit = mf_avail(mf); + if (mf->nice_len <= len_limit) { + len_limit = mf->nice_len; + } else if (len_limit < (4) || (mf->action == LZMA_SYNC_FLUSH)) { + move_pending(mf); + continue; + } + + const uint8_t *cur = mf->buffer + mf->read_pos; + const uint32_t pos = mf->read_pos + mf->offset; + + const uint32_t temp = lzma_crc32_table[0][cur[0]] ^ cur[1]; + const uint32_t hash_2_value = temp & ((1U << 10) - 1); + const uint32_t hash_3_value = (temp ^ ((uint32_t)(cur[2]) << 8)) + & ((1U << 16) - 1); + const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) + ^ (lzma_crc32_table[0][cur[3]] << 5)) + & mf->hash_mask; + + const uint32_t cur_match = mf->hash[((1U << 10) + (1U << 16)) + hash_value]; + + mf->hash[hash_2_value] = pos; + mf->hash[((1U << 10)) + hash_3_value] = pos; + mf->hash[((1U << 10) + (1U << 16)) + hash_value] = pos; + + bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, mf->son, + mf->cyclic_pos, mf->cyclic_size); + move_pos(mf); + } while (--amount != 0); +} + +static inline void +mf_skip(lzma_mf *mf, uint32_t amount) +{ + if (amount != 0) { + mf->skip(mf, amount); + mf->read_ahead += amount; + } +} + +typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder; +typedef uint16_t probability; + +typedef struct { + probability choice; + probability choice2; + probability low[(1 << 4)][(1 << 3)]; + probability mid[(1 << 4)][(1 << 3)]; + probability high[(1 << 8)]; + uint32_t prices[(1 << 4)][((1 << 3) + (1 << 3) + (1 << 8))]; + uint32_t table_size; + uint32_t counters[(1 << 4)]; +} lzma_length_encoder; + +typedef struct { + uint64_t low; + uint64_t cache_size; + uint32_t range; + uint8_t cache; + size_t count; + size_t pos; + + enum { + RC_BIT_0, + RC_BIT_1, + RC_DIRECT_0, + RC_DIRECT_1, + RC_FLUSH, + } symbols[58]; + + probability *probs[58]; +} lzma_range_encoder; + + +typedef enum { + STATE_LIT_LIT, + STATE_MATCH_LIT_LIT, + STATE_REP_LIT_LIT, + STATE_SHORTREP_LIT_LIT, + STATE_MATCH_LIT, + STATE_REP_LIT, + STATE_SHORTREP_LIT, + STATE_LIT_MATCH, + STATE_LIT_LONGREP, + STATE_LIT_SHORTREP, + STATE_NONLIT_MATCH, + STATE_NONLIT_REP, +} lzma_lzma_state; + +typedef struct { + lzma_lzma_state state; + _Bool prev_1_is_literal; + _Bool prev_2; + + uint32_t pos_prev_2; + uint32_t back_prev_2; + + uint32_t price; + uint32_t pos_prev; + uint32_t back_prev; + + uint32_t backs[4]; +} lzma_optimal; + +struct lzma_lzma1_encoder_s { + lzma_range_encoder rc; + lzma_lzma_state state; + uint32_t reps[4]; + lzma_match matches[(2 + ((1 << 3) + (1 << 3) + (1 << 8)) - 1) + 1]; + uint32_t matches_count; + uint32_t longest_match_length; + _Bool fast_mode; + _Bool is_initialized; + _Bool is_flushed; + uint32_t pos_mask; + uint32_t literal_context_bits; + uint32_t literal_pos_mask; + + probability literal[(1 << 4)][0x300]; + probability is_match[12][(1 << 4)]; + probability is_rep[12]; + probability is_rep0[12]; + probability is_rep1[12]; + probability is_rep2[12]; + probability is_rep0_long[12][(1 << 4)]; + probability dist_slot[4][(1 << 6)]; + probability dist_special[(1 << (14 / 2)) - 14]; + probability dist_align[(1 << 4)]; + + lzma_length_encoder match_len_encoder; + lzma_length_encoder rep_len_encoder; + + uint32_t dist_slot_prices[4][(1 << 6)]; + uint32_t dist_prices[4][(1 << (14 / 2))]; + uint32_t dist_table_size; + uint32_t match_price_count; + + uint32_t align_prices[(1 << 4)]; + uint32_t align_price_count; + uint32_t opts_end_index; + uint32_t opts_current_index; + lzma_optimal opts[(1 << 12)]; +}; + +extern void +lzma_lzma_optimum_fast(lzma_lzma1_encoder *restrict coder, + lzma_mf *restrict mf, + uint32_t *restrict back_res, uint32_t *restrict len_res) +{ + const uint32_t nice_len = mf->nice_len; + + uint32_t len_main; + uint32_t matches_count; + if (mf->read_ahead == 0) { + len_main = lzma_mf_find(mf, &matches_count, coder->matches); + } else { + len_main = coder->longest_match_length; + matches_count = coder->matches_count; + } + + const uint8_t *buf = mf_ptr(mf) - 1; + const uint32_t buf_avail + = ((mf_avail(mf) + 1) < ((2 + ((1 << 3) + (1 << 3) + (1 << 8)) - 1)) + ? (mf_avail(mf) + 1) : ((2 + ((1 << 3) + (1 << 3) + (1 << 8)) - 1))); + + if (buf_avail < 2) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + + uint32_t rep_len = 0; + uint32_t rep_index = 0; + + for (uint32_t i = 0; i < 4; ++i) { + const uint8_t *const buf_back = buf - coder->reps[i] - 1; + if ((read16ne(buf) != read16ne(buf_back))) + continue; + const uint32_t len = lzma_memcmplen(buf, buf_back, 2, buf_avail); + if (len >= nice_len) { + *back_res = i; + *len_res = len; + mf_skip(mf, len - 1); + return; + } + if (len > rep_len) { + rep_index = i; + rep_len = len; + } + } + if (len_main >= nice_len) { + *back_res = coder->matches[matches_count - 1].dist + 4; + *len_res = len_main; + mf_skip(mf, len_main - 1); + return; + } + + uint32_t back_main = 0; + if (len_main >= 2) { + back_main = coder->matches[matches_count - 1].dist; + while (matches_count > 1 && len_main == + coder->matches[matches_count - 2].len + 1) { + if (!(((back_main) >> 7) > (coder->matches[ matches_count - 2].dist))) + break; + --matches_count; + len_main = coder->matches[matches_count - 1].len; + back_main = coder->matches[matches_count - 1].dist; + } + if (len_main == 2 && back_main >= 0x80) + len_main = 1; + } + + if (rep_len >= 2) { + if (rep_len + 1 >= len_main + || (rep_len + 2 >= len_main + && back_main > (1U << 9)) + || (rep_len + 3 >= len_main + && back_main > (1U << 15))) { + *back_res = rep_index; + *len_res = rep_len; + mf_skip(mf, rep_len - 1); + return; + } + } + + if (len_main < 2 || buf_avail <= 2) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + + coder->longest_match_length = lzma_mf_find(mf, + &coder->matches_count, coder->matches); + + if (coder->longest_match_length >= 2) { + const uint32_t new_dist = coder->matches[ + coder->matches_count - 1].dist; + + if ((coder->longest_match_length >= len_main + && new_dist < back_main) + || (coder->longest_match_length == len_main + 1 + && !(((new_dist) >> 7) > (back_main))) + || (coder->longest_match_length > len_main + 1) + || (coder->longest_match_length + 1 >= len_main + && len_main >= 3 + && (((back_main) >> 7) > (new_dist)))) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + } + ++buf; + const uint32_t limit = ((2) > (len_main - 1) ? (2) : (len_main - 1)); + for (uint32_t i = 0; i < 4; ++i) { + if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) { + *back_res = (4294967295U); + *len_res = 1; + return; + } + } + + *back_res = back_main + 4; + *len_res = len_main; + mf_skip(mf, len_main - 2); + return; +} + +static inline void +rc_bit(lzma_range_encoder *rc, probability *prob, uint32_t bit) +{ + rc->symbols[rc->count] = bit; + rc->probs[rc->count] = prob; + ++rc->count; +} + +static inline void +rc_bittree(lzma_range_encoder *rc, probability *probs, + uint32_t bit_count, uint32_t symbol) +{ + uint32_t model_index = 1; + + do { + const uint32_t bit = (symbol >> --bit_count) & 1; + rc_bit(rc, &probs[model_index], bit); + model_index = (model_index << 1) + bit; + } while (bit_count != 0); +} + +static _Bool +encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf) +{ + if (mf->read_pos == mf->read_limit) { + if (mf->action == LZMA_RUN) + return 0; + } else { + mf_skip(mf, 1); + mf->read_ahead = 0; + rc_bit(&coder->rc, &coder->is_match[0][0], 0); + rc_bittree(&coder->rc, coder->literal[0], 8, mf->buffer[0]); + } + + coder->is_initialized = 1; + + return 1; +} + +static inline uint32_t +mf_position(const lzma_mf *mf) +{ + return mf->read_pos - mf->read_ahead; +} + +static inline _Bool +rc_shift_low(lzma_range_encoder *rc, + uint8_t *out, size_t *out_pos, size_t out_size) +{ + if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000) + || (uint32_t)(rc->low >> 32) != 0) { + do { + if (*out_pos == out_size) + return 1; + + out[*out_pos] = rc->cache + (uint8_t)(rc->low >> 32); + ++*out_pos; + rc->cache = 0xFF; + } while (--rc->cache_size != 0); + rc->cache = (rc->low >> 24) & 0xFF; + } + + ++rc->cache_size; + rc->low = (rc->low & 0x00FFFFFF) << 8; + return 0; +} + +static inline void +rc_reset(lzma_range_encoder *rc) +{ + rc->low = 0; + rc->cache_size = 1; + rc->range = (4294967295U); + rc->cache = 0; + rc->count = 0; + rc->pos = 0; +} + +static inline _Bool +rc_encode(lzma_range_encoder *rc, + uint8_t *out, size_t *out_pos, size_t out_size) +{ + while (rc->pos < rc->count) { + if (rc->range < (1U << 24)) { + if (rc_shift_low(rc, out, out_pos, out_size)) + return 1; + rc->range <<= 8; + } + + switch (rc->symbols[rc->pos]) { + case RC_BIT_0: { + probability prob = *rc->probs[rc->pos]; + rc->range = (rc->range >> 11) + * prob; + prob += ((1U << 11) - prob) >> 5; + *rc->probs[rc->pos] = prob; + break; + } + + case RC_BIT_1: { + probability prob = *rc->probs[rc->pos]; + const uint32_t bound = prob * (rc->range + >> 11); + rc->low += bound; + rc->range -= bound; + prob -= prob >> 5; + *rc->probs[rc->pos] = prob; + break; + } + + case RC_DIRECT_0: + rc->range >>= 1; + break; + + case RC_DIRECT_1: + rc->range >>= 1; + rc->low += rc->range; + break; + + case RC_FLUSH: + rc->range = (4294967295U); + do { + if (rc_shift_low(rc, out, out_pos, out_size)) + return 1; + } while (++rc->pos < rc->count); + + rc_reset(rc); + return 0; + + default: + break; + } + ++rc->pos; + } + + rc->count = 0; + rc->pos = 0; + return 0; +} + +static inline uint64_t +rc_pending(const lzma_range_encoder *rc) +{ + return rc->cache_size + 5 - 1; +} + +static inline void +literal_matched(lzma_range_encoder *rc, probability *subcoder, + uint32_t match_byte, uint32_t symbol) +{ + uint32_t offset = 0x100; + symbol += 1U << 8; + + do { + match_byte <<= 1; + const uint32_t match_bit = match_byte & offset; + const uint32_t subcoder_index + = offset + match_bit + (symbol >> 8); + const uint32_t bit = (symbol >> 7) & 1; + rc_bit(rc, &subcoder[subcoder_index], bit); + + symbol <<= 1; + offset &= ~(match_byte ^ symbol); + + } while (symbol < (1U << 16)); +} + +static inline void +literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position) +{ + const uint8_t cur_byte = mf->buffer[mf->read_pos - mf->read_ahead]; + probability *subcoder = ((coder->literal)[ + (((position) & (coder->literal_pos_mask)) + << (coder->literal_context_bits)) + + ((uint32_t)(mf->buffer[mf->read_pos - mf->read_ahead - 1]) + >> (8U - (coder->literal_context_bits)))]); + + if (((coder->state) < 7)) { + rc_bittree(&coder->rc, subcoder, 8, cur_byte); + } else { + const uint8_t match_byte + = mf->buffer[mf->read_pos - coder->reps[0] - 1 - mf->read_ahead]; + literal_matched(&coder->rc, subcoder, match_byte, cur_byte); + } + coder->state + = ((coder->state) <= STATE_SHORTREP_LIT_LIT + ? STATE_LIT_LIT : ((coder->state) <= STATE_LIT_SHORTREP + ? (coder->state) - 3 : (coder->state) - 6)); +} + +const uint8_t lzma_rc_prices[] = { + 128, 103, 91, 84, 78, 73, 69, 66, + 63, 61, 58, 56, 54, 52, 51, 49, + 48, 46, 45, 44, 43, 42, 41, 40, + 39, 38, 37, 36, 35, 34, 34, 33, + 32, 31, 31, 30, 29, 29, 28, 28, + 27, 26, 26, 25, 25, 24, 24, 23, + 23, 22, 22, 22, 21, 21, 20, 20, + 19, 19, 19, 18, 18, 17, 17, 17, + 16, 16, 16, 15, 15, 15, 14, 14, + 14, 13, 13, 13, 12, 12, 12, 11, + 11, 11, 11, 10, 10, 10, 10, 9, + 9, 9, 9, 8, 8, 8, 8, 7, + 7, 7, 7, 6, 6, 6, 6, 5, + 5, 5, 5, 5, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1 +}; + +static inline uint32_t +rc_bit_price(const probability prob, const uint32_t bit) +{ + return lzma_rc_prices[(prob ^ ((0U - bit) + & ((1U << 11) - 1))) >> 4]; +} + +static inline uint32_t +rc_bit_0_price(const probability prob) +{ + return lzma_rc_prices[prob >> 4]; +} + +static inline uint32_t +rc_bit_1_price(const probability prob) +{ + return lzma_rc_prices[(prob ^ ((1U << 11) - 1)) + >> 4]; +} + +static inline uint32_t +rc_bittree_price(const probability *const probs, + const uint32_t bit_levels, uint32_t symbol) +{ + uint32_t price = 0; + symbol += 1U << bit_levels; + + do { + const uint32_t bit = symbol & 1; + symbol >>= 1; + price += rc_bit_price(probs[symbol], bit); + } while (symbol != 1); + + return price; +} + +static void +length_update_prices(lzma_length_encoder *lc, const uint32_t pos_state) +{ + const uint32_t table_size = lc->table_size; + lc->counters[pos_state] = table_size; + + const uint32_t a0 = rc_bit_0_price(lc->choice); + const uint32_t a1 = rc_bit_1_price(lc->choice); + const uint32_t b0 = a1 + rc_bit_0_price(lc->choice2); + const uint32_t b1 = a1 + rc_bit_1_price(lc->choice2); + uint32_t *const prices = lc->prices[pos_state]; + + uint32_t i; + for (i = 0; i < table_size && i < (1 << 3); ++i) + prices[i] = a0 + rc_bittree_price(lc->low[pos_state], + 3, i); + + for (; i < table_size && i < (1 << 3) + (1 << 3); ++i) + prices[i] = b0 + rc_bittree_price(lc->mid[pos_state], + 3, i - (1 << 3)); + + for (; i < table_size; ++i) + prices[i] = b1 + rc_bittree_price(lc->high, 8, + i - (1 << 3) - (1 << 3)); + + return; +} + +static inline void +length(lzma_range_encoder *rc, lzma_length_encoder *lc, + const uint32_t pos_state, uint32_t len, const _Bool fast_mode) +{ + len -= 2; + + if (len < (1 << 3)) { + rc_bit(rc, &lc->choice, 0); + rc_bittree(rc, lc->low[pos_state], 3, len); + } else { + rc_bit(rc, &lc->choice, 1); + len -= (1 << 3); + + if (len < (1 << 3)) { + rc_bit(rc, &lc->choice2, 0); + rc_bittree(rc, lc->mid[pos_state], 3, len); + } else { + rc_bit(rc, &lc->choice2, 1); + len -= (1 << 3); + rc_bittree(rc, lc->high, 8, len); + } + } + + if (!fast_mode) + if (--lc->counters[pos_state] == 0) + length_update_prices(lc, pos_state); +} + +static inline void +rep_match(lzma_lzma1_encoder *coder, const uint32_t pos_state, + const uint32_t rep, const uint32_t len) +{ + if (rep == 0) { + rc_bit(&coder->rc, &coder->is_rep0[coder->state], 0); + rc_bit(&coder->rc, + &coder->is_rep0_long[coder->state][pos_state], + len != 1); + } else { + const uint32_t distance = coder->reps[rep]; + rc_bit(&coder->rc, &coder->is_rep0[coder->state], 1); + + if (rep == 1) { + rc_bit(&coder->rc, &coder->is_rep1[coder->state], 0); + } else { + rc_bit(&coder->rc, &coder->is_rep1[coder->state], 1); + rc_bit(&coder->rc, &coder->is_rep2[coder->state], + rep - 2); + + if (rep == 3) + coder->reps[3] = coder->reps[2]; + + coder->reps[2] = coder->reps[1]; + } + + coder->reps[1] = coder->reps[0]; + coder->reps[0] = distance; + } + + if (len == 1) { + coder->state = ((coder->state) < 7 ? STATE_LIT_SHORTREP : STATE_NONLIT_REP); + } else { + length(&coder->rc, &coder->rep_len_encoder, pos_state, len, + coder->fast_mode); + coder->state = ((coder->state) < 7 ? STATE_LIT_LONGREP : STATE_NONLIT_REP); + } +} + +// This array is constantly initialized in the original code. It's quite big +// so we skip it. +const uint8_t lzma_fastpos[1 << 13]; + +static inline uint32_t +get_dist_slot(uint32_t dist) +{ + if (dist < (1U << (13 + ((0) + (0) * (13 - 1))))) + return lzma_fastpos[dist]; + + if (dist < (1U << (13 + ((0) + (1) * (13 - 1))))) + return (uint32_t)(lzma_fastpos[(dist) >> ((0) + (1) * (13 - 1))]) + 2 * ((0) + (1) * (13 - 1)); + + return (uint32_t)(lzma_fastpos[(dist) >> ((0) + (2) * (13 - 1))]) + 2 * ((0) + (2) * (13 - 1)); +} + +static inline void +rc_bittree_reverse(lzma_range_encoder *rc, probability *probs, + uint32_t bit_count, uint32_t symbol) +{ + uint32_t model_index = 1; + do { + const uint32_t bit = symbol & 1; + symbol >>= 1; + rc_bit(rc, &probs[model_index], bit); + model_index = (model_index << 1) + bit; + } while (--bit_count != 0); +} + +static inline void +rc_direct(lzma_range_encoder *rc, uint32_t value, uint32_t bit_count) +{ + do { + rc->symbols[rc->count++] + = RC_DIRECT_0 + ((value >> --bit_count) & 1); + } while (bit_count != 0); +} + +static inline void +match(lzma_lzma1_encoder *coder, const uint32_t pos_state, + const uint32_t distance, const uint32_t len) +{ + coder->state = ((coder->state) < 7 ? STATE_LIT_MATCH : STATE_NONLIT_MATCH); + + length(&coder->rc, &coder->match_len_encoder, pos_state, len, + coder->fast_mode); + + const uint32_t dist_slot = get_dist_slot(distance); + const uint32_t dist_state = ((len) < 4 + 2 ? (len) - 2 : 4 - 1); + rc_bittree(&coder->rc, coder->dist_slot[dist_state], 6, dist_slot); + + if (dist_slot >= 4) { + const uint32_t footer_bits = (dist_slot >> 1) - 1; + const uint32_t base = (2 | (dist_slot & 1)) << footer_bits; + const uint32_t dist_reduced = distance - base; + + if (dist_slot < 14) { + rc_bittree_reverse(&coder->rc, coder->dist_special + base - dist_slot - 1, + footer_bits, dist_reduced); + } else { + rc_direct(&coder->rc, dist_reduced >> 4, + footer_bits - 4); + rc_bittree_reverse( + &coder->rc, coder->dist_align, + 4, dist_reduced & ((1 << 4) - 1)); + ++coder->align_price_count; + } + } + + coder->reps[3] = coder->reps[2]; + coder->reps[2] = coder->reps[1]; + coder->reps[1] = coder->reps[0]; + coder->reps[0] = distance; + ++coder->match_price_count; +} + +static void +encode_symbol(lzma_lzma1_encoder *coder, lzma_mf *mf, + uint32_t back, uint32_t len, uint32_t position) +{ + const uint32_t pos_state = position & coder->pos_mask; + + if (back == (4294967295U)) { + rc_bit(&coder->rc, + &coder->is_match[coder->state][pos_state], 0); + literal(coder, mf, position); + } else { + rc_bit(&coder->rc, + &coder->is_match[coder->state][pos_state], 1); + + if (back < 4) { + rc_bit(&coder->rc, &coder->is_rep[coder->state], 1); + rep_match(coder, pos_state, back, len); + } else { + rc_bit(&coder->rc, &coder->is_rep[coder->state], 0); + match(coder, pos_state, back - 4, len); + } + } + mf->read_ahead -= len; +} + +static void +encode_eopm(lzma_lzma1_encoder *coder, uint32_t position) +{ + const uint32_t pos_state = position & coder->pos_mask; + rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1); + rc_bit(&coder->rc, &coder->is_rep[coder->state], 0); + match(coder, pos_state, (4294967295U), 2); +} + +static inline void +rc_flush(lzma_range_encoder *rc) +{ + for (size_t i = 0; i < 5; ++i) + rc->symbols[rc->count++] = RC_FLUSH; +} + +extern void exit (int __status) + __attribute__ ((__nothrow__ , __leaf__ , __noreturn__)); + +extern lzma_ret +lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, + uint8_t *restrict out, size_t *restrict out_pos, + size_t out_size, uint32_t limit) +{ + + if (!coder->is_initialized && !encode_init(coder, mf)) + return LZMA_OK; + + uint32_t position = mf_position(mf); + + while (1) { + if (rc_encode(&coder->rc, out, out_pos, out_size)) { + return LZMA_OK; + } + + if (limit != (4294967295U) + && (mf->read_pos - mf->read_ahead >= limit + || *out_pos + rc_pending(&coder->rc) + >= (1U << 16) - ((1 << 12) + 1))) + break; + + if (mf->read_pos >= mf->read_limit) { + if (mf->action == LZMA_RUN) + return LZMA_OK; + + + if (mf->read_ahead == 0) + break; + } + uint32_t len; + uint32_t back; + + if (coder->fast_mode) + lzma_lzma_optimum_fast(coder, mf, &back, &len); + else + // The original code contains the call to + // lzma_lzma_optimum_normal(coder, mf, &back, &len, position); + exit (-1); + + encode_symbol(coder, mf, back, len, position); + + position += len; + } + + if (!coder->is_flushed) { + coder->is_flushed = 1; + if (limit == (4294967295U)) + encode_eopm(coder, position); + + rc_flush(&coder->rc); + + if (rc_encode(&coder->rc, out, out_pos, out_size)) { + return LZMA_OK; + } + } + + coder->is_flushed = 0; + return LZMA_STREAM_END; +} + +extern void +lzma_free(void *ptr, const lzma_allocator *allocator) +{ + if (allocator != ((void *)0) && allocator->free != ((void *)0)) + allocator->free(allocator->opaque, ptr); + else + free(ptr); + return; +} + +static _Bool +lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator, + const lzma_lz_options *lz_options) +{ + if (lz_options->dict_size < 4096U + || lz_options->dict_size + > (1U << 30) + (1U << 29) + || lz_options->nice_len > lz_options->match_len_max) + return 1; + + mf->keep_size_before = lz_options->before_size + lz_options->dict_size; + mf->keep_size_after = lz_options->after_size + + lz_options->match_len_max; + uint32_t reserve = lz_options->dict_size / 2; + if (reserve > (1U << 30)) + reserve /= 2; + + reserve += (lz_options->before_size + lz_options->match_len_max + + lz_options->after_size) / 2 + (1U << 19); + + const uint32_t old_size = mf->size; + mf->size = mf->keep_size_before + reserve + mf->keep_size_after; + + if ((mf->buffer != ((void *)0)) && old_size != mf->size) { + lzma_free(mf->buffer, allocator); + mf->buffer = ((void *)0); + } + + mf->match_len_max = lz_options->match_len_max; + mf->nice_len = lz_options->nice_len; + mf->cyclic_size = lz_options->dict_size + 1; + + switch (lz_options->match_finder) { + case LZMA_MF_HC3: + mf->find = &lzma_mf_hc3_find; + mf->skip = &lzma_mf_hc3_skip; + break; + + case LZMA_MF_HC4: + mf->find = &lzma_mf_hc4_find; + mf->skip = &lzma_mf_hc4_skip; + break; + + case LZMA_MF_BT2: + mf->find = &lzma_mf_bt2_find; + mf->skip = &lzma_mf_bt2_skip; + break; + + case LZMA_MF_BT3: + mf->find = &lzma_mf_bt3_find; + mf->skip = &lzma_mf_bt3_skip; + break; + + case LZMA_MF_BT4: + mf->find = &lzma_mf_bt4_find; + mf->skip = &lzma_mf_bt4_skip; + break; + + default: + return 1; + } + + const uint32_t hash_bytes = lz_options->match_finder & 0x0F; + if (hash_bytes > mf->nice_len) + return 1; + + const _Bool is_bt = (lz_options->match_finder & 0x10) != 0; + uint32_t hs; + + if (hash_bytes == 2) { + hs = 0xFFFF; + } else { + hs = lz_options->dict_size - 1; + hs |= hs >> 1; + hs |= hs >> 2; + hs |= hs >> 4; + hs |= hs >> 8; + hs >>= 1; + hs |= 0xFFFF; + + if (hs > (1U << 24)) { + if (hash_bytes == 3) + hs = (1U << 24) - 1; + else + hs >>= 1; + } + } + + mf->hash_mask = hs; + + ++hs; + if (hash_bytes > 2) + hs += (1U << 10); + if (hash_bytes > 3) + hs += (1U << 16); + + const uint32_t old_hash_count = mf->hash_count; + const uint32_t old_sons_count = mf->sons_count; + mf->hash_count = hs; + mf->sons_count = mf->cyclic_size; + if (is_bt) + mf->sons_count *= 2; + + if (old_hash_count != mf->hash_count + || old_sons_count != mf->sons_count) { + lzma_free(mf->hash, allocator); + mf->hash = ((void *)0); + + lzma_free(mf->son, allocator); + mf->son = ((void *)0); + } + + mf->depth = lz_options->depth; + if (mf->depth == 0) { + if (is_bt) + mf->depth = 16 + mf->nice_len / 2; + else + mf->depth = 4 + mf->nice_len / 4; + } + + return 0; +} + +int +main () +{ + lzma_mf mf; + lzma_allocator allocator; + lzma_lz_options lz_options; + + void *coder; + uint8_t *restrict out; + size_t *restrict out_pos; + size_t out_size; + + lz_encoder_prepare(&mf, &allocator, &lz_options); + return (int) lzma_lzma_encode(coder, &mf, out, out_pos, out_size, (4294967295U)); +} + + +/* { dg-final { scan-wpa-ipa-dump "Save results of indirect call analysis." "icp"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "For call" 2 "icp"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "Insert 0 prefetch stmt:" 5 "ipa_prefetch"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "Insert 1 prefetch stmt:" 4 "ipa_prefetch"} } */ +/* { dg-final { scan-wpa-ipa-dump-times "Insert 2 prefetch stmt:" 2 "ipa_prefetch"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/ipa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/ipa.exp new file mode 100644 index 0000000000000000000000000000000000000000..e284ad0024781c16dd13b0dcf27d5819a419fb7e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/ipa/ipa.exp @@ -0,0 +1,35 @@ +# Copyright (C) 1997-2022 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/pr107190.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/pr107190.c new file mode 100644 index 0000000000000000000000000000000000000000..d1e72e5df841ab8a50ed92e36c81ad7eeb8c510c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/pr107190.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fmerge-mull -fexpensive-optimizations -fdump-tree-phiopt2-details" } */ + +# define BN_BITS4 32 +# define BN_MASK2 (0xffffffffffffffffL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000L) +# define BN_MASK2h1 (0xffffffff80000000L) +# define LBITS(a) ((a)&BN_MASK2l) +# define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l) +# define L2HBITS(a) (((a)< +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10000; +node_p n; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + + for (int i = 0; i < MAX; i++) + { + n[i].l = n[i].a; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].l != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in Complete Structure Relayout is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-1.c new file mode 100644 index 0000000000000000000000000000000000000000..63bb695ae14a30c8c938f35df304fa6f304de74b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-1.c @@ -0,0 +1,46 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 1; +node_p n; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-2.c new file mode 100644 index 0000000000000000000000000000000000000000..0f75d5d121cf057d8f898e5a037cdca6d1b7a0ef --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-2.c @@ -0,0 +1,59 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10; +node_p n; +node_p m; + +int main() +{ + int i; + for (i = 0; i < MAX / 5; i++) + { + n = (node_p) calloc(MAX, sizeof(node_t)); + if (i == 0) + { + m = n; + } + } + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + m[i].a = 50; + } + + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-3.c new file mode 100644 index 0000000000000000000000000000000000000000..3dcb674c6e9a610734be8b3d351dfd2a6701809f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_allocation-3.c @@ -0,0 +1,77 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10; +node_p n; +node_p m; + +void test (int, int) __attribute__((noinline)); + +void +test (int num, int flag) +{ + if (num <= 0) + { + return; + } + n = (node_p) calloc (num, sizeof (node_t)); + if (flag) + { + m = n; + } + return; +} + +int +main () +{ + test (MAX, 1); + test (MAX, 0); + + for (int i = 0; i < MAX; i++) + { + n[i].a = 100; + } + for (int i = 0; i < MAX; i++) + { + m[i].a = 50; + } + + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + for (int i = 0; i < MAX; i++) + { + if (m[i].a != 50) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_cast_int.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_cast_int.c new file mode 100644 index 0000000000000000000000000000000000000000..6907158c9b0dc6d3d251b29dcda3bda946a779e9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_cast_int.c @@ -0,0 +1,52 @@ +// { dg-do run } + +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 100; +node_p n; +unsigned long y; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + + for (int i = 0; i < MAX; i++) + { + n[i].b = 50; + } + + node_p x = &n[5]; + y = (unsigned long) x; + y += 8; + + if (*((unsigned long*) y) != 50) + { + abort (); + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "struct node has escaped: \"Type escapes a cast from/to intergral type\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_separate_instance.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_separate_instance.c new file mode 100644 index 0000000000000000000000000000000000000000..9e5e05838e64436500aed343354ed59496ec3ae5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_separate_instance.c @@ -0,0 +1,48 @@ +#include +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; + node_p c; + node_p d; + long e; + long f; + long g; + long h; + long i; + long j; + long k; + long l; + int m; + int n; +}; + +const int MAX = 10000; +node_p n; +node_t t; + +int +main () +{ + n = (node_p) calloc (MAX, sizeof (node_t)); + t.a = 100; + + for (int i = 0; i < MAX; i++) + { + n[i].a = t.a; + } + for (int i = 0; i < MAX; i++) + { + if (n[i].a != 100) + { + abort (); + } + } + return 0; +} + +/* { dg-final { scan-ipa-dump "struct node has escaped: \"Type escapes via a separate instance\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_skip_void_struct_name.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_skip_void_struct_name.c new file mode 100644 index 0000000000000000000000000000000000000000..c5e4968d91436e51304390c5ab519b6d5ba9e01d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/csr_skip_void_struct_name.c @@ -0,0 +1,53 @@ +// Structures without names should not be optimized +/* { dg-do compile } */ +#include +#include + +typedef struct +{ + int a; + float b; + double s1; + double s2; + double s3; + double s4; + double s5; + double s6; + double s7; + double s8; +} str_t1; + +#define N 1000 + +int num; + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + str_t1 *p1 = calloc (num, sizeof (str_t1)); + + if (p1 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + for (i = 0; i < num; i++) + p1[i].b = 2; + + for (i = 0; i < num; i++) + if (p1[i].a != 1) + abort (); + + for (i = 0; i < num; i++) + if (fabsf (p1[i].b - 2) > 0.0001) + abort (); + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in Complete Structure Relayout." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_DTE_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_DTE_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..10b5be86d3cf3a759b5a99fdc0ef7df712f62ac1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_DTE_verify.c @@ -0,0 +1,86 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; +arc_p stop_arcs = NULL; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + net[0]->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + net[0]->arcs->id = 100; + + for (unsigned i = 0; i < 3; i++) + { + net[0]->arcs->id = net[0]->arcs->id + 2; + stop_arcs->cost = net[0]->arcs->id / 2; + stop_arcs->net_add = net[0]; + printf("stop_arcs->cost = %ld\n", stop_arcs->cost); + net[0]->arcs++; + stop_arcs++; + } + + if( net[1] != 0 && stop_arcs != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ele_minus_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ele_minus_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..5ecfa9fe1339a1ba8c3c1418c8337eef29c66fbe --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ele_minus_verify.c @@ -0,0 +1,60 @@ +// verify newarc[cmp-1].flow +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p ap = NULL; + +int +main () +{ + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[0].id); + for (int i = 1; i < MAX; i++) + { + ap[i-1].id = 500; + } + printf("%d\n", ap[0].id); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_escape.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_escape.c new file mode 100644 index 0000000000000000000000000000000000000000..09efe8027165317540e03fa3d8eea9f09f08b9c1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_escape.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + int x; +} network_t; + +struct arc +{ + int flow; + network_t* net_add; +}; + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; +arc_p stop_arcs = NULL; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + net[0]->x = 100; + + for (unsigned i = 0; i < 3; i++) + { + net[0]->x = net[0]->x + 2; + stop_arcs->flow = net[0]->x / 2; + stop_arcs->flow = stop_arcs->flow + 20; + stop_arcs->net_add = net[0]; + stop_arcs++; + } + + if( net[1] != 0 && stop_arcs != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_board_init.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_board_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d217f7bd80e719ca96ab92b9ecdbd394a2c1a6ab --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_board_init.c @@ -0,0 +1,77 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_5__ TYPE_2__; +typedef struct TYPE_4__ TYPE_1__; + +struct TYPE_4__ +{ + int Pin; + int Pull; + int Mode; + int Speed; +}; + +struct TYPE_5__ +{ + int MEMRMP; +}; +typedef TYPE_1__ GPIO_InitTypeDef; + +int BT_RST_PIN; +int BT_RST_PORT; +int CONN_POS10_PIN; +int CONN_POS10_PORT; +int GPIO_HIGH (int, int); +int GPIO_MODE_INPUT; +int GPIO_MODE_OUTPUT_PP; +int GPIO_NOPULL; +int GPIO_PULLUP; +int GPIO_SPEED_FREQ_LOW; +int HAL_GPIO_Init (int, TYPE_1__ *); +scalar_t__ IS_GPIO_RESET (int, int); +TYPE_2__ *SYSCFG; +int __HAL_RCC_GPIOB_CLK_ENABLE (); +int __HAL_RCC_GPIOC_CLK_ENABLE (); + +__attribute__((used)) static void +LBF_DFU_If_Needed (void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + __HAL_RCC_GPIOC_CLK_ENABLE (); + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Pin = BT_RST_PIN; + HAL_GPIO_Init (BT_RST_PORT, &GPIO_InitStruct); + + GPIO_HIGH (BT_RST_PORT, BT_RST_PIN); + __HAL_RCC_GPIOB_CLK_ENABLE (); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Pin = CONN_POS10_PIN; + HAL_GPIO_Init (CONN_POS10_PORT, &GPIO_InitStruct); + + if (IS_GPIO_RESET (CONN_POS10_PORT, CONN_POS10_PIN)) + { + SYSCFG->MEMRMP = 0x00000001; + asm ( + "LDR R0, =0x000000\n\t" + "LDR SP, [R0, #0]\n\t" + ); + asm ( + "LDR R0, [R0, #0]\n\t" + "BX R0\n\t" + ); + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_claw.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_claw.c new file mode 100644 index 0000000000000000000000000000000000000000..f9e2cf471c837b4d49c41736a1f611059fffbb49 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_claw.c @@ -0,0 +1,84 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_2__ TYPE_1__; + +struct net_device +{ + struct claw_privbk* ml_priv; +}; +struct clawctl +{ + int linkid; +}; +struct claw_privbk +{ + int system_validate_comp; + TYPE_1__* p_env; + int ctl_bk; +}; +typedef int __u8; +struct TYPE_2__ +{ + scalar_t__ packing; + int api_type; +}; + +int CLAW_DBF_TEXT (int, int, char*); +int CONNECTION_REQUEST; +int HOST_APPL_NAME; +scalar_t__ PACKING_ASK; +scalar_t__ PACK_SEND; +int WS_APPL_NAME_IP_NAME; +int WS_APPL_NAME_PACKED; +int claw_send_control (struct net_device*, int, int, int, int, int, int); +int setup; + +__attribute__((noinline)) int +claw_send_control (struct net_device* net, int a, int b, int c, int d, int e, + int f) +{ + return net->ml_priv->system_validate_comp + a + b + c + d + f; +} + +__attribute__((used)) static int +claw_snd_conn_req (struct net_device *dev, __u8 link) +{ + int rc; + struct claw_privbk *privptr = dev->ml_priv; + struct clawctl *p_ctl; + CLAW_DBF_TEXT (2, setup, "snd_conn"); + rc = 1; + p_ctl = (struct clawctl *)&privptr->ctl_bk; + p_ctl->linkid = link; + if (privptr->system_validate_comp == 0x00) + { + return rc; + } + if (privptr->p_env->packing == PACKING_ASK) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + WS_APPL_NAME_PACKED, WS_APPL_NAME_PACKED); + } + if (privptr->p_env->packing == PACK_SEND) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + WS_APPL_NAME_IP_NAME, WS_APPL_NAME_IP_NAME); + } + if (privptr->p_env->packing == 0) + { + rc = claw_send_control (dev, CONNECTION_REQUEST, 0, 0, 0, + HOST_APPL_NAME, privptr->p_env->api_type); + } + return rc; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_dtrace.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_dtrace.c new file mode 100644 index 0000000000000000000000000000000000000000..c86c4bb3cd0c8eb95f9e9d2e3bbe3e08b8e2f275 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_dtrace.c @@ -0,0 +1,56 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_4__ TYPE_2__; +typedef struct TYPE_3__ TYPE_1__; + +typedef int uint8_t; +typedef int uint16_t; + +struct TYPE_4__ +{ + size_t cpu_id; +}; + +struct TYPE_3__ +{ + int cpuc_dtrace_flags; +}; + +TYPE_2__ *CPU; +volatile int CPU_DTRACE_FAULT; +TYPE_1__ *cpu_core; +scalar_t__ dtrace_load8 (uintptr_t); + +__attribute__((used)) static int +dtrace_bcmp (const void *s1, const void *s2, size_t len) +{ + volatile uint16_t *flags; + flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + if (s1 == s2) + return (0); + if (s1 == NULL || s2 == NULL) + return (1); + if (s1 != s2 && len != 0) + { + const uint8_t *ps1 = s1; + const uint8_t *ps2 = s2; + do + { + if (dtrace_load8 ((uintptr_t)ps1++) != *ps2++) + return (1); + } + while (--len != 0 && !(*flags & CPU_DTRACE_FAULT)); + } + return (0); +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_gc.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_gc.c new file mode 100644 index 0000000000000000000000000000000000000000..8484d29d256b70941f9d75c2673fbee3c3341018 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_gc.c @@ -0,0 +1,162 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +struct mrb_context +{ + size_t stack; + size_t stbase; + size_t stend; + size_t eidx; + int *ci; + int *cibase; + int status; +}; + +struct RObject +{ + int dummy; +}; + +struct RHash +{ + int dummy; +}; + +struct RFiber +{ + struct mrb_context *cxt; +}; + +struct RClass +{ + int dummy; +}; + +struct RBasic +{ + int tt; +}; + +struct RArray +{ + int dummy; +}; + +typedef int mrb_state; +typedef int mrb_gc; +typedef int mrb_callinfo; +size_t ARY_LEN (struct RArray *); +size_t MRB_ENV_STACK_LEN (struct RBasic *); +int MRB_FIBER_TERMINATED; + +#define MRB_TT_ARRAY 140 +#define MRB_TT_CLASS 139 +#define MRB_TT_DATA 138 +#define MRB_TT_ENV 137 +#define MRB_TT_EXCEPTION 136 +#define MRB_TT_FIBER 135 +#define MRB_TT_HASH 134 +#define MRB_TT_ICLASS 133 +#define MRB_TT_MODULE 132 +#define MRB_TT_OBJECT 131 +#define MRB_TT_PROC 130 +#define MRB_TT_RANGE 129 +#define MRB_TT_SCLASS 128 + +size_t ci_nregs (int *); +int gc_mark_children (int *, int *, struct RBasic *); +size_t mrb_gc_mark_hash_size (int *, struct RHash *); +size_t mrb_gc_mark_iv_size (int *, struct RObject *); +size_t mrb_gc_mark_mt_size (int *, struct RClass *); + +__attribute__((used)) static size_t +gc_gray_mark (mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) +{ + size_t children = 0; + gc_mark_children (mrb, gc, obj); + switch (obj->tt) + { + case MRB_TT_ICLASS: + children++; + break; + + case MRB_TT_CLASS: + case MRB_TT_SCLASS: + case MRB_TT_MODULE: + { + struct RClass *c = (struct RClass *)obj; + children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj); + children += mrb_gc_mark_mt_size (mrb, c); + children ++; + } + break; + + case MRB_TT_OBJECT: + case MRB_TT_DATA: + case MRB_TT_EXCEPTION: + children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj); + break; + + case MRB_TT_ENV: + children += MRB_ENV_STACK_LEN (obj); + break; + + case MRB_TT_FIBER: + { + struct mrb_context *c = ((struct RFiber *)obj)->cxt; + size_t i; + mrb_callinfo *ci; + if (!c || c->status == MRB_FIBER_TERMINATED) + break; + + i = c->stack - c->stbase; + if (c->ci) + { + i += ci_nregs (c->ci); + } + if (c->stbase + i > c->stend) + i = c->stend - c->stbase; + + children += i; + children += c->eidx; + if (c->cibase) + { + for (i = 0, ci = c->cibase; ci <= c->ci; i++, ci++) + ; + } + children += i; + } + break; + + case MRB_TT_ARRAY: + { + struct RArray *a = (struct RArray *)obj; + children += ARY_LEN (a); + } + break; + + case MRB_TT_HASH: + children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj); + children += mrb_gc_mark_hash_size (mrb, (struct RHash *)obj); + break; + + case MRB_TT_PROC: + case MRB_TT_RANGE: + children += 2; + break; + default: + break; + } + + return children; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_hpsa.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_hpsa.c new file mode 100644 index 0000000000000000000000000000000000000000..300b2dac4db1ea877c4eef600b150fc9d49f3804 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_hpsa.c @@ -0,0 +1,126 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_6__ TYPE_3__; +typedef struct TYPE_5__ TYPE_2__; +typedef struct TYPE_4__ TYPE_1__; + +struct io_accel2_cmd +{ + int dummy; +}; + +struct hpsa_tmf_struct +{ + int it_nexus; +}; + +struct hpsa_scsi_dev_t +{ + int nphysical_disks; + int ioaccel_handle; + struct hpsa_scsi_dev_t **phys_disk; +}; + +struct ctlr_info +{ + TYPE_3__ *pdev; + struct io_accel2_cmd *ioaccel2_cmd_pool; +}; +struct TYPE_4__ +{ + int LunAddrBytes; +}; + +struct TYPE_5__ +{ + TYPE_1__ LUN; +}; + +struct CommandList +{ + size_t cmdindex; + int cmd_type; + struct hpsa_scsi_dev_t *phys_disk; + TYPE_2__ Header; +}; + +struct TYPE_6__ +{ + int dev; +}; + +int BUG (); +#define CMD_IOACCEL1 132 +#define CMD_IOACCEL2 131 +#define CMD_IOCTL_PEND 130 +#define CMD_SCSI 129 +#define IOACCEL2_TMF 128 +int dev_err (int *, char *, int); +scalar_t__ hpsa_is_cmd_idle (struct CommandList *); +int le32_to_cpu (int); +int test_memcmp (unsigned char *, int *, int); + +__attribute__((used)) static bool +hpsa_cmd_dev_match (struct ctlr_info *h, struct CommandList *c, + struct hpsa_scsi_dev_t *dev, unsigned char *scsi3addr) +{ + int i; + bool match = false; + struct io_accel2_cmd * c2 = &h->ioaccel2_cmd_pool[c->cmdindex]; + struct hpsa_tmf_struct *ac = (struct hpsa_tmf_struct *)c2; + + if (hpsa_is_cmd_idle (c)) + return false; + + switch (c->cmd_type) + { + case CMD_SCSI: + case CMD_IOCTL_PEND: + match = !test_memcmp (scsi3addr, &c->Header.LUN.LunAddrBytes, + sizeof (c->Header.LUN.LunAddrBytes)); + break; + + case CMD_IOACCEL1: + case CMD_IOACCEL2: + if (c->phys_disk == dev) + { + match = true; + } + else + { + for (i = 0; i < dev->nphysical_disks && !match; i++) + { + match = dev->phys_disk[i] == c->phys_disk; + } + } + break; + + case IOACCEL2_TMF: + for (i = 0; i < dev->nphysical_disks && !match; i++) + { + match = dev->phys_disk[i]->ioaccel_handle == + le32_to_cpu (ac->it_nexus); + } + break; + + case 0: + match = false; + break; + default: + dev_err (&h->pdev->dev, "unexpected cmd_type: %d\n", c->cmd_type); + BUG (); + } + + return match; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_mv_udc_core.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_mv_udc_core.c new file mode 100644 index 0000000000000000000000000000000000000000..9397b98eaef0eed1b594cb13fd9e87dccd78e037 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_mv_udc_core.c @@ -0,0 +1,82 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_4__ TYPE_2__; +typedef struct TYPE_3__ TYPE_1__; +typedef int u32; + +struct mv_udc +{ + TYPE_2__ *op_regs; + TYPE_1__ *ep_dqh; + struct mv_ep *eps; +}; + +struct mv_ep +{ + TYPE_1__ *dqh; + struct mv_udc *udc; +}; + +struct TYPE_4__ +{ + int *epctrlx; +}; + +struct TYPE_3__ +{ + int max_packet_length; + int next_dtd_ptr; +}; + +int EP0_MAX_PKT_SIZE; +int EPCTRL_RX_ENABLE; +int EPCTRL_RX_EP_TYPE_SHIFT; +int EPCTRL_TX_ENABLE; +int EPCTRL_TX_EP_TYPE_SHIFT; +int EP_QUEUE_HEAD_IOS; +int EP_QUEUE_HEAD_MAX_PKT_LEN_POS; +int EP_QUEUE_HEAD_NEXT_TERMINATE; +int USB_ENDPOINT_XFER_CONTROL; +int readl (int *); +int writel (int, int *); + +__attribute__((used)) static void +ep0_reset (struct mv_udc *udc) +{ + struct mv_ep *ep; + u32 epctrlx; + int i = 0; + for (i = 0; i < 2; i++) + { + ep = &udc->eps[i]; + ep->udc = udc; + ep->dqh = &udc->ep_dqh[i]; + ep->dqh->max_packet_length = + (EP0_MAX_PKT_SIZE << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) + | EP_QUEUE_HEAD_IOS; + ep->dqh->next_dtd_ptr = EP_QUEUE_HEAD_NEXT_TERMINATE; + epctrlx = readl (&udc->op_regs->epctrlx[0]); + if (i) + { + epctrlx |= EPCTRL_TX_ENABLE + | (USB_ENDPOINT_XFER_CONTROL << EPCTRL_TX_EP_TYPE_SHIFT); + } + else + { + epctrlx |= EPCTRL_RX_ENABLE + | (USB_ENDPOINT_XFER_CONTROL << EPCTRL_RX_EP_TYPE_SHIFT); + } + writel (epctrlx, &udc->op_regs->epctrlx[0]); + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_tcp_usrreq.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_tcp_usrreq.c new file mode 100644 index 0000000000000000000000000000000000000000..0ae75e13e8f5b4d89640b65e269bcaaacd37c0d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_tcp_usrreq.c @@ -0,0 +1,58 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +struct tcpcb +{ + int t_state; +}; + +struct socket +{ + int dummy; +}; + +struct proc +{ + int dummy; +}; + +struct inpcb +{ + scalar_t__ inp_lport; +}; + +int COMMON_END (int); +int COMMON_START (); +int PRU_LISTEN; +int TCPS_LISTEN; +int in_pcbbind (struct inpcb *, int *, struct proc *); +struct inpcb* sotoinpcb (struct socket *); + +__attribute__((used)) static void +tcp_usr_listen (struct socket *so, struct proc *p) +{ + int error = 0; + struct inpcb *inp = sotoinpcb (so); + struct tcpcb *tp; + + COMMON_START (); + if (inp->inp_lport == 0) + { + error = in_pcbbind (inp, NULL, p); + } + if (error == 0) + { + tp->t_state = TCPS_LISTEN; + } + COMMON_END (PRU_LISTEN); +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_ui_main.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_ui_main.c new file mode 100644 index 0000000000000000000000000000000000000000..512fb37a7f48fff187d2ec3b52491b27cf97a359 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_extr_ui_main.c @@ -0,0 +1,61 @@ +/* { dg-do compile} */ + +#define NULL ((void*)0) +typedef unsigned long size_t; +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long scalar_t__; +typedef int bool; +#define false 0 +#define true 1 + +typedef struct TYPE_4__ TYPE_2__; +typedef struct TYPE_3__ TYPE_1__; + +struct TYPE_4__ +{ + size_t modCount; + TYPE_1__ *modList; +}; + +struct TYPE_3__ +{ + void *modDescr; + void *modName; +}; + +size_t MAX_MODS; +void *String_Alloc (char *); +int test_strlen (char *); +int trap_FD_GetFileList (char *, char *, char *, int); +TYPE_2__ uiInfo; + +__attribute__((used)) static void +UI_LoadMods () +{ + int numdirs; + char dirlist[2048]; + char *dirptr; + char *descptr; + int i; + int dirlen; + + uiInfo.modCount = 0; + numdirs = trap_FD_GetFileList ("$modelist", "", dirlist, sizeof (dirlist)); + dirptr = dirlist; + for (i = 0; i < numdirs; i++) + { + dirlen = test_strlen (dirptr) + 1; + descptr = dirptr + dirlen; + uiInfo.modList[uiInfo.modCount].modName = String_Alloc (dirptr); + uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc (descptr); + dirptr += dirlen + test_strlen (descptr) + 1; + uiInfo.modCount++; + if (uiInfo.modCount >= MAX_MODS) + { + break; + } + } +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_func_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_func_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..74ea93bbc59282b7912d29605bb9610ae1158240 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_func_ptr.c @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +#include + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +int num; + +int (*foo)(int d); +int f (int t); + +typedef struct str_t str_t1; +struct str_t +{ + int a; + float b; + int (*foo)(int d); +}; + +int main () +{ + int i, r; + r = rand (); + num = r > N ? N : r; + str_t1 * p1 = calloc (num, sizeof (str_t1)); + if (p1 == NULL) + return 0; + for (i = 0; i < num; i++) + { + p1[i].foo = malloc (1 * sizeof (f)); + p1[i].foo = f; + p1[i].foo (i); + } + + for (i = 0; i < num; i++) + p1[i].a = 1; + + for (i = 0; i < num; i++) + p1[i].b = 2; + + for (i = 0; i < num; i++) + if (p1[i].a != 1) + abort (); + + for (i = 0; i < num; i++) + if (abs (p1[i].b - 2) > 0.0001) + abort (); + + return 0; +} + +int f (int t) +{ + if ( t < 0) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_mem_ref_offset.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_mem_ref_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..6148770282cfb758be4c84e58f9673045c150302 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_mem_ref_offset.c @@ -0,0 +1,58 @@ +/* Supports the MEM_REF offset. + _1 = MEM[(struct arc *)ap_4 + 72B].flow; + Old rewrite:_1 = ap.reorder.0_8->flow; + New rewrite:_1 = MEM[(struct arc.reorder.0 *)ap.reorder.0_8 + 64B].flow. */ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + const int MAX = 100; + /* A similar scenario can be reproduced only by using local variables. */ + arc_p ap = NULL; + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..0570d8952094d075339cf02baabc45842ef22b58 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_mul_layer_ptr_record_bug.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct T_HASH_ENTRY +{ + unsigned int hash; + unsigned int klen; + char *key; +} iHashEntry; + +typedef struct T_HASH +{ + unsigned int size; + unsigned int fill; + unsigned int keys; + + iHashEntry **array; +} uHash; + +uHash *retval; + +int +main() { + retval->array = (iHashEntry **)calloc(sizeof(iHashEntry *), retval->size); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_diff.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_diff.c new file mode 100644 index 0000000000000000000000000000000000000000..4c395264da942ff7d5ac3e9796ada1938868b514 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_diff.c @@ -0,0 +1,71 @@ +// support POINTER_DIFF_EXPR & NOP_EXPR to avoid +// escape_unhandled_rewrite, "Type escapes via a unhandled rewrite stmt" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + arc_t *old_arcs; + node_t *node; + node_t *stop; + size_t off; + network_t* net; + + for( ; node->number < stop->number; node++ ) + { + off = node->basic_arc - old_arcs; + node->basic_arc = (arc_t *)(net->arcs + off); + } + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 3 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_negate_expr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_negate_expr.c new file mode 100644 index 0000000000000000000000000000000000000000..e59a4b48429bb8e638c1ab3c15f151b915f631c5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_negate_expr.c @@ -0,0 +1,55 @@ +// support NEGATE_EXPR rewriting +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + int64_t susp = 0; + const int MAX = 100; + arc_p ap = (arc_p) calloc(MAX, sizeof(arc_t)); + ap -= susp; + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..48cd7932a670b4d18deaf2f393fc31eb737aaba1 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/dfe_ptr_ptr.c @@ -0,0 +1,55 @@ +// release escape_ptr_ptr, "Type is used in a pointer to a pointer [not handled yet]"; +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_t **ap = NULL; + +int +main () +{ + ap = (arc_t**) malloc(MAX * sizeof(arc_t*)); + (*ap)[0].id = 300; + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 2 "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_cast_int.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_cast_int.c new file mode 100644 index 0000000000000000000000000000000000000000..6f67fc556afca98085f22ae1cfd238f69a342ce6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_cast_int.c @@ -0,0 +1,91 @@ +// Escape cast int for pointer compression +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + node_p n1 = (node_p) 0x123456; + + for (unsigned i = 0; i < MAX; i++) + { + node->pred = n1; + node = node + 1; + } + + node = net->nodes; + + for (unsigned i = 0; i < MAX; i++) + { + if (node->pred != n1) + { + abort (); + } + node = node + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in pointer compression" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_compress_and_decomress.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_compress_and_decomress.c new file mode 100644 index 0000000000000000000000000000000000000000..d0b8d1afa48b16b71971992c86b19c8452c4916e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_compress_and_decomress.c @@ -0,0 +1,90 @@ +// Support basic pointer compression and decompression +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + + for (unsigned i = 0; i < MAX; i++) + { + node->pred = node; + node = node + 1; + } + + node = net->nodes; + + for (unsigned i = 0; i < MAX; i++) + { + if (node->pred != node) + { + abort (); + } + node = node + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in pointer compression is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_ptr2void.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_ptr2void.c new file mode 100644 index 0000000000000000000000000000000000000000..5022c1967bc79798ac42210e458f0071dd6f1fbc --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_ptr2void.c @@ -0,0 +1,87 @@ +// Partially support escape_cast_void for pointer compression. +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs, sorted_arcs; + int x; + node_p nodes, stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +network_t* net = NULL; +int cnt = 0; + +__attribute__((noinline)) int +primal_feasible (network_t *net) +{ + void* stop; + node_t *node; + + node = net->nodes; + stop = (void *)net->stop_nodes; + for( node++; node < (node_t *)stop; node++ ) + { + net->x = 1; + printf( "PRIMAL NETWORK SIMPLEX: "); + } + return 0; +} + +int +main () +{ + net = (network_t*) calloc (1, 20); + net->nodes = calloc (MAX, sizeof (node_t)); + net->stop_nodes = net->nodes + MAX - 1; + cnt = primal_feasible( net ); + + net = (network_t*) calloc (1, 20); + if( !(net->arcs) ) + { + return -1; + } + return cnt; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in pointer compression is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_simple_rewrite_pc.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_simple_rewrite_pc.c new file mode 100644 index 0000000000000000000000000000000000000000..98943c9b81315858abc38d388847a0efc67b4b33 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_simple_rewrite_pc.c @@ -0,0 +1,112 @@ +// Check simplify rewrite chance for pointer compression and decompression +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; +arc_p arc; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + arc = net->arcs; + + for (unsigned i = 0; i < MAX; i++) + { + arc->head = node; + arc->head->child = node; + node->potential = i + 1; + arc->cost = arc->head->potential; + arc->tail = node->sibling; + if (i % 2) + node->pred = net->nodes + i; + else + node->pred = NULL; + + if (node->pred && node->pred->child != NULL) + node->number = 0; + else + node->number = 1; + + node = node + 1; + arc = arc + 1; + } + + node = net->nodes; + arc = net->arcs; + + for (unsigned i = 0; i < MAX; i++) + { + node_p t = i % 2 ? node : NULL; + int tt = i % 2 ? 0 : 1; + if (arc->head->pred != t || arc->cost == 0 + || arc->tail != node->sibling || node->number != tt) + { + abort (); + } + arc = arc + 1; + node = node + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in pointer compression is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_skip_void_struct_name.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_skip_void_struct_name.c new file mode 100644 index 0000000000000000000000000000000000000000..a0e191267b7a0b7c2d22cca530a3d710b4241a00 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/pc_skip_void_struct_name.c @@ -0,0 +1,53 @@ +// Structures without names should not be optimized +/* { dg-do compile } */ +#include +#include + +typedef struct +{ + int a; + float b; + double s1; + double s2; + double s3; + double s4; + double s5; + double s6; + double s7; + double s8; +} str_t1; + +#define N 1000 + +int num; + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + str_t1 *p1 = calloc (num, sizeof (str_t1)); + + if (p1 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + for (i = 0; i < num; i++) + p1[i].b = 2; + + for (i = 0; i < num; i++) + if (p1[i].a != 1) + abort (); + + for (i = 0; i < num; i++) + if (fabsf (p1[i].b - 2) > 0.0001) + abort (); + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform in pointer compression" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_DTE_struct_instance_field.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_DTE_struct_instance_field.c new file mode 100644 index 0000000000000000000000000000000000000000..1b6a462e2715c36ddb361b5d0306cf2e45e4c3f2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_DTE_struct_instance_field.c @@ -0,0 +1,75 @@ +// escape_instance_field, "Type escapes via a field of instance". +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; + node_t node; +} network_t; + + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; + node_t node; +}; + + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + net[0]->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + /* Contains an escape type and has structure instance field. */ + net[0]->arcs->node = net[0]->node; + + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_DTE_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_DTE_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..346c7126446a35b7dc5c5ff8caefad78ff6b3dde --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_DTE_verify.c @@ -0,0 +1,94 @@ +// Verify in escape_dependent_type_escapes, +// the multi-layer dereference is rewriting correctly,and the memory access +// is correct. + +// release +// escape_dependent_type_escapes, +// "Type uses a type which escapes or is used by a type which escapes" +// avoid escape_cast_another_ptr, "Type escapes a cast to a different pointer" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; + +/* let it escape_array, "Type is used in an array [not handled yet]". */ +network_t* net[2]; +arc_p stop_arcs = NULL; + +int +main () +{ + net[0] = (network_t*) calloc (1, sizeof(network_t)); + net[0]->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + + net[0]->arcs->id = 100; + + for (unsigned i = 0; i < 3; i++) + { + net[0]->arcs->id = net[0]->arcs->id + 2; + stop_arcs->cost = net[0]->arcs->id / 2; + stop_arcs->net_add = net[0]; + printf("stop_arcs->cost = %ld\n", stop_arcs->cost); + net[0]->arcs++; + stop_arcs++; + } + + if( net[1] != 0 && stop_arcs != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_check_ptr_layers_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_check_ptr_layers_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..b876fef861fa2f6507ec37d8b2f030da26d4ca74 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_check_ptr_layers_bug.c @@ -0,0 +1,24 @@ +/* check_ptr_layers bugfix.*/ +/* { dg-do compile } */ +struct { + char a; +} **b = 0, *e = 0; +long c; +char d = 9; +int f; + +void g() +{ + for (; f;) + if (c) + (*e).a++; + if (!d) + for (;;) + b &&c; +} +int +main() +{ + g(); +} +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_create_fields_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_create_fields_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..7d7641f011d6c9f9efb5285134ea92fa2db36a1f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_create_fields_bug.c @@ -0,0 +1,82 @@ +// bugfix: +// Common members do not need to reconstruct. +// Otherwise, eg:int* -> int** and void* -> void**. +/* { dg-do compile } */ + +#include +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t* cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t** org_cost; +}; + +struct a +{ + int t; + int t1; +}; + +__attribute__((noinline)) int +f(int i, int j) +{ + struct a *t = NULL; + struct a t1 = {i, j}; + t = &t1; + auto int g(void) __attribute__((noinline)); + int g(void) + { + return t->t + t->t1; + } + return g(); +} + +arc_t **ap = NULL; +const int MAX = 100; + +int +main() +{ + if (f(1, 2) != 3) + { + abort (); + } + ap = (arc_t**) malloc(MAX * sizeof(arc_t*)); + (*ap)[0].id = 300; + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_create_new_func_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_create_new_func_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..63fb3f8284cb9d6218abc2419593cc30c2969632 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_create_new_func_bug.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ + +#include +#include + +#define MallocOrDie(x) sre_malloc((x)) + +struct gki_elem { + char *key; + int idx; + struct gki_elem *nxt; +}; + +typedef struct { + struct gki_elem **table; + + int primelevel; + int nhash; + int nkeys; +} GKI; + +void +Die(char *format, ...) +{ + exit(1); +} + +void * +sre_malloc(size_t size) +{ + void *ptr; + + if ((ptr = malloc (size)) == NULL) + { + Die("malloc of %ld bytes failed", size); + } + return ptr; +} + + +__attribute__((noinline)) int +GKIStoreKey(GKI *hash, char *key) +{ + hash->table[0] = MallocOrDie(sizeof(struct gki_elem)); +} + +int +main () +{ + GKI *hash; + char *key; + GKIStoreKey(hash, key); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ele_minus_verify.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ele_minus_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..8c431e15ffd3d259ef81ac89a457dc5b68de36b7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ele_minus_verify.c @@ -0,0 +1,60 @@ +// verify newarc[cmp-1].flow +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p ap = NULL; + +int +main () +{ + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[0].id); + for (int i = 1; i < MAX; i++) + { + ap[i-1].id = 500; + } + printf("%d\n", ap[0].id); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_escape_by_base.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_escape_by_base.c new file mode 100644 index 0000000000000000000000000000000000000000..efc95a4cd56e1bb10a0db989b77e0d201b360fdd --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_escape_by_base.c @@ -0,0 +1,83 @@ +// release type is used by a type which escapes. +// avoid escape_cast_another_ptr, "Type escapes a cast to a different pointer" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +network_t* net = NULL; +arc_p stop_arcs = NULL; +int cnt = 0; + +int +main () +{ + net = (network_t*) calloc (1, 20); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + if(!(net->arcs)) + { + return -1; + } + + for( int i = 0; i < MAX; i++, net->arcs = stop_arcs) + { + cnt++; + } + + net = (network_t*) calloc (1, 20); + if( !(net->arcs) ) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_external_func_types.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_external_func_types.c new file mode 100644 index 0000000000000000000000000000000000000000..2a9bea78369abb1ab4f7547f3a3ba96102f598d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_external_func_types.c @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-shared" } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + int x; + arc_p arcs, sorted_arcs; + node_p nodes, stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +extern int bcf_sr_add_reader (network_t *); +extern int bcf_hdr_dup (arc_p); + +int +test () +{ + network_t *net = (network_t *) calloc (1, 20); + + if (!bcf_sr_add_reader(net)) + printf("error"); + arc_p arc = net->nodes->basic_arc; + if(!bcf_hdr_dup(arc)) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_int_cast_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_int_cast_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..75fc10575d58ccbc49955c8497807668462fd766 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_int_cast_ptr.c @@ -0,0 +1,72 @@ +// release escape_cast_another_ptr, "Type escapes a cast to a different pointer" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +typedef int cmp_t(const void *, const void *); + +__attribute__((noinline)) void +spec_qsort(void *a, cmp_t *cmp) +{ + char *pb = NULL; + while (cmp(pb, a)) + { + pb += 1; + } +} + +static int arc_compare( arc_t **a1, int a2 ) +{ + if( (*a1)->id < a2 ) + { + return -1; + } + return 1; +} + +int +main() +{ + spec_qsort(NULL, (int (*)(const void *, const void *))arc_compare); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_mem_ref_offset.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_mem_ref_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..9fb06877bcbf068e2d47a91b5a214ed1b8f89c6b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_mem_ref_offset.c @@ -0,0 +1,58 @@ +/* Supports the MEM_REF offset. + _1 = MEM[(struct arc *)ap_4 + 72B].flow; + Old rewrite:_1 = ap.reorder.0_8->flow; + New rewrite:_1 = MEM[(struct arc.reorder.0 *)ap.reorder.0_8 + 64B].flow. */ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + const int MAX = 100; + /* A similar scenario can be reproduced only by using local variables. */ + arc_p ap = NULL; + ap = (arc_p) calloc(MAX, sizeof(arc_t)); + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..e8eb0eaa09a549805d5486c8726e4b82003842b3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +#include +#include + +typedef struct T_HASH_ENTRY +{ + unsigned int hash; + unsigned int klen; + char *key; +} iHashEntry; + +typedef struct T_HASH +{ + unsigned int size; + unsigned int fill; + unsigned int keys; + + iHashEntry **array; +} uHash; + +uHash *retval; + +int +main() { + retval->array = (iHashEntry **)calloc(sizeof(iHashEntry *), retval->size); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_pass_conflict.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_pass_conflict.c new file mode 100644 index 0000000000000000000000000000000000000000..bd535afd08d1ed5dc3657a4089f38e314e821a86 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_pass_conflict.c @@ -0,0 +1,109 @@ +// For testing: +/* +Compile options: gcc -O3 -g +-flto -flto-partition=one -fipa-reorder-fields -fipa-struct-reorg +-v -save-temps -fdump-ipa-all-details test.c -o test + +in COMPLETE_STRUCT_RELAYOUT pass: +N type: struct node.reorder.0 new = "Type escapes a cast to a different pointer" +copy$head_26 = test_arc.reorder.0_49->head; + +type : struct arc.reorder.0(1599) { +fields = { +field (5382) {type = cost_t} +field (5383) {type = struct node.reorder.0 *} // but node has escaped. +field (5384) {type = struct node.reorder.0 *} +field (5386) {type = struct arc.reorder.0 *} +field (5387) {type = struct arc.reorder.0 *} +field (5388) {type = flow_t} +field (5389) {type = cost_t} +field (5381) {type = int} +field (5385) {type = short int} +} + +// The types of the two types are inconsistent after the rewriting. +newarc_2(D)->tail = tail_1(D); +vs +struct_reorder.0_61(D)->tail = tail_1(D); +*/ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +__attribute__((noinline)) void +replace_weaker_arc( arc_t *newarc, node_t *tail, node_t *head) +{ + printf("test"); +} + +__attribute__((noinline)) int64_t +switch_arcs(arc_t** deleted_arcs, arc_t* arcnew) +{ + int64_t count = 0; + arc_t *test_arc, copy; + + if (!test_arc->ident) + { + copy = *test_arc; + count++; + *test_arc = arcnew[0]; + replace_weaker_arc(arcnew, NULL, NULL); + } + return count; +} + +int +main () +{ + switch_arcs(NULL, NULL); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr2void_lto.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr2void_lto.c new file mode 100644 index 0000000000000000000000000000000000000000..11393a197a357dcdaae6353cb199aac31eef9c89 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr2void_lto.c @@ -0,0 +1,87 @@ +// escape_cast_void, "Type escapes a cast to/from void*" +// stop_393 = net.stop_nodes; void *stop; +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs, sorted_arcs; + int x; + node_p nodes, stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +network_t* net = NULL; +int cnt = 0; + +__attribute__((noinline)) int +primal_feasible (network_t *net) +{ + void* stop; + node_t *node; + + node = net->nodes; + stop = (void *)net->stop_nodes; + for( node++; node < (node_t *)stop; node++ ) + { + printf( "PRIMAL NETWORK SIMPLEX: " ); + } + return 0; +} + +int +main () +{ + net = (network_t*) calloc (1, 20); + net->nodes = calloc (MAX, sizeof (node_t)); + net->stop_nodes = calloc (MAX, sizeof (node_t)); + cnt = primal_feasible( net ); + + net = (network_t*) calloc (1, 20); + if( !(net->arcs) ) + { + return -1; + } + return cnt; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_diff.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_diff.c new file mode 100644 index 0000000000000000000000000000000000000000..d601fae64d4d8e919835155339a7d38c69a0a9a3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_diff.c @@ -0,0 +1,71 @@ +// support POINTER_DIFF_EXPR & NOP_EXPR to avoid +// escape_unhandled_rewrite, "Type escapes via a unhandled rewrite stmt" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + arc_t *old_arcs; + node_t *node; + node_t *stop; + size_t off; + network_t* net; + + for( ; node->number < stop->number; node++ ) + { + off = node->basic_arc - old_arcs; + node->basic_arc = (arc_t *)(net->arcs + off); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 3" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_negate_expr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_negate_expr.c new file mode 100644 index 0000000000000000000000000000000000000000..4d5f25aa1645e702617101b7da8c1201f3daacea --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_negate_expr.c @@ -0,0 +1,55 @@ +// support NEGATE_EXPR rewriting +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main () +{ + int64_t susp = 0; + const int MAX = 100; + arc_p ap = (arc_p) calloc(MAX, sizeof(arc_t)); + ap -= susp; + printf("%d\n", ap[1].flow); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_offset.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..b3891fde9280142a50ed3fcb023c6541f7aa4d42 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_offset.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ + +#include +#include + +struct node +{ + struct node *left, *right; + double a, b, c, d, e, f; +} +*a; +int b, c; +void +CreateNode (struct node **p1) +{ + *p1 = calloc (10, sizeof (struct node)); +} + +int +main () +{ + a->left = 0; + struct node *t = a; + CreateNode (&t->right); + + struct node p = *a; + b = 1; + if (p.left) + b = 0; + if (b) + printf (" Tree.\n"); +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..4df79e4f0e8d2a35d638127f23172907226ade87 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_ptr.c @@ -0,0 +1,55 @@ +// release escape_ptr_ptr, "Type is used in a pointer to a pointer [not handled yet]"; +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_t **ap = NULL; + +int +main () +{ + ap = (arc_t**) malloc(MAX * sizeof(arc_t*)); + (*ap)[0].id = 300; + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_ptr_ptr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_ptr_ptr.c new file mode 100644 index 0000000000000000000000000000000000000000..49d2106d1dc6d083c6f6debc5ff42031b3b86d76 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_ptr_ptr_ptr.c @@ -0,0 +1,58 @@ +// release escape_ptr_ptr, "Type is used in a pointer to a pointer [not handled yet]" + +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p **ap; + + +int +main () +{ + ap = (arc_p**) calloc(MAX, sizeof(arc_p*)); + (**ap)[0].id = 500; + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rescusive_type.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rescusive_type.c new file mode 100644 index 0000000000000000000000000000000000000000..f71c7894f361b9a6b8eaa5071328c005f1a5fe63 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rescusive_type.c @@ -0,0 +1,57 @@ +// release escape_rescusive_type, "Recusive type" +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; +arc_p ap = NULL; + +int +main () +{ + ap = (arc_p) calloc (MAX, sizeof (arc_t)); + ap[0].id = 100; + ap[0].head = (node_p) calloc (MAX, sizeof (node_t)); + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_assign_more_cmp.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_assign_more_cmp.c new file mode 100644 index 0000000000000000000000000000000000000000..721cee2c6ae74564564001f4b608194c52cdaeac --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_assign_more_cmp.c @@ -0,0 +1,65 @@ +// support more gimple assign rhs code +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +__attribute__((noinline)) int +compare(arc_p p1, arc_p p2) +{ + return p1 < p2; +} + +int n = 0; +int m = 0; + +int +main () +{ + scanf ("%d %d", &n, &m); + arc_p p = calloc (10, sizeof (struct arc)); + if (compare (&p[n], &p[m])) + { + printf ("ss!"); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_cond_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_cond_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..3871d3d99f14ef43d01d76700c340257916f5b49 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_cond_bug.c @@ -0,0 +1,72 @@ +// rewrite_cond bugfix; +/* +if (iterator_600 != 0B) +old rewrite: _1369 = iterator.reorder.0_1249 != 0B; if (_1369 != 1) +new rewrite: if (iterator.reorder.0_1249 != 0B) +*/ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct list_elem +{ + arc_t* arc; + struct list_elem* next; +}list_elem; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int i = 0; + +int +main () +{ + register list_elem *first_list_elem; + register list_elem* iterator; + iterator = first_list_elem->next; + while (iterator) + { + iterator = iterator->next; + i++; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 3" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_cond_more_cmp.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_cond_more_cmp.c new file mode 100644 index 0000000000000000000000000000000000000000..5ad206433e02387b2da88df97ccb873e13a4dda4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_cond_more_cmp.c @@ -0,0 +1,58 @@ +// support if (_150 >= _154) +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +int +main() +{ + arc_p **ap = (arc_p**) malloc(1 * sizeof(arc_p*)); + arc_p **arcs_pointer_sorted = (arc_p**) malloc(1 * sizeof(arc_p*)); + arcs_pointer_sorted[0] = (arc_p*) calloc (1, sizeof(arc_p)); + + if (arcs_pointer_sorted >= ap) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_phi_bug.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_phi_bug.c new file mode 100644 index 0000000000000000000000000000000000000000..a002f98892ea734e8da409ec912b81de0855aa8d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_rewrite_phi_bug.c @@ -0,0 +1,81 @@ +/* +Exclude the rewriting error caused by +first_list_elem = (list_elem *)NULL; +rewriting PHI:first_list_elem_700 = PHI <0B(144), 0B(146)> +into: +first_list_elem.reorder.0_55 = PHI <(144), (146)> +*/ +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct list_elem +{ + arc_t* arc; + struct list_elem* next; +}list_elem; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout, firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail, head; + short ident; + arc_p nextout, nextin; + int64_t flow; + int64_t org_cost; +}; + +const int MAX = 100; + +list_elem* new_list_elem; +list_elem* first_list_elem; + +int +main () +{ + int i = 0; + list_elem *first_list_elem; + list_elem *new_list_elem; + arc_t *arcout; + for( ; i < MAX && arcout->ident == -1; i++); + + first_list_elem = (list_elem *)NULL; + for( ; i < MAX; i++) + { + new_list_elem = (list_elem*) calloc(1, sizeof(list_elem)); + new_list_elem->next = first_list_elem; + first_list_elem = new_list_elem; + } + if (first_list_elem != 0) + { + return -1; + } + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 3" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_shwi.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_shwi.c new file mode 100644 index 0000000000000000000000000000000000000000..2bb326ff20057364ebbde5039f97f4003dc4447d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_shwi.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +struct foo {int dx; long dy; int dz; }; +struct goo {long offset; struct foo* pfoo; }; + +void* func (long); + +__attribute__((used)) static void +test(struct goo* g) +{ + void* pvoid; + struct foo* f; + + for (f = g->pfoo; f->dx; f++) + { + if (f->dy) + break; + } + f--; + + pvoid = func(f->dz + g->offset); + return; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_visible_func.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_visible_func.c new file mode 100644 index 0000000000000000000000000000000000000000..f77a062bda6c0dee37a9ada6905b50d4bddd9db5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_visible_func.c @@ -0,0 +1,92 @@ +// release escape_visible_function, "Type escapes via expternally visible function call" +// compile options: gcc -O3 -fno-inline -fwhole-program +// -flto-partition=one -fipa-struct-reorg arc_compare.c -fdump-ipa-all -S -v +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +__attribute__((noinline)) static int +arc_compare( arc_t **a1, arc_t **a2 ) +{ + if( (*a1)->flow > (*a2)->flow ) + { + return 1; + } + if( (*a1)->flow < (*a2)->flow ) + { + return -1; + } + if( (*a1)->id < (*a2)->id ) + { + return -1; + } + + return 1; +} + +__attribute__((noinline)) void +spec_qsort(void *array, int nitems, int size, + int (*cmp)(const void*,const void*)) +{ + for (int i = 0; i < nitems - 1; i++) + { + if (cmp (array , array)) + { + printf ("CMP 1\n"); + } + else + { + printf ("CMP 2\n"); + } + } +} + +typedef int cmp_t(const void *, const void *); + +int +main () +{ + void *p = calloc (100, sizeof (arc_t **)); + spec_qsort (p, 100, 0, (int (*)(const void *, const void *))arc_compare); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_void_ptr_param_func.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_void_ptr_param_func.c new file mode 100644 index 0000000000000000000000000000000000000000..cba6225a5e9c875015289485f90f091ee591398f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/rf_void_ptr_param_func.c @@ -0,0 +1,54 @@ +// Add a safe func mechanism. +// avoid escape_unkown_field, "Type escapes via an unkown field accessed" +// avoid escape_cast_void, "Type escapes a cast to/from void*" eg: GIMPLE_NOP +/* { dg-do compile } */ + +#include +#include + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +struct arc +{ + int id; + int64_t cost; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; +}; + +void +__attribute__((noinline)) spec_qsort (void *a, size_t es) +{ + char *pa; + char *pb; + int cmp_result; + + while ((*(arc_t **)a)->id < *((int *)a)) + { + if (cmp_result == 0) + { + spec_qsort (a, es); + pa = (char *)a - es; + a += es; + *(long *)pb = *(long *)pa; + } + else + { + a -= pa - pb; + } + } +} + +int +main() +{ + arc_p **arcs_pointer_sorted; + spec_qsort (arcs_pointer_sorted[0], sizeof (arc_p)); + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/semi_relayout_rewrite.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/semi_relayout_rewrite.c new file mode 100644 index 0000000000000000000000000000000000000000..aca8400ca15b636f6dfaeabe920751b6d00de9cf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/semi_relayout_rewrite.c @@ -0,0 +1,86 @@ +// Check simplify rewrite chance for semi-relayout +/* { dg-do compile } */ + +#include +#include + +typedef struct node node_t; +typedef struct node *node_p; + +typedef struct arc arc_t; +typedef struct arc *arc_p; + +typedef struct network +{ + arc_p arcs; + arc_p sorted_arcs; + int x; + node_p nodes; + node_p stop_nodes; +} network_t; + +struct node +{ + int64_t potential; + int orientation; + node_p child; + node_p pred; + node_p sibling; + node_p sibling_prev; + arc_p basic_arc; + arc_p firstout; + arc_p firstin; + arc_p arc_tmp; + int64_t flow; + int64_t depth; + int number; + int time; +}; + +struct arc +{ + int id; + int64_t cost; + node_p tail; + node_p head; + short ident; + arc_p nextout; + arc_p nextin; + int64_t flow; + int64_t org_cost; + network_t* net_add; +}; + + +const int MAX = 100; +network_t* net; +node_p node; +arc_p arc; + +int +main () +{ + net = (network_t*) calloc (1, sizeof(network_t)); + net->arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->sorted_arcs = (arc_p) calloc (MAX, sizeof (arc_t)); + net->nodes = (node_p) calloc (MAX, sizeof (node_t)); + net->arcs->id = 100; + + node = net->nodes; + arc = net->arcs; + + for (unsigned i = 0; i < MAX; i++) + { + arc->head = node; + arc->head->child = node; + node->potential = i + 1; + arc->cost = arc->head->potential; + arc->tail = node->sibling; + node = node + 1; + arc = arc + 1; + } + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform in semi-relayout is 1" "struct_reorg" } } */ \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_address_of_field.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_address_of_field.c new file mode 100644 index 0000000000000000000000000000000000000000..9d58edab80a1ab7482ecd96ace02fa9ad30b57b9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_address_of_field.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ + +static struct S { + int *p1; + int *p2; +} s; + +typedef __UINTPTR_TYPE__ uintptr_t; + +int +foo () +{ + int i = 1; + int j = 2; + struct S s; + int **p; + s.p1 = &i; + s.p2 = &j; + p = &s.p1; + uintptr_t pi = (uintptr_t) p; + pi = pi + sizeof (int *); + p = (int **)pi; + **p = 3; + return j; +} + +int +main () +{ + if (foo () != 3) + { + __builtin_abort (); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "struct S has escaped: \"Type escapes via taking the address of field\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_convert_mem.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_convert_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..a99ee0de48429404d55247d572777321b7d009d3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_convert_mem.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +struct T1 { + long var1; + int var2; +}; + +struct T2 { + long var1; + int var2; +}; + +void test (void*); + +__attribute__((used)) void +foo (struct T2 *t2) +{ + struct T1* t1 = (void *)(&t2[1]); + void* data = (void *)(&t1[1]); + + test(data); + return; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_maxmin_expr.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_maxmin_expr.c new file mode 100644 index 0000000000000000000000000000000000000000..fb135ef0bb5ccc12fde41eeb59c3784aef79d05b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_maxmin_expr.c @@ -0,0 +1,25 @@ +// { dg-do compile } + +#include + +struct S { + unsigned long a; + unsigned long b; +}; + +struct S* s; +struct S* t = (struct S*) 1000; + +int +main () +{ + s = (struct S*) calloc (1000, sizeof (struct S)); + s = s > t ? s : t; + if (s == 0) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_pointer_and.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_pointer_and.c new file mode 100644 index 0000000000000000000000000000000000000000..9a4b10d9aef61d9a651b203876095294891e69a8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_pointer_and.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +struct test {long val; struct test* next; }; + +unsigned long P_DATA; + +void func (struct test*); + +__attribute__((used)) static void +foo (struct test* pt) +{ + struct test t; + + t.next = (void *)((unsigned long)pt->next & P_DATA); + func(&t); + return; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_pointer_minus.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_pointer_minus.c new file mode 100644 index 0000000000000000000000000000000000000000..9a82da0d6e15d8440523691e7fdb9b8d6652c188 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/sr_pointer_minus.c @@ -0,0 +1,33 @@ +// { dg-do compile } + +#include + +typedef struct node node_t; +typedef struct node* node_p; + +struct node { + unsigned long a; + unsigned long b; +}; + +int max; +int x; + +node_p n; +node_p z; + +int +main () +{ + n = (node_p) calloc (max, sizeof (node_t)); + + node_p xp = &n[x]; + + if (xp - z == 10) + { + abort (); + } + return 0; +} + +/* { dg-final { scan-ipa-dump "struct node has escaped: \"Type escapes via a unhandled rewrite stmt\"" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct-reorg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct-reorg.exp new file mode 100644 index 0000000000000000000000000000000000000000..687f6609f9b51af212ab1dbdc978aada5febe38c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct-reorg.exp @@ -0,0 +1,66 @@ +# Copyright (C) 1997-2023 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 +# . + +load_lib gcc-dg.exp +load_lib torture-options.exp + +# Initialize `dg'. +dg-init +torture-init + +set STRUCT_REORG_TORTURE_OPTIONS [list \ + { -O3 } \ + { -Ofast } ] + +set-torture-options $STRUCT_REORG_TORTURE_OPTIONS {{}} + +# -fipa-struct-reorg +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/wo_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/w_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/struct_reorg*.cpp]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/sr_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/csr_*.c]] \ + "" "-fipa-struct-reorg -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-reorder-fields +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/rf_*.c]] \ + "" "-fipa-reorder-fields -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=3 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dfe*.c]] \ + "" "-fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program" +gcc-dg-runtest $srcdir/$subdir/struct_reorg-7.c \ + "" "-fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=4 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pc*.c]] \ + "" "-fipa-struct-reorg=4 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=5 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pc*.c]] \ + "" "-fipa-struct-reorg=5 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# -fipa-struct-reorg=6 +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/semi_relayout*.c]] \ + "" "-fipa-struct-reorg=6 -fdump-ipa-all -flto-partition=one -fwhole-program" + +# All done. +torture-finish +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-1.c new file mode 100644 index 0000000000000000000000000000000000000000..23444fe8b0de3ff8c48eae1589393417b2fc2608 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-1.c @@ -0,0 +1,30 @@ +// { dg-do compile } +// { dg-options "-O3 -flto-partition=one -fipa-struct-reorg -fdump-ipa-all -fwhole-program" } + +struct a +{ + int t, t1; +}; + +static struct a *b; + +void *xmalloc(int); + + +void f(void) +{ + b = xmalloc (sizeof(*b)); +} + +int g(void) +{ + return b->t; +} + +int main() +{ + f (); + return g (); +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-10.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-10.c new file mode 100644 index 0000000000000000000000000000000000000000..ec422f76f60841f5100711661d8b02c852c0322f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-10.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */ + +struct a { + int b; + char c; +}; +struct { + double d; + _Bool e; +} * f; +struct g { + struct a h; +} i; +long j; +void k(); +void l() { k(i); } +void k(struct a m) { + f->e = 0; + for (;;) + l(); +} +int main() { + for (; j; f = 0) { + struct g *n = 0; + char o = n->h.c; + } + l(); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-11.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-11.c new file mode 100644 index 0000000000000000000000000000000000000000..3e42aa84a3f801e2a94abbdd671abb5b06bfb292 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-11.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */ + +struct a { + int b; + double c; +}; +struct d { + struct a e; +}; +int f; +int main() { + _Bool g; + struct d **h = 0; + g = *h += f; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-12.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-12.c new file mode 100644 index 0000000000000000000000000000000000000000..d434f9fe0036335efbe1e9c33c36a7faeb6a615f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-12.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */ + +struct foo { + long element1; + long element2; +}; + +struct goo { + struct foo element_foo; +}; + +struct goo g1; + +void func () { + struct foo (*local)[] = 0; + long idx; + (g1).element_foo = (*local)[idx]; +} + +struct foo g2; +int main () { + func (); + g2 = g1.element_foo; + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-2.c new file mode 100644 index 0000000000000000000000000000000000000000..44babd35b04fcc1aa1afa55c5b24a29c65b72e2e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-2.c @@ -0,0 +1,29 @@ +// { dg-do run } + +#include + +struct a +{ + int t; + int t1; +}; + +__attribute__((noinline)) int f(int i, int j) +{ + struct a *t; + struct a t1 = {i, j}; + t = &t1; + auto int g(void) __attribute__((noinline)); + int g(void) + { + return t->t + t->t1; + } + return g(); +} + +int main() +{ + assert (f(1, 2) == 3); +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-3.c new file mode 100644 index 0000000000000000000000000000000000000000..2d1f95c99350b95d2d5e08a3fa533eec2f37fea7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-3.c @@ -0,0 +1,28 @@ +// { dg-do compile } +// { dg-options "-O3 -flto-partition=one -fipa-struct-reorg -fdump-ipa-all -fwhole-program" } + +#include +typedef struct { + long laststart_offset; + unsigned regnum; +} compile_stack_elt_t; +typedef struct { + compile_stack_elt_t *stack; + unsigned size; +} compile_stack_type; +__attribute__((noinline)) void f (const char *p, const char *pend, int c) +{ + compile_stack_type compile_stack; + while (p != pend) + if (c) + compile_stack.stack = realloc (compile_stack.stack, + (compile_stack.size << 1) + * sizeof (compile_stack_elt_t)); +} + +int main() +{ + f (NULL, NULL, 1); +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-4.c new file mode 100644 index 0000000000000000000000000000000000000000..e5a8a6c847fef2eecad98db5c3f29526f3c39cee --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-4.c @@ -0,0 +1,59 @@ +/* { dg-do run } */ + +extern void abort (void); + +struct S +{ + int b; + int *c; +}; +static int d, e; + +static struct S s; + +static int * +__attribute__((noinline, const)) +foo (void) +{ + return &s.b; +} + +int * +__attribute__((noinline)) +bar (int **f) +{ + s.c = &d; + *f = &e; + /* As nothing ever takes the address of any int * field in struct S, + the write to *f can't alias with the s.c field. */ + return s.c; +} + +int +__attribute__((noinline)) +baz (int *x) +{ + s.b = 1; + *x = 4; + /* Function foo takes address of an int field in struct S, + so *x can alias with the s.b field (and it does in this testcase). */ + return s.b; +} + +int +__attribute__((noinline)) +t (void) +{ + int *f = (int *) 0; + return 10 * (bar (&f) != &d) + baz (foo ()); +} + +int +main (void) +{ + if (t () != 4) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-5.c new file mode 100644 index 0000000000000000000000000000000000000000..273baa9a368c43c70bb280e68aaecc44dd9e960a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-5.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-flto -fno-use-linker-plugin" } */ + +struct D +{ + int n; + int c [8]; +}; + +struct A +{ + int i; + char *p; +}; + +struct B +{ + struct A *a; + struct D *d; +}; + +int dtInsert1 (struct B *b) +{ + struct A a = { 0, 0 }; + struct D *d; + b->a = &a; + d = b->d; + &d->c [d->n]; + return 0; +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-6.c new file mode 100644 index 0000000000000000000000000000000000000000..455f9b501d66c68780db79ae563963db093f3216 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-6.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-flto -fno-use-linker-plugin" } */ + +typedef struct basic_block_def *basic_block; +typedef struct gimple_seq_node_d *gimple_seq_node; +typedef struct gimple_seq_d *gimple_seq; +typedef struct +{ + gimple_seq_node ptr; + gimple_seq seq; + basic_block bb; +} gimple_stmt_iterator; +typedef void *gimple; +extern void exit(int); +struct gimple_seq_node_d +{ + gimple stmt; + struct gimple_seq_node_d *next; +}; +struct gimple_seq_d +{ +}; +static __inline__ gimple_stmt_iterator +gsi_start (gimple_seq seq) +{ + gimple_stmt_iterator i; + i.seq = seq; + return i; +} +static __inline__ unsigned char +gsi_end_p (gimple_stmt_iterator i) +{ + return i.ptr == ((void *)0); +} +static __inline__ void +gsi_next (gimple_stmt_iterator *i) +{ + i->ptr = i->ptr->next; +} +static __inline__ gimple +gsi_stmt (gimple_stmt_iterator i) +{ + return i.ptr->stmt; +} +void +c_warn_unused_result (gimple_seq seq) +{ + gimple_stmt_iterator i; + for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i)) + { + gimple g = gsi_stmt (i); + if (!g) exit(0); + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-7.c new file mode 100644 index 0000000000000000000000000000000000000000..afc0bd86ca5aba475bbe1de806f3ce06cc7228a5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-7.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +#include +#include + +struct gki_elem { + char *key; + int idx; +}; + +typedef struct { + struct gki_elem *table; + + int primelevel; + int nhash; + int nkeys; +} GKI; + +void * +sre_malloc(size_t size) +{ + void *ptr = malloc (size); + return ptr; +} + +__attribute__((noinline)) int +GKIStoreKey(GKI *hash) +{ + hash->table = sre_malloc(sizeof(struct gki_elem)); +} + +int +main () +{ + GKI *hash = malloc (sizeof(GKI)); + GKIStoreKey(hash); + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-8.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-8.c new file mode 100644 index 0000000000000000000000000000000000000000..9bcfaf3681b16e913c367f0349cf69c02c5da9e2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-8.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +#include +#include +#include + +typedef struct { + unsigned char blue; + unsigned char green; +} Pixel; + +typedef struct { + unsigned short colormaplength; + Pixel *colormapdata; +} TargaImage; + +TargaImage *img; + +int main() { + img = (TargaImage *) malloc( sizeof(TargaImage) ); + if (img->colormaplength > 0) { + img->colormapdata = (Pixel *) malloc(sizeof(Pixel) * img->colormaplength); + memset(img->colormapdata, 0, (sizeof(Pixel) * img->colormaplength) ); + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-9.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-9.c new file mode 100644 index 0000000000000000000000000000000000000000..052f4e3bdc180d0c241cfae8d5f3f2a065e040ca --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/struct_reorg-9.c @@ -0,0 +1,54 @@ +/* { dg-do run } */ + +extern void abort(void); + +struct packed_ushort { + unsigned short ucs; +} __attribute__((packed)); + +struct source { + int pos, length; +}; + +static int flag; + +static void __attribute__((noinline)) fetch(struct source *p) +{ + p->length = 128; +} + +static struct packed_ushort __attribute__((noinline)) next(struct source *p) +{ + struct packed_ushort rv; + + if (p->pos >= p->length) { + if (flag) { + flag = 0; + fetch(p); + return next(p); + } + flag = 1; + rv.ucs = 0xffff; + return rv; + } + rv.ucs = 0; + return rv; +} + +int main(void) +{ + struct source s; + int i; + + s.pos = 0; + s.length = 0; + flag = 0; + + for (i = 0; i < 16; i++) { + struct packed_ushort rv = next(&s); + if ((i == 0 && rv.ucs != 0xffff) + || (i > 0 && rv.ucs != 0)) + abort(); + } + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_global_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_global_array.c new file mode 100644 index 0000000000000000000000000000000000000000..733413a94d01d133eb280c256f479be8c93c15d5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_global_array.c @@ -0,0 +1,29 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#define N 1000 +str_t A[N]; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_global_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_global_var.c new file mode 100644 index 0000000000000000000000000000000000000000..0ef686e74e736eb4152ac2f0ec85483d8d0600ba --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_global_var.c @@ -0,0 +1,42 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +str_t *p; + +int +main () +{ + int i, sum; + + p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].a = p[i].b + 1; + + for (i = 0; i < N; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_local_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_local_array.c new file mode 100644 index 0000000000000000000000000000000000000000..23a53be5386214264383182ac3dcfbfcb474beab --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_local_array.c @@ -0,0 +1,37 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i; + str_t A[N]; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_local_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_local_var.c new file mode 100644 index 0000000000000000000000000000000000000000..0cbb172f269d6c748479d950b00611d6f53e7cf5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_local_var.c @@ -0,0 +1,40 @@ +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i, sum; + + str_t * p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].a = p[i].b + 1; + + for (i = 0; i < N; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_single_str_global.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_single_str_global.c new file mode 100644 index 0000000000000000000000000000000000000000..f900b1349ac9ea9148b7d9c4c684131ea8fbb416 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_prof_single_str_global.c @@ -0,0 +1,31 @@ +#include +typedef struct +{ + int a; + int b; +}str_t; + +#define N 3 + +str_t str; + +int +main () +{ + int i; + int res = 1<<(1< + +typedef struct +{ + int a; + float b; +}str_t1; + +typedef struct +{ + int c; + float d; +}str_t2; + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +str_t1 *p1; +str_t2 *p2; +int num; + +void +foo (void) +{ + int i; + + for (i=0; i < num; i++) + p2[i].c = 2; +} + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + p1 = malloc (num * sizeof (str_t1)); + p2 = malloc (num * sizeof (str_t2)); + + if (p1 == NULL || p2 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + foo (); + + for (i = 0; i < num; i++) + if (p1[i].a != 1 || p2[i].c != 2) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_ratio_cold_str.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_ratio_cold_str.c new file mode 100644 index 0000000000000000000000000000000000000000..dcc545964fd7116206fe21ba4bef3ad72b056269 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/w_ratio_cold_str.c @@ -0,0 +1,43 @@ +#include +typedef struct +{ + int a; + int b; +}str_t1; + +typedef struct +{ + float a; + float b; +}str_t2; + +#define N1 1000 +#define N2 100 +str_t1 A1[N1]; +str_t2 A2[N2]; + +int +main () +{ + int i; + + for (i = 0; i < N1; i++) + A1[i].a = 0; + + for (i = 0; i < N2; i++) + A2[i].a = 0; + + for (i = 0; i < N1; i++) + if (A1[i].a != 0) + abort (); + + for (i = 0; i < N2; i++) + if (A2[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* Arrays are not handled. */ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_array_field.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_array_field.c new file mode 100644 index 0000000000000000000000000000000000000000..6d6375fc1ea41657d3bc8937c30957c7a3a79b4e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_array_field.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct basic +{ + int a; + int b[10]; +} type_struct; + +type_struct *str1; + +int main() +{ + int i; + + str1 = malloc (10 * sizeof (type_struct)); + + for (i=0; i<=9; i++) + str1[i].a = str1[i].b[0]; + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_array_through_pointer.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_array_through_pointer.c new file mode 100644 index 0000000000000000000000000000000000000000..9d32134089f859f9fe72894d486ba8ef0486666a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_array_through_pointer.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i; + str_t A[N]; + str_t *p = A; + + for (i = 0; i < N; i++) + p[i].a = 0; + + for (i = 0; i < N; i++) + if (p[i].a != 0) + abort (); + + return 0; +} + +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_double_malloc.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_double_malloc.c new file mode 100644 index 0000000000000000000000000000000000000000..d79992a5302e64c677212bd79f7d9451bd4c3ba7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_double_malloc.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include + +typedef struct test_struct +{ + int a; + int b; +} type_struct; + +typedef type_struct **struct_pointer2; + +struct_pointer2 str1; + +int main() +{ + int i, j; + + str1 = malloc (2 * sizeof (type_struct *)); + + for (i = 0; i <= 1; i++) + str1[i] = malloc (2 * sizeof (type_struct)); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_empty_str.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_empty_str.c new file mode 100644 index 0000000000000000000000000000000000000000..ee9b0d76595817903ba6695f2b029ffa51a44ba8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_empty_str.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include + +struct S { int a; struct V *b; }; +typedef struct { int c; } T; +typedef struct { int d; int e; } U; + +void * +fn (void *x) +{ + return x; +} + +int +foo (struct S *s) +{ + T x; + + T y = *(T *)fn (&x); + return y.c; +} + +int +bar (struct S *s) +{ + U x; + + U y = *(U *)fn (&x); + return y.d + s->a; +} + +int +main () +{ + struct S s; + + foo(&s) + bar (&s); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_arg_to_local.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_arg_to_local.c new file mode 100644 index 0000000000000000000000000000000000000000..9ebb2b4cc969632eb88ccc942208f46df22a27b4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_arg_to_local.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ + +#include +struct str +{ + int a; + float b; +}; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +foo (struct str * p_str) +{ + static int sum = 0; + + sum = sum + p_str->a; + return sum; +} + +int +main () +{ + int i, sum; + struct str * p = malloc (N * sizeof (struct str)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + sum = foo (p+i); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_replace_type.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_replace_type.c new file mode 100644 index 0000000000000000000000000000000000000000..fa8c66b9e92e3264258f9431140ace34bfc23057 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_replace_type.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ + +#include + +struct AngleDef +{ + double K; + double th0; +}; +typedef struct AngleDef angldef; + +struct bndangdihe +{ + int nbond; + int nangl; + int ndihe; +}; +typedef struct bndangdihe bah; + +struct ambprmtop +{ + double *AnglK; + double *AnglEq; + bah nBAH; + angldef *AParam; + char source[512]; + char eprulesource[512]; +}; +typedef struct ambprmtop prmtop; + +static void OrderBondParameters (prmtop *tp) +{ + int i; + tp->AParam = (angldef *)malloc (tp->nBAH.nangl * sizeof (angldef)); + for (i = 0; i < tp->nBAH.nangl; i++) + { + tp->AParam[i].K = tp->AnglK[i]; + tp->AParam[i].th0 = tp->AnglEq[i]; + } +} + +void main () +{ + prmtop *tp = (prmtop *)malloc (100 * sizeof (prmtop)); + OrderBondParameters (tp); +} + +/*---------------------------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_return-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_return-1.c new file mode 100644 index 0000000000000000000000000000000000000000..d0dce8b536f182b6595368c499f69e1528845d40 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_return-1.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-ipa-sra" } */ + +#include + +struct A { + int d; + int d1; +}; + +struct A a; + +struct A *foo () __attribute__((noinline)); +struct A *foo () +{ + a.d = 5; + return &a; +} + +int +main () +{ + a.d = 0; + foo (); + + if (a.d != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped. .Type escapes via a return" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_return.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_return.c new file mode 100644 index 0000000000000000000000000000000000000000..71167182d50a919da1cce2ff306b493fe3de038d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_return.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-ipa-sra" } */ + +#include + +struct A { + int d; +}; + +struct A a; + +struct A foo () __attribute__((noinline)); +struct A foo () +{ + a.d = 5; + return a; +} + +int +main () +{ + a.d = 0; + foo (); + + if (a.d != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped: \"Type escapes via a return" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_str_init.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_str_init.c new file mode 100644 index 0000000000000000000000000000000000000000..74fa11f3940cabafe7ffdbeec46f54cb883ea499 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_str_init.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + int b; +}str_t; + +#define N 2 + +str_t A[2] = {{1,1},{2,2}}; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + A[i].b = A[i].a; + + for (i = 0; i < N; i++) + if (A[i].b != A[i].a) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_array.c new file mode 100644 index 0000000000000000000000000000000000000000..60d2466e1daffc8364b38b2ff31d7a68ec60f4a7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_array.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#define N 1000 + +typedef struct +{ + str_t A[N]; + int c; +}str_with_substr_t; + +str_with_substr_t a; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + a.A[i].b = 0; + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_pointer.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_pointer.c new file mode 100644 index 0000000000000000000000000000000000000000..baf617816d6cec401e3e42d07d0841a58b7a8437 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_pointer.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +typedef struct +{ + str_t * sub_str; + int c; +}str_with_substr_t; + +int foo; + +int +main (void) +{ + int i; + str_with_substr_t A[N]; + str_t a[N]; + + for (i=0; i < N; i++) + A[i].sub_str = &(a[i]); + + for (i=0; i < N; i++) + A[i].sub_str->a = 5; + + foo = A[56].sub_str->a; + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped...Type is used in an array" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_value.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_value.c new file mode 100644 index 0000000000000000000000000000000000000000..33fce3b235048a331ea9e70a62cc124e780c958e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_escape_substr_value.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + + +typedef struct +{ + str_t sub_str; + int c; +}str_with_substr_t; + +int +main () +{ + int i; + str_with_substr_t A[N]; + + for (i = 0; i < N; i++) + A[i].sub_str.a = 5; + + for (i = 0; i < N; i++) + if (A[i].sub_str.a != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped...Type is used in an array" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_global_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_global_array.c new file mode 100644 index 0000000000000000000000000000000000000000..1c5a3aa15e5fee1e954efd0c5dec835e5dd69f55 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_global_array.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#define N 1000 +str_t A[N]; + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_global_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_global_var.c new file mode 100644 index 0000000000000000000000000000000000000000..a0d1467fe9cc305b57a5eb87c7103b8ad4048b95 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_global_var.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +str_t *p; + +int +main () +{ + int i, sum; + + p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].b = p[i].a + 1; + + for (i = 0; i < N; i++) + if (p[i].b != p[i].a + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_local_array.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_local_array.c new file mode 100644 index 0000000000000000000000000000000000000000..6c24e1c8b054e552decde5f8ad44d67ff6e24b96 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_local_array.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i; + str_t A[N]; + + for (i = 0; i < N; i++) + { + A[i].a = 0; + } + + for (i = 0; i < N; i++) + if (A[i].a != 0) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" { xfail *-*-* } } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_local_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_local_var.c new file mode 100644 index 0000000000000000000000000000000000000000..8f2f8143f65b35f1615bbd82e5c044a1d7153158 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_local_var.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i, sum; + + str_t * p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].b = i; + + for (i = 0; i < N; i++) + p[i].b = p[i].a + 1; + + for (i = 0; i < N; i++) + if (p[i].b != p[i].a + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_malloc_size_var-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_malloc_size_var-1.c new file mode 100644 index 0000000000000000000000000000000000000000..98bf01a6d07762795e054b4cd5d89d0b394838da --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_malloc_size_var-1.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + long i, num; + + num = rand(); + num = num > N ? N : num; + str_t * p = malloc (num * sizeof (str_t)); + + if (p == 0) + return 0; + + for (i = 1; i <= num; i++) + p[i-1].b = i; + + for (i = 1; i <= num; i++) + p[i-1].a = p[i-1].b + 1; + + for (i = 0; i < num; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_malloc_size_var.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_malloc_size_var.c new file mode 100644 index 0000000000000000000000000000000000000000..66b0f967c80a78b18cf074eb69fc8ff74786b2aa --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_malloc_size_var.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 8000 +#define N 1000 +#else +#define N (STACK_SIZE/8) +#endif +#else +#define N 1000 +#endif + +int +main () +{ + int i, num; + + num = rand(); + num = num > N ? N : num; + str_t * p = malloc (num * sizeof (str_t)); + + if (p == 0) + return 0; + + for (i = 0; i < num; i++) + p[i].b = i; + + for (i = 0; i < num; i++) + p[i].a = p[i].b + 1; + + for (i = 0; i < num; i++) + if (p[i].a != p[i].b + 1) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 1" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_mult_field_peeling.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_mult_field_peeling.c new file mode 100644 index 0000000000000000000000000000000000000000..d28bcfb023741ac1378c55f2e431fe291db7c7b5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_mult_field_peeling.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + float b; + int c; + float d; +}str_t; + +#ifdef STACK_SIZE +#if STACK_SIZE > 1600 +#define N 100 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 100 +#endif + +int +main () +{ + int i; + str_t *p = malloc (N * sizeof (str_t)); + if (p == NULL) + return 0; + for (i = 0; i < N; i++) + p[i].a = 5; + + for (i = 0; i < N; i++) + if (p[i].a != 5) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* Two more fields structure is not splitted. */ +/* { dg-final { scan-ipa-dump "No structures to transform." "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_single_str_global.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_single_str_global.c new file mode 100644 index 0000000000000000000000000000000000000000..37a6a43a8595f5afcde51750d9e67876eb79d4a6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_single_str_global.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +typedef struct +{ + int a; + int b; +}str_t; + +#define N 3 + +str_t str; + +int +main () +{ + int i; + int res = 1<<(1< +typedef struct +{ + int a; + int b; +}str_t; + +#define N 3 + +int +main () +{ + int i; + int res = 1<<(1< +typedef struct +{ + int a; + int *b; +}str_t; + +#define N 3 + +str_t *p; + +int +main () +{ + str_t str; + int i; + int res = 1 << (1 << N); + p = &str; + str.a = 2; + + p->b = &(p->a); + + for (i=0; i < N; i++) + p->a = *(p->b)*(*(p->b)); + + if (p->a != res) + abort (); + + /* POSIX ignores all but the 8 low-order bits, but other + environments may not. */ + return (p->a & 255); +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "has escaped...Type escapes a cast to a different" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_two_strs.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_two_strs.c new file mode 100644 index 0000000000000000000000000000000000000000..cba92e99555cbaadf2f57e8b9a59d36b5751b1cf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/struct/wo_prof_two_strs.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include + +typedef struct +{ + int a; + float b; +}str_t1; + +typedef struct +{ + int c; + float d; +}str_t2; + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +str_t1 *p1; +str_t2 *p2; +int num; + +void +foo (void) +{ + int i; + + for (i=0; i < num; i++) + p2[i].c = 2; +} + +int +main () +{ + int i, r; + + r = rand (); + num = r > N ? N : r; + p1 = malloc (num * sizeof (str_t1)); + p2 = malloc (num * sizeof (str_t2)); + + if (p1 == NULL || p2 == NULL) + return 0; + + for (i = 0; i < num; i++) + p1[i].a = 1; + + foo (); + + for (i = 0; i < num; i++) + if (p1[i].a != 1 || p2[i].c != 2) + abort (); + + return 0; +} + +/*--------------------------------------------------------------------------*/ +/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "struct_reorg" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-1.c new file mode 100644 index 0000000000000000000000000000000000000000..e18ef5ec1a64242b0b9705687002e4b84d3ba802 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (++len != len_limit) + if (pb[len] != cur[len]) + break; + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 1 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-2.c new file mode 100644 index 0000000000000000000000000000000000000000..f4b20b43c4076c99575f4c1b11d8756728a6b7f4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-2.c @@ -0,0 +1,90 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define EMPTY_HASH_VALUE 0 +#define my_min(x, y) ((x) < (y) ? (x) : (y)) +#define true 1 + +typedef struct { + uint32_t len; + uint32_t dist; +} lzma_match; + + +lzma_match * +func ( + const uint32_t len_limit, + const uint32_t pos, + const uint8_t *const cur, + uint32_t cur_match, + uint32_t depth, + uint32_t *const son, + const uint32_t cyclic_pos, + const uint32_t cyclic_size, + lzma_match *matches, + uint32_t len_best) +{ + uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; + uint32_t *ptr1 = son + (cyclic_pos << 1); + + uint32_t len0 = 0; + uint32_t len1 = 0; + + while (true) + { + const uint32_t delta = pos - cur_match; + if (depth-- == 0 || delta >= cyclic_size) + { + *ptr0 = EMPTY_HASH_VALUE; + *ptr1 = EMPTY_HASH_VALUE; + return matches; + } + + uint32_t *const pair = son + ((cyclic_pos - delta + (delta > cyclic_pos ? cyclic_size : 0)) << 1); + + const uint8_t *const pb = cur -delta; + uint32_t len = my_min(len0, len1); + + if (pb[len] == cur[len]) + { + while (++len != len_limit) + if (pb[len] != cur[len]) + break; + + if (len_best < len) + { + len_best = len; + matches->len = len; + matches->dist = delta - 1; + ++matches; + + if (len == len_limit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return matches; + } + } + } + + if (pb[len] < cur[len]) + { + *ptr1 = cur_match; + ptr1 = pair + 1; + cur_match = *ptr1; + len1 = len; + } + else + { + *ptr0 = cur_match; + ptr0 = pair; + cur_match = *ptr0; + len0 = len; + } + } +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 1 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-3.c new file mode 100644 index 0000000000000000000000000000000000000000..86f5e7a1e68c405d7bcf9d51b20b8d4bc24b1d6c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-3.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len != len_limit) + { + if (pb[len] != cur[len]) + break; + len = len + 1; + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 1 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-4.c new file mode 100644 index 0000000000000000000000000000000000000000..d665586997039eb7264b5079d3972daf3746db9f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-4.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len != len_limit) + { + if (pb[len] != cur[len]) + break; + len = len + 2; + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-5.c new file mode 100644 index 0000000000000000000000000000000000000000..e3e12bca4153090b73ed5d47cc3f92d7e08222c8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-5.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (++len != len_limit) + if (pb[len] != cur[len-1]) + break; + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-6.c new file mode 100644 index 0000000000000000000000000000000000000000..b8500735eda725791db82397446e6385776990f4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-6.c @@ -0,0 +1,19 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len++ != len_limit) + if (pb[len] != cur[len]) + break; + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-7.c new file mode 100644 index 0000000000000000000000000000000000000000..977bf56859e6abd3002d15dda113d04942c6b45e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-7.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (len != len_limit) + { + len = len + 1; + if (pb[len] != cur[len]) + break; + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-8.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-8.c new file mode 100644 index 0000000000000000000000000000000000000000..386784c92c6a69661a9430c819b5f78f2fa7ea2f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/awiden-compare-8.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target {{ aarch64*-*-linux* } && lp64 } } } */ +/* { dg-options "-O3 -mabi=lp64 -farray-widen-compare -fdump-tree-awiden_compare-details" } */ + +#include +#include + +#define my_min(x, y) ((x) < (y) ? (x) : (y)) + +uint32_t +func (uint32_t len0, uint32_t len1, const uint32_t len_limit, const uint8_t *const pb, const uint8_t *const cur) +{ + uint32_t len = my_min(len0, len1); + while (++len != len_limit) + { + if (pb[len] != cur[len]) + { + len = len - 1; + break; + } + } + return len; +} + +/* { dg-final { scan-tree-dump-times "loop form is success" 0 "awiden_compare"} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/tree-ssa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/tree-ssa.exp new file mode 100644 index 0000000000000000000000000000000000000000..e5b524fa4500a5555b72cc8e9f39a0435700402f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/tree-ssa/tree-ssa.exp @@ -0,0 +1,36 @@ +# Copyright (C) 1997-2022 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/uaddsub.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/uaddsub.c new file mode 100644 index 0000000000000000000000000000000000000000..96c26d308b4f999c74836948fa7a531bf457d019 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.dg/uaddsub.c @@ -0,0 +1,143 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fuaddsub-overflow-match-all -fdump-tree-optimized" } */ +#include + +typedef unsigned __int128 uint128_t; +typedef struct uint256_t +{ + uint128_t lo; + uint128_t hi; +} uint256_t; + +uint16_t add16 (uint8_t a, uint8_t b) +{ + uint8_t tmp = a + b; + uint8_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint16_t res = overflow; + res <<= 8; + res += tmp; + return res; +} + +uint32_t add32 (uint16_t a, uint16_t b) +{ + uint16_t tmp = a + b; + uint16_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint32_t res = overflow; + res <<= 16; + res += tmp; + return res; +} + +uint64_t add64 (uint32_t a, uint32_t b) +{ + uint32_t tmp = a + b; + uint32_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint64_t res = overflow; + res <<= 32; + res += tmp; + return res; +} + +uint128_t add128 (uint64_t a, uint64_t b) +{ + uint64_t tmp = a + b; + uint64_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint128_t res = overflow; + res <<= 64; + res += tmp; + return res; +} + +uint256_t add256 (uint128_t a, uint128_t b) +{ + uint128_t tmp = a + b; + uint128_t overflow = 0; + if (tmp < a) + overflow = 1; + + uint256_t res; + res.hi = overflow; + res.lo = tmp; + return res; +} + +uint16_t sub16 (uint8_t a, uint8_t b) +{ + uint8_t tmp = a - b; + uint8_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint16_t res = overflow; + res <<= 8; + res += tmp; + return res; +} + +uint32_t sub32 (uint16_t a, uint16_t b) +{ + uint16_t tmp = a - b; + uint16_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint32_t res = overflow; + res <<= 16; + res += tmp; + return res; +} + +uint64_t sub64 (uint32_t a, uint32_t b) +{ + uint32_t tmp = a - b; + uint32_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint64_t res = overflow; + res <<= 32; + res += tmp; + return res; +} + +uint128_t sub128 (uint64_t a, uint64_t b) +{ + uint64_t tmp = a - b; + uint64_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint128_t res = overflow; + res <<= 64; + res += tmp; + return res; +} + +uint256_t sub256 (uint128_t a, uint128_t b) +{ + uint128_t tmp = a - b; + uint128_t overflow = 0; + if (tmp > a) + overflow = -1; + + uint256_t res; + res.hi = overflow; + res.lo = tmp; + return res; +} + +/* { dg-final { scan-tree-dump-times "= .ADD_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "= .SUB_OVERFLOW \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\(D\\)\\)" 5 "optimized" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aarch64.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aarch64.exp new file mode 100644 index 0000000000000000000000000000000000000000..0a2732a307530d44963cdeeffd3e74ff0450ef6f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aarch64.exp @@ -0,0 +1,45 @@ +# Specific regression driver for AArch64. +# Copyright (C) 2009-2022 Free Software Foundation, Inc. +# Contributed by ARM Ltd. +# +# This file is part of GCC. +# +# GCC 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, or (at your option) +# any later version. +# +# GCC 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 +# . */ + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an AArch64 target. +if {![istarget aarch64*-*-*] } then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aes-decrypt.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aes-decrypt.c new file mode 100644 index 0000000000000000000000000000000000000000..966ec553212ccc5bad889fedd5ff6be6e1b69158 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aes-decrypt.c @@ -0,0 +1,478 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline --save-temps -fcrypto-accel-aes -march=armv8.2-a+lse+crypto" } */ + +#include +#include +#include +#include +#include + +typedef uint8_t u8; +typedef uint32_t u32; + +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; + +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; + +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; + +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; + +static const u8 Td4[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; + +#define GETU32(pt) \ + ( \ + ((u32)(pt)[0] << 24) \ + ^ ((u32)(pt)[1] << 16) \ + ^ ((u32)(pt)[2] << 8) \ + ^ ((u32)(pt)[3]) \ + ) + +#define PUTU32(ct, st) \ + { \ + (ct)[0] = (u8)((st) >> 24); \ + (ct)[1] = (u8)((st) >> 16); \ + (ct)[2] = (u8)((st) >> 8); \ + (ct)[3] = (u8)(st); \ + } + +void +aes_decrypt (const unsigned char *in, unsigned char *out, + const u32 *rk, int nr) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + int r = nr >> 1; + + s0 = GETU32 (in ) ^ rk[0]; + s1 = GETU32 (in + 4) ^ rk[1]; + s2 = GETU32 (in + 8) ^ rk[2]; + s3 = GETU32 (in + 12) ^ rk[3]; + + for (;;) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]; + s1 = + Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]; + s2 = + Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]; + s3 = + Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]; + } + + s0 = + ((u32)Td4[(t0 >> 24) ] << 24) ^ + ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t2 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t1 ) & 0xff]) ^ + rk[0]; + PUTU32 (out , s0); + + s1 = + ((u32)Td4[(t1 >> 24) ] << 24) ^ + ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t3 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t2 ) & 0xff]) ^ + rk[1]; + PUTU32 (out + 4, s1); + + s2 = + ((u32)Td4[(t2 >> 24) ] << 24) ^ + ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t0 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t3 ) & 0xff]) ^ + rk[2]; + PUTU32 (out + 8, s2); + + s3 = + ((u32)Td4[(t3 >> 24) ] << 24) ^ + ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t1 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t0 ) & 0xff]) ^ + rk[3]; + PUTU32 (out + 12, s3); +} + +int main () +{ + const u8 input[16] = { 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, + 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 }; + + const u8 expected[16] = { 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, + 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 }; + + const u8 key[] = { 0xa8, 0xf9, 0x14, 0xd0, 0x89, 0x25, 0xee, 0xc9, + 0xc8, 0x0c, 0x3f, 0xe1, 0xa6, 0x0c, 0x63, 0xb6, + 0x63, 0x5a, 0x7b, 0x0c, 0xfe, 0xea, 0x19, 0x13, + 0x90, 0x88, 0x39, 0xb0, 0xb4, 0xfb, 0x4c, 0x66, + 0x5a, 0x92, 0x7d, 0xdf, 0x9d, 0xb0, 0x62, 0x1f, + 0x6e, 0x62, 0x20, 0xa3, 0x24, 0x73, 0x75, 0xd6, + 0x47, 0x76, 0xc0, 0x12, 0xc7, 0x22, 0x1f, 0xc0, + 0xf3, 0xd2, 0x42, 0xbc, 0x4a, 0x11, 0x55, 0x75, + 0x76, 0xd8, 0xfc, 0x6e, 0x80, 0x54, 0xdf, 0xd2, + 0x34, 0xf0, 0x5d, 0x7c, 0xb9, 0xc3, 0x17, 0xc9, + 0xfc, 0x0a, 0xa3, 0x6e, 0xf6, 0x8c, 0x23, 0xbc, + 0xb4, 0xa4, 0x82, 0xae, 0x8d, 0x33, 0x4a, 0xb5, + 0x13, 0x44, 0x88, 0x90, 0x0a, 0x86, 0x80, 0xd2, + 0x42, 0x28, 0xa1, 0x12, 0x39, 0x97, 0xc8, 0x1b, + 0xf7, 0x13, 0x1f, 0x7c, 0x19, 0xc2, 0x08, 0x42, + 0x48, 0xae, 0x21, 0xc0, 0x7b, 0xbf, 0x69, 0x09, + 0xeb, 0x05, 0x75, 0xcc, 0xee, 0xd1, 0x17, 0x3e, + 0x51, 0x6c, 0x29, 0x82, 0x33, 0x11, 0x48, 0xc9, + 0xa7, 0x08, 0x37, 0x2b, 0x05, 0xd4, 0x62, 0xf2, + 0xbf, 0xbd, 0x3e, 0xbc, 0x62, 0x7d, 0x61, 0x4b, + 0x16, 0x15, 0x7e, 0x2b, 0xa6, 0xd2, 0xae, 0x28, + 0x88, 0x15, 0xf7, 0xab, 0x3c, 0x4f, 0xcf, 0x09 }; + + u8 output[16] = { 0 }; + + aes_decrypt (input, output, (u32*) key, 10); + + if (memcmp (output, expected, 16) != 0) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler "rev32" } } */ +/* { dg-final { scan-assembler "aesimc" } } */ +/* { dg-final { scan-assembler "aesd" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aes-encrypt.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aes-encrypt.c new file mode 100644 index 0000000000000000000000000000000000000000..e3f3c446f9484b4a9993d8decb43fdbc043ef66c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/aes-encrypt.c @@ -0,0 +1,443 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline --save-temps -fcrypto-accel-aes -march=armv8.2-a+lse+crypto" } */ + +#include +#include +#include +#include +#include + +typedef uint8_t u8; +typedef uint32_t u32; + +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; + +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; + +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; + +static const u32 Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; + +#define GETU32(pt) \ + ( \ + ((u32)(pt)[0] << 24) \ + ^ ((u32)(pt)[1] << 16) \ + ^ ((u32)(pt)[2] << 8) \ + ^ ((u32)(pt)[3]) \ + ) + +#define PUTU32(ct, st) \ + { \ + (ct)[0] = (u8)((st) >> 24); \ + (ct)[1] = (u8)((st) >> 16); \ + (ct)[2] = (u8)((st) >> 8); \ + (ct)[3] = (u8)(st); \ + } + +void +aes_encrypt (const unsigned char *in, unsigned char *out, + const u32 *rk, int nr) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; + + int r = nr >> 1; + + s0 = GETU32 (in ) ^ rk[0]; + s1 = GETU32 (in + 4) ^ rk[1]; + s2 = GETU32 (in + 8) ^ rk[2]; + s3 = GETU32 (in + 12) ^ rk[3]; + + for (;;) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) + break; + + s0 = + Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]; + s1 = + Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]; + s2 = + Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]; + s3 = + Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]; + } + + s0 = + (Te2[(t0 >> 24) ] & 0xff000000) ^ + (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32 (out , s0); + + s1 = + (Te2[(t1 >> 24) ] & 0xff000000) ^ + (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32 (out + 4, s1); + + s2 = + (Te2[(t2 >> 24) ] & 0xff000000) ^ + (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32 (out + 8, s2); + + s3 = + (Te2[(t3 >> 24) ] & 0xff000000) ^ + (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32 (out + 12, s3); +} + + +int main () +{ + const u8 input[16] = { 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, + 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 }; + + const u8 expected[16] = { 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, + 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 }; + + const u8 key[] = { 0x16, 0x15, 0x7e, 0x2b, 0xa6, 0xd2, 0xae, 0x28, + 0x88, 0x15, 0xf7, 0xab, 0x3c, 0x4f, 0xcf, 0x09, + 0x17, 0xfe, 0xfa, 0xa0, 0xb1, 0x2c, 0x54, 0x88, + 0x39, 0x39, 0xa3, 0x23, 0x05, 0x76, 0x6c, 0x2a, + 0xf2, 0x95, 0xc2, 0xf2, 0x43, 0xb9, 0x96, 0x7a, + 0x7a, 0x80, 0x35, 0x59, 0x7f, 0xf6, 0x59, 0x73, + 0x7d, 0x47, 0x80, 0x3d, 0x3e, 0xfe, 0x16, 0x47, + 0x44, 0x7e, 0x23, 0x1e, 0x3b, 0x88, 0x7a, 0x6d, + 0x41, 0xa5, 0x44, 0xef, 0x7f, 0x5b, 0x52, 0xa8, + 0x3b, 0x25, 0x71, 0xb6, 0x00, 0xad, 0x0b, 0xdb, + 0xf8, 0xc6, 0xd1, 0xd4, 0x87, 0x9d, 0x83, 0x7c, + 0xbc, 0xb8, 0xf2, 0xca, 0xbc, 0x15, 0xf9, 0x11, + 0x7a, 0xa3, 0x88, 0x6d, 0xfd, 0x3e, 0x0b, 0x11, + 0x41, 0x86, 0xf9, 0xdb, 0xfd, 0x93, 0x00, 0xca, + 0x0e, 0xf7, 0x54, 0x4e, 0xf3, 0xc9, 0x5f, 0x5f, + 0xb2, 0x4f, 0xa6, 0x84, 0x4f, 0xdc, 0xa6, 0x4e, + 0x21, 0x73, 0xd2, 0xea, 0xd2, 0xba, 0x8d, 0xb5, + 0x60, 0xf5, 0x2b, 0x31, 0x2f, 0x29, 0x8d, 0x7f, + 0xf3, 0x66, 0x77, 0xac, 0x21, 0xdc, 0xfa, 0x19, + 0x41, 0x29, 0xd1, 0x28, 0x6e, 0x00, 0x5c, 0x57, + 0xa8, 0xf9, 0x14, 0xd0, 0x89, 0x25, 0xee, 0xc9, + 0xc8, 0x0c, 0x3f, 0xe1, 0xa6, 0x0c, 0x63, 0xb6 }; + + u8 output[16] = { 0 }; + + aes_encrypt (input, output, (u32*) key, 10); + + if (memcmp (output, expected, 16) != 0) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler "rev32" } } */ +/* { dg-final { scan-assembler "aesmc" } } */ +/* { dg-final { scan-assembler "aese" } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/ccmp_3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/ccmp_3.c new file mode 100644 index 0000000000000000000000000000000000000000..b509ba81010f52c12cfa2dd343b02256a456146b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/ccmp_3.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O -fdump-rtl-expand-details -fccmp2" } */ + +int func (int a, int b, int c) +{ + while(1) + { + if(a-- == 0 || b >= c) + { + return 1; + } + } +} + +/* { dg-final { scan-assembler-times "\tccmp\t" 1} } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/sve/aarch64-sve.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/sve/aarch64-sve.exp new file mode 100644 index 0000000000000000000000000000000000000000..71dd6687c6b02d4879b84ed0885183c3d0edd78f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/sve/aarch64-sve.exp @@ -0,0 +1,55 @@ +# Specific regression driver for AArch64 SVE. +# Copyright (C) 2009-2022 Free Software Foundation, Inc. +# Contributed by ARM Ltd. +# +# This file is part of GCC. +# +# GCC 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, or (at your option) +# any later version. +# +# GCC 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 +# . */ + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't an AArch64 target. +if {![istarget aarch64*-*-*] } then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# Initialize `dg'. +dg-init + +if { [check_effective_target_aarch64_sve] } { + set sve_flags "" +} else { + set sve_flags "-march=armv8.2-a+sve" +} + +# Most of the code-quality tests are written for LP64. Just do the +# correctness tests for ILP32. +if { [check_effective_target_ilp32] } { + set pattern "*_run" +} else { + set pattern "*" +} + +aarch64-with-arch-dg-options $sve_flags { + # Main loop. + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/$pattern.\[cCS\]]] \ + "" $sve_flags +} + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/sve/var_stride_flexible_segment_len_1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/sve/var_stride_flexible_segment_len_1.c new file mode 100644 index 0000000000000000000000000000000000000000..894f075f3310f78d077368b325ee8d63d26b42e4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/aarch64/sve/var_stride_flexible_segment_len_1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize --param=vect-alias-flexible-segment-len=1" } */ + +#define TYPE int +#define SIZE 257 + +void __attribute__ ((weak)) +f (TYPE *x, TYPE *y, unsigned short n, long m __attribute__((unused))) +{ + for (int i = 0; i < SIZE; ++i) + x[i * n] += y[i * n]; +} + +/* { dg-final { scan-assembler {\tld1w\tz[0-9]+} } } */ +/* { dg-final { scan-assembler {\tst1w\tz[0-9]+} } } */ +/* { dg-final { scan-assembler {\tldr\tw[0-9]+} } } */ +/* { dg-final { scan-assembler {\tstr\tw[0-9]+} } } */ +/* Should use a WAR check that multiplies by (VF-2)*4 rather than + an overlap check that multiplies by (257-1)*4. */ +/* { dg-final { scan-assembler {\tcntb\t(x[0-9]+)\n.*\tsub\tx[0-9]+, \1, #8\n.*\tmul\tx[0-9]+,[^\n]*\1} } } */ +/* One range check and a check for n being zero. */ +/* { dg-final { scan-assembler-times {\t(?:cmp|tst)\t} 2 } } */ +/* { dg-final { scan-assembler-times {\tccmp\t} 1 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amx-helper.h b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amx-helper.h new file mode 100644 index 0000000000000000000000000000000000000000..6ed9f5eb30e3164c6e3c85f3d9ba1288e51adaa7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amx-helper.h @@ -0,0 +1,61 @@ +#ifndef AMX_HELPER_H_INCLUDED +#define AMX_HELPER_H_INCLUDED +#if defined(AMX_FP16) || defined(AMX_COMPLEX) +#include +#include +#endif +#include "amx-check.h" + +typedef union +{ + _Float16 f16; + uint16_t u; +} union16f_uw; + +#if defined(AMX_FP16) || defined(AMX_COMPLEX) +/* Transformation functions between fp16/float */ +static uint16_t make_f32_fp16 (float f) +{ + union16f_uw tmp; + __m128 b = _mm_set_ss (f); + __m128h a; + tmp.f16 = _mm_cvtsh_h (_mm_cvtss_sh (a, b)); + return tmp.u; +} + +static float make_fp16_f32 (uint16_t fp) +{ + union16f_uw tmp; + tmp.u = fp; + __m128h b = _mm_set_sh (tmp.f16); + __m128 a; + return _mm_cvtss_f32 (_mm_cvtsh_ss (a, b)); +} + +/* Init tile buffer with fp16 pairs */ +void init_fp16_max_tile_buffer (uint8_t* buf) +{ + int i, j; + uint16_t* ptr = (uint16_t *) buf; + + for (i = 0; i < 16; i++) + for (j = 0; j < 32; j++) + { + float f = 2.5f * i + 1.25f * j; + ptr[i * 32 + j] = make_f32_fp16 (f); + } +} + +/* Init tile fp16 pair buffer with zero */ +void init_fp16_max_tile_zero_buffer (uint8_t* buf) +{ + int i, j; + uint16_t* ptr = (uint16_t *) buf; + + for (i = 0; i < 16; i++) + for (j = 0; j < 32; j++) + ptr[i * 32 + j] = make_f32_fp16 (0.0f); +} +#endif + +#endif diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-asmatt-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-asmatt-1.c new file mode 100644 index 0000000000000000000000000000000000000000..b6745e34b8b8c95144d012af03d278df7eafc486 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-asmatt-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -mamx-complex" } */ +/* { dg-final { scan-assembler "tcmmimfp16ps\[ \\t]+\[^\n\]*%tmm3+\[^\n\]*%tmm2+\[^\n\]*%tmm1" } } */ +/* { dg-final { scan-assembler "tcmmrlfp16ps\[ \\t]+\[^\n\]*%tmm3+\[^\n\]*%tmm2+\[^\n\]*%tmm1" } } */ +#include + +#define TMM1 1 +#define TMM2 2 +#define TMM3 3 + +void TEST() +{ + _tile_cmmimfp16ps (TMM1, TMM2, TMM3); + _tile_cmmrlfp16ps (TMM1, TMM2, TMM3); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-asmintel-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-asmintel-1.c new file mode 100644 index 0000000000000000000000000000000000000000..305465e88607a731967e99aae532e10a00144505 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-asmintel-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-require-effective-target masm_intel } */ +/* { dg-options "-O2 -mamx-complex -masm=intel" } */ +/* { dg-final { scan-assembler "tcmmimfp16ps\[ \\t]+\[^\n\]*%tmm1+\[^\n\]*%tmm2+\[^\n\]*%tmm3" } } */ +/* { dg-final { scan-assembler "tcmmrlfp16ps\[ \\t]+\[^\n\]*%tmm1+\[^\n\]*%tmm2+\[^\n\]*%tmm3" } } */ +#include + +void TEST() +{ + _tile_cmmimfp16ps (1, 2, 3); + _tile_cmmrlfp16ps (1, 2, 3); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-cmmimfp16ps-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-cmmimfp16ps-2.c new file mode 100644 index 0000000000000000000000000000000000000000..6e3762c9f6f4059479e82fb00a88fc47a5eb8414 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-cmmimfp16ps-2.c @@ -0,0 +1,53 @@ +/* { dg-do run { target { ! ia32 } } } */ +/* { dg-require-effective-target amx_complex } */ +/* { dg-require-effective-target avx512fp16 } */ +/* { dg-options "-O2 -mamx-complex -mavx512fp16" } */ +#define AMX_COMPLEX +#define DO_TEST test_amx_complex_cmmimfp16ps +void test_amx_complex_cmmimfp16ps (); +#include "amx-helper.h" + +void calc_matrix_cmmimfp16ps (__tile *dst, __tile *src1, __tile *src2) +{ + uint16_t *src1_buf = (uint16_t *) src1->buf; + uint16_t *src2_buf = (uint16_t *) src2->buf; + float *dst_buf = (float *) dst->buf; + + int M = src1->rows; + int N = src1->colsb / 4; + int K = src2->colsb / 4; + int i, j, k, t; + + for (i = 0; i < M; i++) + for (j = 0; j < N; j++) + for (k = 0; k < K; k++) + for (t = 0; t < 2; t+=2) + dst_buf[i * N + k] += + (make_fp16_f32(src1_buf[i * 2 * N + 2 * j + t]) * + make_fp16_f32(src2_buf[j * 2 * K + 2 * k + t + 1])) + + (make_fp16_f32(src1_buf[i * 2 * N + 2 * j + t + 1]) * + make_fp16_f32(src2_buf[j * 2 * K + 2 * k + t])); +} + +void test_amx_complex_cmmimfp16ps () +{ + __tilecfg_u cfg; + __tile dst, dst_ref, src1, src2; + uint8_t tmp_dst_buf[1024], tmp_dst_zero_buf[1024]; + + init_fp16_max_tile_buffer (tmp_dst_buf); + init_fp16_max_tile_zero_buffer (tmp_dst_zero_buf); + + init_tile_config (&cfg); + init_tile_reg_and_src_with_buffer (1, dst, tmp_dst_zero_buf); + init_tile_reg_and_src_with_buffer (2, src1, tmp_dst_buf); + init_tile_reg_and_src_with_buffer (3, src2, tmp_dst_buf); + + calc_matrix_cmmimfp16ps (&dst, &src1, &src2); + + _tile_cmmimfp16ps (1, 2, 3); + _tile_stored (1, dst_ref.buf, _STRIDE); + + if (!check_tile_register (&dst_ref, &dst)) + abort (); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c new file mode 100644 index 0000000000000000000000000000000000000000..15940708a0288f086b81ac337bc9ea9e8a12cf69 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxcomplex-cmmrlfp16ps-2.c @@ -0,0 +1,53 @@ +/* { dg-do run { target { ! ia32 } } } */ +/* { dg-require-effective-target amx_complex } */ +/* { dg-require-effective-target avx512fp16 } */ +/* { dg-options "-O2 -mamx-complex -mavx512fp16" } */ +#define AMX_COMPLEX +#define DO_TEST test_amx_complex_cmmrlfp16ps +void test_amx_complex_cmmrlfp16ps(); +#include "amx-helper.h" + +void calc_matrix_cmmrlfp16ps (__tile *dst, __tile *src1, __tile *src2) +{ + uint16_t *src1_buf = (uint16_t *) src1->buf; + uint16_t *src2_buf = (uint16_t *) src2->buf; + float *dst_buf = (float *) dst->buf; + + int M = src1->rows; + int N = src1->colsb / 4; + int K = src2->colsb / 4; + int i, j, k, t; + + for (i = 0; i < M; i++) + for (j = 0; j < N; j++) + for (k = 0; k < K; k++) + for (t = 0; t < 2; t+=2) + dst_buf[i * N + k] += + (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t]) * + make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t])) - + (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t + 1]) * + make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t + 1])); +} + +void test_amx_complex_cmmrlfp16ps () +{ + __tilecfg_u cfg; + __tile dst, dst_ref, src1, src2; + uint8_t tmp_dst_buf[1024], tmp_dst_zero_buf[1024]; + + init_fp16_max_tile_buffer (tmp_dst_buf); + init_fp16_max_tile_zero_buffer (tmp_dst_zero_buf); + + init_tile_config (&cfg); + init_tile_reg_and_src_with_buffer (1, dst, tmp_dst_zero_buf); + init_tile_reg_and_src_with_buffer (2, src1, tmp_dst_buf); + init_tile_reg_and_src_with_buffer (3, src2, tmp_dst_buf); + + calc_matrix_cmmrlfp16ps (&dst, &src1, &src2); + + _tile_cmmrlfp16ps (1, 2, 3); + _tile_stored (1, dst_ref.buf, _STRIDE); + + if (!check_tile_register (&dst_ref, &dst)) + abort (); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-asmatt-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-asmatt-1.c new file mode 100644 index 0000000000000000000000000000000000000000..09ae6d408f1481bcb69771242302faa6bd158156 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-asmatt-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -mamx-fp16" } */ +/* { dg-final { scan-assembler "tdpfp16ps\[ \\t]+\[^\n\]*%tmm3+\[^\n\]*%tmm2+\[^\n\]*%tmm1" } } */ +#include + +#define TMM1 1 +#define TMM2 2 +#define TMM3 3 + +void TEST () +{ + _tile_dpfp16ps (TMM1, TMM2, TMM3); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-asmintel-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-asmintel-1.c new file mode 100644 index 0000000000000000000000000000000000000000..a8dff945f23f59446cb502fc87d2aae99024b017 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-asmintel-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-require-effective-target masm_intel } */ +/* { dg-options "-O2 -mamx-fp16 -masm=intel" } */ +/* { dg-final { scan-assembler "tdpfp16ps\[ \\t]+\[^\n\]*%tmm1+\[^\n\]*%tmm2+\[^\n\]*%tmm3" } } */ +#include + +void TEST () +{ + _tile_dpfp16ps (1, 2, 3); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-dpfp16ps-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-dpfp16ps-2.c new file mode 100644 index 0000000000000000000000000000000000000000..2d359a689eac1dc883f2788dc04113289279abf8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/amxfp16-dpfp16ps-2.c @@ -0,0 +1,57 @@ +/* { dg-do run { target { ! ia32 } } } */ +/* { dg-require-effective-target amx_tile } */ +/* { dg-require-effective-target amx_fp16 } */ +/* { dg-require-effective-target avx512fp16 } */ +/* { dg-options "-O2 -mamx-tile -mamx-fp16 -mavx512fp16" } */ +#define AMX_FP16 +#define DO_TEST test_amx_fp16_dpfp16ps +void test_amx_fp16_dpfp16ps (); +#include "amx-helper.h" + +void calc_matrix_dpfp16ps (__tile *dst, __tile *src1, __tile *src2) +{ + uint16_t *src1_buf = (uint16_t *)src1->buf; + uint16_t *src2_buf = (uint16_t *)src2->buf; + float *dst_buf = (float *)dst->buf; + + int M = src1->rows; + int N = src1->colsb / 4; + int K = src2->colsb / 4; + int i, j, k, t; + + for (i = 0; i < M; i++) + for (j = 0; j < N; j++) + for (k = 0; k < K; k++) + for (t = 0; t < 2; t+=2) + { + dst_buf[i * K + k] += + (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t]) * + make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t])) + + (make_fp16_f32 (src1_buf[i * 2 * N + 2 * j + t + 1]) * + make_fp16_f32 (src2_buf[j * 2 * K + 2 * k + t + 1])); + } + +} + +void test_amx_fp16_dpfp16ps () +{ + __tilecfg_u cfg; + __tile dst, dst_ref, src1, src2; + uint8_t tmp_dst_buf[1024], tmp_dst_zero_buf[1024]; + + init_fp16_max_tile_buffer (tmp_dst_buf); + init_fp16_max_tile_zero_buffer (tmp_dst_zero_buf); + + init_tile_config (&cfg); + init_tile_reg_and_src_with_buffer (1, dst, tmp_dst_zero_buf); + init_tile_reg_and_src_with_buffer (2, src1, tmp_dst_buf); + init_tile_reg_and_src_with_buffer (3, src2, tmp_dst_buf); + + calc_matrix_dpfp16ps (&dst, &src1, &src2); + + _tile_dpfp16ps (1, 2, 3); + _tile_stored (1, dst_ref.buf, _STRIDE); + + if (!check_float_tile_register (&dst_ref, &dst)) + abort (); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/avx-vzeroupper-29.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/avx-vzeroupper-29.c new file mode 100644 index 0000000000000000000000000000000000000000..4af637757f763846f6ca8f9af15c5ffda378eebf --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/avx-vzeroupper-29.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -mavx -mtune=generic -mvzeroupper -dp" } */ + +#include + +extern __m256 x, y; + +void +foo () +{ + x = y; +} + +/* { dg-final { scan-assembler-times "avx_vzeroupper" 1 } } */ diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/i386.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/i386.exp new file mode 100644 index 0000000000000000000000000000000000000000..304a9026ffd23d121da4c37fd706382f36f64cd5 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/i386.exp @@ -0,0 +1,60 @@ +# Copyright (C) 1997-2022 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a x86 target. +if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { + return +} + +# Load support procs. +load_lib gcc-dg.exp +load_lib clearcap.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init +clearcap-init + +global runtests +# Special case compilation of vect-args.c so we don't have to +# replicate it 16 times. +if [runtest_file_p $runtests $srcdir/$subdir/vect-args.c] { + foreach type { "" -mmmx -m3dnow -msse -msse2 -mavx -mavx2 -mavx512f } { + foreach level { "" -O } { + set flags "$type $level" + verbose -log "Testing vect-args, $flags" 1 + dg-test $srcdir/$subdir/vect-args.c $flags "" + } + } +} + +# Everything else. +set tests [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] +set tests [prune $tests $srcdir/$subdir/vect-args.c] + +# Main loop. +dg-runtest $tests "" $DEFAULT_CFLAGS + +# All done. +clearcap-finish +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/mvc17.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/mvc17.c new file mode 100644 index 0000000000000000000000000000000000000000..8b83c1aecb36e02d20e66e6895e17adbf073168a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/mvc17.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O2 -march=x86-64" } */ +/* { dg-final { scan-assembler-times "rep mov" 1 } } */ + +__attribute__((target_clones("default","arch=icelake-server"))) +void +foo (char *a, char *b, int size) +{ + __builtin_memcpy (a, b, size & 0x7F); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110108-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110108-2.c new file mode 100644 index 0000000000000000000000000000000000000000..2d1d2fd49915f6dd6e1a92402b800d24137806aa --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110108-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx2 -O2 -funsigned-char" } */ +/* { dg-final { scan-assembler-times "vpblendvb" 2 } } */ + +#include +__m128i do_stuff_128(__m128i X0, __m128i X1, __m128i X2) { + __m128i Result = _mm_blendv_epi8(X0, X1, X2); + return Result; +} + +__m256i do_stuff_256(__m256i X0, __m256i X1, __m256i X2) { + __m256i Result = _mm256_blendv_epi8(X0, X1, X2); + return Result; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110170-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110170-3.c new file mode 100644 index 0000000000000000000000000000000000000000..70daa89e9aae8adf3c15b0bc70c3285c84665352 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110170-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -fno-if-conversion -fno-if-conversion2" } */ +/* { dg-final { scan-assembler-not {(?n)movq.*r} } } */ + +void __cond_swap(double* __x, double* __y) { + _Bool __r = (*__x < *__y); + double __tmp = __r ? *__x : *__y; + *__y = __r ? *__y : *__x; + *__x = __tmp; +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110309.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110309.c new file mode 100644 index 0000000000000000000000000000000000000000..f6e9e9c3c616dfdcdf210e5668ad5b97976586b3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr110309.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 --param vect-partial-vector-usage=1 -march=znver4 -mprefer-vector-width=256" } */ +/* { dg-final { scan-assembler-not {(?n)vpblendd.*ymm} } } */ + + +void foo (int * __restrict a, int *b) +{ + for (int i = 0; i < 6; ++i) + a[i] = b[i] + 42; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr111306.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr111306.c new file mode 100644 index 0000000000000000000000000000000000000000..541725ebdadfd62f08d5aaf550ab54d2cfd1a764 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr111306.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -mavx512fp16 -mavx512vl" } */ +/* { dg-require-effective-target avx512fp16 } */ + +#define AVX512FP16 +#include "avx512f-helper.h" + +__attribute__((optimize("O2"),noipa)) +void func1(_Float16 *a, _Float16 *b, int n, _Float16 *c) { + __m512h rA = _mm512_loadu_ph(a); + for (int i = 0; i < n; i += 32) { + __m512h rB = _mm512_loadu_ph(b + i); + _mm512_storeu_ph(c + i, _mm512_fcmul_pch(rB, rA)); + } +} + +void +test_512 (void) +{ + int n = 32; + _Float16 a[n], b[n], c[n]; + _Float16 exp[n]; + for (int i = 1; i <= n; i++) { + a[i - 1] = i & 1 ? -i : i; + b[i - 1] = i; + } + + func1(a, b, n, c); + for (int i = 0; i < n / 32; i += 2) { + if (c[i] != a[i] * b[i] + a[i+1] * b[i+1] + || c[i+1] != a[i] * b[i+1] - a[i+1]*b[i]) + __builtin_abort (); + } +} + + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr112891-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr112891-2.c new file mode 100644 index 0000000000000000000000000000000000000000..164c3985d5083470f2bc7cb87c194620937e68e4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr112891-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx2 -O3" } */ +/* { dg-final { scan-assembler-times "vzeroupper" 1 } } */ + +void +__attribute__((noinline)) +bar (double* a) +{ + a[0] = 1.0; + a[1] = 2.0; +} + +double +__attribute__((noinline)) +foo (double* __restrict a, double* b) +{ + a[0] += b[0]; + a[1] += b[1]; + a[2] += b[2]; + a[3] += b[3]; + bar (b); + return a[5] + b[5]; +} + +double +foo1 (double* __restrict a, double* b) +{ + double c = foo (a, b); + return __builtin_exp (c); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr112891.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr112891.c new file mode 100644 index 0000000000000000000000000000000000000000..dbf6c67948a46147ebf7ff5a49699157a950959b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/pr112891.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx2 -O3" } */ +/* { dg-final { scan-assembler-times "vzeroupper" 1 } } */ + +void +__attribute__((noinline)) +bar (double* a) +{ + a[0] = 1.0; + a[1] = 2.0; +} + +void +__attribute__((noinline)) +foo (double* __restrict a, double* b) +{ + a[0] += b[0]; + a[1] += b[1]; + a[2] += b[2]; + a[3] += b[3]; + bar (b); +} + +double +foo1 (double* __restrict a, double* b) +{ + foo (a, b); + return __builtin_exp (b[1]); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-1.c new file mode 100644 index 0000000000000000000000000000000000000000..80f25e70e8e33a4d7c5de845218272141dc966bd --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-1.c @@ -0,0 +1,40 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mprefetchi -O2" } */ +/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+" 2 } } */ +/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+" 2 } } */ + +#include + +int +bar (int a) +{ + return a + 1; +} + +int +foo1 (int b) +{ + _mm_prefetch (bar, _MM_HINT_IT0); + return bar (b) + 1; +} + +int +foo2 (int b) +{ + _mm_prefetch (bar, _MM_HINT_IT1); + return bar (b) + 1; +} + +int +foo3 (int b) +{ + _m_prefetchit0 (bar); + return bar (b) + 1; +} + +int +foo4 (int b) +{ + _m_prefetchit1 (bar); + return bar (b) + 1; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-2.c new file mode 100644 index 0000000000000000000000000000000000000000..e05ce9c733d41944f1cd803cfb5f9bf5a7a512b7 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-mprefetchi -O2" } */ +/* { dg-final { scan-assembler-not "\[ \\t\]+prefetchit0" } } */ +/* { dg-final { scan-assembler-not "\[ \\t\]+prefetchit1" } } */ + +#include + +int +bar (int a) +{ + return a + 1; +} + +int +foo1 (int b) +{ + __builtin_ia32_prefetch (bar, 0, 3, 1); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ + return bar (b) + 1; +} + +int +foo2 (int b) +{ + __builtin_ia32_prefetchi (bar, 2); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ + return bar (b) + 1; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-3.c new file mode 100644 index 0000000000000000000000000000000000000000..f0a4173d2a6af5ae5522e806f49930bc61680a16 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-3.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-mprefetchi -O2" } */ +/* { dg-final { scan-assembler-not "prefetchit0" } } */ +/* { dg-final { scan-assembler-not "prefetchit1" } } */ + +#include + +void* p; + +void extern +prefetchi_test1 (void) +{ + __builtin_ia32_prefetchi (p, 2); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ +} + +void extern +prefetchi_test2 (void) +{ + __builtin_ia32_prefetch (p, 0, 3, 1); /* { dg-warning "instruction prefetch applies when in 64-bit mode with RIP-relative addressing and option '-mprefetchi'; they stay NOPs otherwise" } */ +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-4.c new file mode 100644 index 0000000000000000000000000000000000000000..73ae596d147a1f4ba821a61ee1d8d16f2948a5fb --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/i386/prefetchi-4.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +#include + +void* p; + +void extern +prefetch_test (void) +{ + __builtin_ia32_prefetch (p, 0, 3, 0); + __builtin_ia32_prefetch (p, 0, 2, 0); + __builtin_ia32_prefetch (p, 0, 1, 0); + __builtin_ia32_prefetch (p, 0, 0, 0); + __builtin_ia32_prefetch (p, 1, 3, 0); + __builtin_ia32_prefetch (p, 1, 2, 0); + __builtin_ia32_prefetch (p, 1, 1, 0); + __builtin_ia32_prefetch (p, 1, 0, 0); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-1.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-1.c new file mode 100644 index 0000000000000000000000000000000000000000..5c5623d9b2f75a9f54e9502125119de2092a2e58 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-mno-inline-atomics" } */ +/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ +/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_add_1" } } */ +/* { dg-final { scan-assembler "\tcall\t__sync_fetch_and_nand_1" } } */ +/* { dg-final { scan-assembler "\tcall\t__sync_bool_compare_and_swap_1" } } */ + +char foo; +char bar; +char baz; + +int +main () +{ + __sync_fetch_and_add(&foo, 1); + __sync_fetch_and_nand(&bar, 1); + __sync_bool_compare_and_swap (&baz, 1, 2); +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-2.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-2.c new file mode 100644 index 0000000000000000000000000000000000000000..01b439086924243fc5892d1833a2093615e3049a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* Verify that subword atomics do not generate calls. */ +/* { dg-options "-minline-atomics" } */ +/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "fetch_and_nand" { target *-*-* } 0 } */ +/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_add_1" } } */ +/* { dg-final { scan-assembler-not "\tcall\t__sync_fetch_and_nand_1" } } */ +/* { dg-final { scan-assembler-not "\tcall\t__sync_bool_compare_and_swap_1" } } */ + +#include "inline-atomics-1.c" \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-3.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-3.c new file mode 100644 index 0000000000000000000000000000000000000000..709f3734377b5a630f29a6c49a7c4d0efcc27f25 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-3.c @@ -0,0 +1,569 @@ +/* Check all char alignments. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ + +/* Test the execution of the __atomic_*OP builtin routines for a char. */ + +extern void abort(void); + +char count, res; +const char init = ~0; + +struct A +{ + char a; + char b; + char c; + char d; +} __attribute__ ((packed)) A; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub (char* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and (char* v) +{ + *v = init; + + if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand (char* v) +{ + *v = init; + + if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor (char* v) +{ + *v = init; + count = 0; + + if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch (char* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch (char* v) +{ + *v = init; + + if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + *v = init; + if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch (char* v) +{ + *v = init; + + if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch (char* v) +{ + *v = init; + count = 0; + + if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch (char* v) +{ + *v = 0; + count = 1; + + if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add (char* v) +{ + *v = 0; + count = 1; + + __atomic_add_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_CONSUME); + if (*v != 2) + abort (); + + __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); + if (*v != 3) + abort (); + + __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); + if (*v != 4) + abort (); + + __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 5) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); + if (*v != 6) + abort (); +} + + +void +test_sub (char* v) +{ + *v = res = 20; + count = 0; + + __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); + if (*v != --res) + abort (); +} + +void +test_and (char* v) +{ + *v = init; + + __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); + if (*v != 0) + abort (); + + *v = init; + __atomic_fetch_and (v, init, __ATOMIC_CONSUME); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, init, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_nand (char* v) +{ + *v = init; + + __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); + if (*v != 0) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); + if (*v != init) + abort (); +} + + + +void +test_xor (char* v) +{ + *v = init; + count = 0; + + __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_or (char* v) +{ + *v = 0; + count = 1; + + __atomic_or_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_CONSUME); + if (*v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); + if (*v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); + if (*v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); + if (*v != 63) + abort (); +} + +int +main () +{ + char* V[] = {&A.a, &A.b, &A.c, &A.d}; + + for (int i = 0; i < 4; i++) { + test_fetch_add (V[i]); + test_fetch_sub (V[i]); + test_fetch_and (V[i]); + test_fetch_nand (V[i]); + test_fetch_xor (V[i]); + test_fetch_or (V[i]); + + test_add_fetch (V[i]); + test_sub_fetch (V[i]); + test_and_fetch (V[i]); + test_nand_fetch (V[i]); + test_xor_fetch (V[i]); + test_or_fetch (V[i]); + + test_add (V[i]); + test_sub (V[i]); + test_and (V[i]); + test_nand (V[i]); + test_xor (V[i]); + test_or (V[i]); + } + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-4.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-4.c new file mode 100644 index 0000000000000000000000000000000000000000..eecfaae5cc6530871cd1bf6769467057af2b9e7c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-4.c @@ -0,0 +1,566 @@ +/* Check all short alignments. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-2.c */ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */ + +/* Test the execution of the __atomic_*OP builtin routines for a short. */ + +extern void abort(void); + +short count, res; +const short init = ~0; + +struct A +{ + short a; + short b; +} __attribute__ ((packed)) A; + +/* The fetch_op routines return the original value before the operation. */ + +void +test_fetch_add (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3) + abort (); + + if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4) + abort (); + + if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5) + abort (); +} + + +void +test_fetch_sub (short* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) != res--) + abort (); + + if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) != res--) + abort (); + + if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) != res--) + abort (); +} + +void +test_fetch_and (short* v) +{ + *v = init; + + if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_fetch_nand (short* v) +{ + *v = init; + + if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) != 0 ) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) != 0) + abort (); + + if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_xor (short* v) +{ + *v = init; + count = 0; + + if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) != init) + abort (); +} + +void +test_fetch_or (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) != 0) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) != 1) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) != 7) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) != 15) + abort (); + + count *= 2; + if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) != 31) + abort (); +} + +/* The OP_fetch routines return the new value after the operation. */ + +void +test_add_fetch (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3) + abort (); + + if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5) + abort (); + + if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6) + abort (); +} + + +void +test_sub_fetch (short* v) +{ + *v = res = 20; + count = 0; + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) != --res) + abort (); + + if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) != --res) + abort (); + + if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) != --res) + abort (); +} + +void +test_and_fetch (short* v) +{ + *v = init; + + if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) != 0) + abort (); + + *v = init; + if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) != 0) + abort (); + + *v = ~*v; + if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_nand_fetch (short* v) +{ + *v = init; + + if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) != init) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) != 0) + abort (); + + if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) != init) + abort (); +} + + + +void +test_xor_fetch (short* v) +{ + *v = init; + count = 0; + + if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) != 0) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) != 0) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) != init) + abort (); + + if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) != init) + abort (); + + if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) != 0) + abort (); +} + +void +test_or_fetch (short* v) +{ + *v = 0; + count = 1; + + if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) != 1) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) != 3) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) != 7) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) != 15) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) != 31) + abort (); + + count *= 2; + if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) != 63) + abort (); +} + + +/* Test the OP routines with a result which isn't used. Use both variations + within each function. */ + +void +test_add (short* v) +{ + *v = 0; + count = 1; + + __atomic_add_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_CONSUME); + if (*v != 2) + abort (); + + __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE); + if (*v != 3) + abort (); + + __atomic_fetch_add (v, 1, __ATOMIC_RELEASE); + if (*v != 4) + abort (); + + __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 5) + abort (); + + __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST); + if (*v != 6) + abort (); +} + + +void +test_sub (short* v) +{ + *v = res = 20; + count = 0; + + __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE); + if (*v != --res) + abort (); + + __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL); + if (*v != --res) + abort (); + + __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST); + if (*v != --res) + abort (); +} + +void +test_and (short* v) +{ + *v = init; + + __atomic_and_fetch (v, 0, __ATOMIC_RELAXED); + if (*v != 0) + abort (); + + *v = init; + __atomic_fetch_and (v, init, __ATOMIC_CONSUME); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, init, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL); + if (*v != 0) + abort (); + + *v = ~*v; + __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_nand (short* v) +{ + *v = init; + + __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, init, __ATOMIC_RELEASE); + if (*v != 0) + abort (); + + __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST); + if (*v != init) + abort (); +} + + + +void +test_xor (short* v) +{ + *v = init; + count = 0; + + __atomic_xor_fetch (v, count, __ATOMIC_RELAXED); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME); + if (*v != 0) + abort (); + + __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE); + if (*v != 0) + abort (); + + __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE); + if (*v != init) + abort (); + + __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL); + if (*v != init) + abort (); + + __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST); + if (*v != 0) + abort (); +} + +void +test_or (short* v) +{ + *v = 0; + count = 1; + + __atomic_or_fetch (v, count, __ATOMIC_RELAXED); + if (*v != 1) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_CONSUME); + if (*v != 3) + abort (); + + count *= 2; + __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE); + if (*v != 7) + abort (); + + count *= 2; + __atomic_fetch_or (v, 8, __ATOMIC_RELEASE); + if (*v != 15) + abort (); + + count *= 2; + __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL); + if (*v != 31) + abort (); + + count *= 2; + __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST); + if (*v != 63) + abort (); +} + +int +main () { + short* V[] = {&A.a, &A.b}; + + for (int i = 0; i < 2; i++) { + test_fetch_add (V[i]); + test_fetch_sub (V[i]); + test_fetch_and (V[i]); + test_fetch_nand (V[i]); + test_fetch_xor (V[i]); + test_fetch_or (V[i]); + + test_add_fetch (V[i]); + test_sub_fetch (V[i]); + test_and_fetch (V[i]); + test_nand_fetch (V[i]); + test_xor_fetch (V[i]); + test_or_fetch (V[i]); + + test_add (V[i]); + test_sub (V[i]); + test_and (V[i]); + test_nand (V[i]); + test_xor (V[i]); + test_or (V[i]); + } + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-5.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-5.c new file mode 100644 index 0000000000000000000000000000000000000000..52093894a79760fd806d7651e648b7a46e88460d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-5.c @@ -0,0 +1,87 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-1.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_compare_exchange_n builtin for a char. */ + +extern void abort(void); + +char v = 0; +char expected = 0; +char max = ~0; +char desired = ~0; +char zero = 0; + +#define STRONG 0 +#define WEAK 1 + +int +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-6.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-6.c new file mode 100644 index 0000000000000000000000000000000000000000..8fee8c4481190d5307e8d990628084e367c52e0d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-6.c @@ -0,0 +1,87 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-compare-exchange-2.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_compare_exchange_n builtin for a short. */ + +extern void abort(void); + +short v = 0; +short expected = 0; +short max = ~0; +short desired = ~0; +short zero = 0; + +#define STRONG 0 +#define WEAK 1 + +int +main () +{ + + if (!__atomic_compare_exchange_n (&v, &expected, max, STRONG , __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, 0, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange_n (&v, &expected, desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange_n (&v, &expected, desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + /* Now test the generic version. */ + + v = 0; + + if (!__atomic_compare_exchange (&v, &expected, &max, STRONG, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) + abort (); + if (expected != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) + abort (); + if (expected != max) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &zero, STRONG , __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) + abort (); + if (expected != max) + abort (); + if (v != 0) + abort (); + + if (__atomic_compare_exchange (&v, &expected, &desired, WEAK, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) + abort (); + if (expected != 0) + abort (); + + if (!__atomic_compare_exchange (&v, &expected, &desired, STRONG , __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) + abort (); + if (expected != 0) + abort (); + if (v != max) + abort (); + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-7.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-7.c new file mode 100644 index 0000000000000000000000000000000000000000..24c344c0ce3d6929d6c7b66ef55048f3e7203626 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-7.c @@ -0,0 +1,69 @@ +/* Test __atomic routines for existence and proper execution on 1 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-1.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_exchange_n builtin for a char. */ + +extern void abort(void); + +char v, count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) + abort (); + count++; + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-8.c b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-8.c new file mode 100644 index 0000000000000000000000000000000000000000..edc212df04e21a110340dcf9a3bd8fbfaacd1560 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/inline-atomics-8.c @@ -0,0 +1,69 @@ +/* Test __atomic routines for existence and proper execution on 2 byte + values with each valid memory model. */ +/* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-exchange-2.c */ +/* { dg-do run } */ +/* { dg-options "-minline-atomics" } */ + +/* Test the execution of the __atomic_X builtin for a short. */ + +extern void abort(void); + +short v, count, ret; + +int +main () +{ + v = 0; + count = 0; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELAXED) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQUIRE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_RELEASE) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_ACQ_REL) != count) + abort (); + count++; + + if (__atomic_exchange_n (&v, count + 1, __ATOMIC_SEQ_CST) != count) + abort (); + count++; + + /* Now test the generic version. */ + + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELAXED); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQUIRE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_RELEASE); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_ACQ_REL); + if (ret != count - 1 || v != count) + abort (); + count++; + + __atomic_exchange (&v, &count, &ret, __ATOMIC_SEQ_CST); + if (ret != count - 1 || v != count) + abort (); + count++; + + return 0; +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/riscv.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/riscv.exp new file mode 100644 index 0000000000000000000000000000000000000000..9b7ec568d3bf5a9b366c3c8d3ea77600956858c2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/gcc.target/riscv/riscv.exp @@ -0,0 +1,43 @@ +# Copyright (C) 2017-2022 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 +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a RISC-V target. +if ![istarget riscv*-*-*] then { + return +} + +lappend ADDITIONAL_TORTURE_OPTIONS {-Og -g} {-Oz} + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/asan-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/asan-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..7e0f85dc9b0c29fb89faddc09097ca52425dfac4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/asan-dg.exp @@ -0,0 +1,361 @@ +# Copyright (C) 2012-2022 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 +# . + +# Return 1 if compilation with -fsanitize=address is error-free for trivial +# code, 0 otherwise. +# +# NOTE: This should only be used between calls to asan_init and asan_finish. +# It is therefore defined here rather than in target-supports.exp. + +proc check_effective_target_fsanitize_address {} { + if ![check_no_compiler_messages fsanitize_address executable { + int main (void) { return 0; } + }] { + return 0; + } + + # asan doesn't work if there's a ulimit on virtual memory. + if ![is_remote target] { + if [catch {exec sh -c "ulimit -v"} ulimit_v] { + # failed to get ulimit + } elseif [regexp {^[0-9]+$} $ulimit_v] { + # ulimit -v gave a numeric limit + warning "skipping asan tests due to ulimit -v" + return 0; + } + } + + return 1; +} + +proc asan_include_flags {} { + global srcdir + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set flags "-I$srcdir/../../libsanitizer/include" + + return "$flags" +} + +# +# asan_link_flags -- compute library path and flags to find libasan. +# (originally from g++.exp) +# + +proc asan_link_flags_1 { paths lib } { + global srcdir + global ld_library_path + global shlib_ext + global ${lib}_saved_library_path + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + set ${lib}_saved_library_path $ld_library_path + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.a"] + || [file exists "${gccpath}/libsanitizer/${lib}/.libs/lib${lib}.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/ " + append flags " -B${gccpath}/libsanitizer/${lib}/ " + append flags " -L${gccpath}/libsanitizer/${lib}/.libs " + append ld_library_path ":${gccpath}/libsanitizer/${lib}/.libs" + } + } else { + global tool_root_dir + + set libdir [lookfor_file ${tool_root_dir} lib${lib}] + if { $libdir != "" } { + append flags "-L${libdir} " + append ld_library_path ":${libdir}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +proc asan_link_flags { paths } { + return [asan_link_flags_1 $paths asan] +} + +# +# asan_init -- called at the start of each subdir of tests +# + +proc asan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global asan_saved_TEST_ALWAYS_FLAGS + global asan_saved_ALWAYS_CXXFLAGS + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[asan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[asan_link_flags [get_multilibs]]" + } + } + + set include_flags "[asan_include_flags]" + + if [info exists TEST_ALWAYS_FLAGS] { + set asan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set asan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=address -g $include_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $include_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $include_flags" + } + } +} + +# +# asan_finish -- called at the start of each subdir of tests +# + +proc asan_finish { args } { + global TEST_ALWAYS_FLAGS + global asan_saved_TEST_ALWAYS_FLAGS + global asan_saved_ALWAYS_CXXFLAGS + global asan_saved_library_path + global ld_library_path + + if [info exists asan_saved_ALWAYS_CXXFLAGS ] { + set ALWAYS_CXXFLAGS $asan_saved_ALWAYS_CXXFLAGS + } else { + if [info exists asan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $asan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + if [info exists asan_saved_library_path ] { + set ld_library_path $asan_saved_library_path + set_ld_library_path_env_vars + } + clear_effective_target_cache +} + +# Symbolize lines like +# #2 0xdeadbeef (/some/path/libsanitizer.so.0.0.0+0xbeef) +# in $output using addr2line to +# #2 0xdeadbeef in foobar file:123 +proc asan_symbolize { output } { + set addresses [regexp -inline -all -line "^ *#\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+)\[+\](0x\[0-9a-f\]+)\[)\]$" "$output"] + if { [llength $addresses] > 0 } { + set addr2line_name [find_binutils_prog addr2line] + set idx 1 + while { $idx < [llength $addresses] } { + set key [regsub -all "\[\]\[\]" [lindex $addresses $idx] "\\\\&"] + set val [lindex $addresses [expr $idx + 1]] + lappend arr($key) $val + set idx [expr $idx + 3] + } + foreach key [array names arr] { + set args "-f -e $key $arr($key)" + set status [remote_exec host "$addr2line_name" "$args"] + if { [lindex $status 0] > 0 } continue + regsub -all "\r\n" [lindex $status 1] "\n" addr2line_output + regsub -all "\[\n\r\]BFD: \[^\n\r\]*" $addr2line_output "" addr2line_output + regsub -all "^BFD: \[^\n\r\]*\[\n\r\]" $addr2line_output "" addr2line_output + set addr2line_output [regexp -inline -all -line "^\[^\n\r]*" $addr2line_output] + set idx 0 + foreach val $arr($key) { + if { [expr $idx + 1] < [llength $addr2line_output] } { + set fnname [lindex $addr2line_output $idx] + set fileline [lindex $addr2line_output [expr $idx + 1]] + if { "$fnname" != "??" } { + set newkey "$key+$val" + set repl($newkey) "$fnname $fileline" + } + set idx [expr $idx + 2] + } + } + } + set idx 0 + set new_output "" + while {[regexp -start $idx -indices " #\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+\[+\]0x\[0-9a-f\]+)\[)\]" "$output" -> addr] > 0} { + set low [lindex $addr 0] + set high [lindex $addr 1] + set val [string range "$output" $low $high] + append new_output [string range "$output" $idx [expr $low - 2]] + if [info exists repl($val)] { + append new_output "in $repl($val)" + } else { + append new_output "($val)" + } + set idx [expr $high + 2] + } + append new_output [string range "$output" $idx [string length "$output"]] + return "$new_output" + } + return "$output" +} + +# Return a list of gtest tests, printed in the form +# DEJAGNU_GTEST_TEST AddressSanitizer_SimpleDeathTest +# DEJAGNU_GTEST_TEST AddressSanitizer_VariousMallocsTest +proc asan_get_gtest_test_list { output } { + set idx 0 + set ret "" + while {[regexp -start $idx -indices "DEJAGNU_GTEST_TEST (\[^\n\r\]*)(\r\n|\n|\r)" "$output" -> testname] > 0} { + set low [lindex $testname 0] + set high [lindex $testname 1] + set val [string range "$output" $low $high] + lappend ret $val + set idx [expr $high + 1] + } + return $ret +} + +# Return a list of gtest EXPECT_DEATH tests, printed in the form +# DEJAGNU_GTEST_EXPECT_DEATH1 statement DEJAGNU_GTEST_EXPECT_DEATH1 regexp DEJAGNU_GTEST_EXPECT_DEATH1 +# DEJAGNU_GTEST_EXPECT_DEATH2 other statement DEJAGNU_GTEST_EXPECT_DEATH2 other regexp DEJAGNU_GTEST_EXPECT_DEATH2 +proc asan_get_gtest_expect_death_list { output } { + set idx 0 + set ret "" + while {[regexp -start $idx -indices "DEJAGNU_GTEST_EXPECT_DEATH(\[0-9\]*)" "$output" -> id ] > 0} { + set low [lindex $id 0] + set high [lindex $id 1] + set val_id [string range "$output" $low $high] + if {[regexp -start $low -indices "$val_id (.*) DEJAGNU_GTEST_EXPECT_DEATH$val_id (.*) DEJAGNU_GTEST_EXPECT_DEATH$val_id\[\n\r\]" "$output" whole statement regexpr ] == 0} { break } + set low [lindex $statement 0] + set high [lindex $statement 1] + set val_statement [string range "$output" $low $high] + set low [lindex $regexpr 0] + set high [lindex $regexpr 1] + set val_regexpr [string range "$output" $low $high] + lappend ret [list "$val_id" "$val_statement" "$val_regexpr"] + set idx [lindex $whole 1] + } + return $ret +} + +# Replace ${tool}_load with a wrapper so that we can symbolize the output. +if { [info procs ${tool}_load] != [list] \ + && [info procs saved_asan_${tool}_load] == [list] } { + rename ${tool}_load saved_asan_${tool}_load + + proc ${tool}_load { program args } { + global tool + global asan_last_gtest_test_list + global asan_last_gtest_expect_death_list + set result [eval [list saved_asan_${tool}_load $program] $args] + set output [lindex $result 1] + set symbolized_output [asan_symbolize "$output"] + set asan_last_gtest_test_list [asan_get_gtest_test_list "$output"] + set asan_last_gtest_expect_death_list [asan_get_gtest_expect_death_list "$output"] + set result [list [lindex $result 0] $symbolized_output] + return $result + } +} + +# Utility for running gtest asan emulation under dejagnu, invoked via dg-final. +# Call pass if variable has the desired value, otherwise fail. +# +# Argument 0 handles expected failures and the like +proc asan-gtest { args } { + global tool + global asan_last_gtest_test_list + global asan_last_gtest_expect_death_list + + if { ![info exists asan_last_gtest_test_list] } { return } + if { [llength $asan_last_gtest_test_list] == 0 } { return } + if { ![isnative] || [is_remote target] } { return } + + set gtest_test_list $asan_last_gtest_test_list + unset asan_last_gtest_test_list + + if { [llength $args] >= 1 } { + switch [dg-process-target [lindex $args 0]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # This assumes that we are three frames down from dg-test, and that + # it still stores the filename of the testcase in a local variable "name". + # A cleaner solution would require a new DejaGnu release. + upvar 2 name testcase + upvar 2 prog prog + + set output_file "[file rootname [file tail $prog]].exe" + + foreach gtest $gtest_test_list { + set testname "$testcase $gtest" + set status -1 + + setenv DEJAGNU_GTEST_ARG "$gtest" + set result [${tool}_load ./$output_file $gtest] + unsetenv DEJAGNU_GTEST_ARG + set status [lindex $result 0] + set output [lindex $result 1] + if { "$status" == "pass" } { + pass "$testname execution test" + if { [info exists asan_last_gtest_expect_death_list] } { + set gtest_expect_death_list $asan_last_gtest_expect_death_list + foreach gtest_death $gtest_expect_death_list { + set id [lindex $gtest_death 0] + set testname "$testcase $gtest [lindex $gtest_death 1]" + set regexpr [lindex $gtest_death 2] + set status -1 + + setenv DEJAGNU_GTEST_ARG "$gtest:$id" + set result [${tool}_load ./$output_file "$gtest:$id"] + unsetenv DEJAGNU_GTEST_ARG + set status [lindex $result 0] + set output [lindex $result 1] + if { "$status" == "fail" } { + pass "$testname execution test" + if { ![regexp $regexpr ${output}] } { + fail "$testname output pattern test" + send_log "Output should match: $regexpr\n" + } else { + pass "$testname output pattern test" + } + } elseif { "$status" == "pass" } { + fail "$testname execution test" + } else { + $status "$testname execution test" + } + } + } + } else { + $status "$testname execution test" + } + unset asan_last_gtest_expect_death_list + } + + return +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/atomic-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/atomic-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..86dcfa674eaf0eb379639617c44b56f3d402e7e4 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/atomic-dg.exp @@ -0,0 +1,113 @@ +# Copyright (C) 2013-2022 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 +# . + +# +# atomic_link_flags -- compute library path and flags to find libatomic. +# (originally from g++.exp) +# + +proc atomic_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libatomic/.libs/libatomic.a"] + || [file exists "${gccpath}/libatomic/.libs/libatomic.${shlib_ext}"] } { + append flags " -B${gccpath}/libatomic/ " + append flags " -L${gccpath}/libatomic/.libs" + append ld_library_path ":${gccpath}/libatomic/.libs" + } + } else { + global tool_root_dir + + set libatomic [lookfor_file ${tool_root_dir} libatomic] + if { $libatomic != "" } { + append flags "-L${libatomic} " + append ld_library_path ":${libatomic}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# atomic_init -- called at the start of each subdir of tests +# + +proc atomic_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global atomic_saved_TEST_ALWAYS_FLAGS + global atomic_saved_ALWAYS_CXXFLAGS + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[atomic_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[atomic_link_flags [get_multilibs]]" + } + } + + append link_flags " -latomic " + + if [info exists TEST_ALWAYS_FLAGS] { + set atomic_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set atomic_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags" + } + } + return [check_no_compiler_messages_nocache libatomic_available executable { + int main (void) { return 0; } + }] +} + +# +# atomic_finish -- called at the end of each subdir of tests +# + +proc atomic_finish { args } { + global TEST_ALWAYS_FLAGS + global atomic_saved_TEST_ALWAYS_FLAGS + global atomic_saved_ALWAYS_CXXFLAGS + + if [info exists atomic_saved_ALWAYS_CXXFLAGS] { + set ALWAYS_CXXFLAGS $atomic_saved_ALWAYS_CXXFLAGS + } else { + if [info exists atomic_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $atomic_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/c-compat.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/c-compat.exp new file mode 100644 index 0000000000000000000000000000000000000000..5b5beae0ca041f2bb66e004477aea391cd793068 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/c-compat.exp @@ -0,0 +1,166 @@ +# Copyright (C) 2002-2022 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 +# . + +# Please email any bugs, comments, and/or additions to this file to: +# gcc-patches@gcc.gnu.org + +# Globals. + +global compat_use_alt +global compat_same_alt +global compat_have_dfp +global compat_skip_list + +# This file defines procs for determining features supported by both C +# compilers for compatibility tests. + +load_lib target-supports.exp +load_lib target-libpath.exp + +# +# compat-use-alt-compiler -- make the alternate compiler the default +# +proc compat-use-alt-compiler { } { + global GCC_UNDER_TEST ALT_CC_UNDER_TEST + global compat_same_alt compat_alt_caret compat_alt_color compat_no_line_no + global compat_alt_urls compat_alt_plain_output + global TEST_ALWAYS_FLAGS + + # We don't need to do this if the alternate compiler is actually + # the same as the compiler under test. + if { $compat_same_alt == 0 } then { + set GCC_UNDER_TEST $ALT_CC_UNDER_TEST + + # These flags are no longer added to TEST_ALWAYS_FLAGS by prune.exp + # because they are subsumed by -fdiagnostics-plain-output. Add them back + # for compatibility testing with older compilers that do not understand + # -fdiagnostics-plain-output. + set TEST_ALWAYS_FLAGS "-fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never -fdiagnostics-urls=never $TEST_ALWAYS_FLAGS" + + if { $compat_alt_caret == 0 } then { + regsub -all -- "-fno-diagnostics-show-caret" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + if { $compat_alt_color == 0 } then { + regsub -all -- "-fdiagnostics-color=never" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + if { $compat_alt_urls == 0 } then { + regsub -all -- "-fdiagnostics-urls=never" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + if { $compat_no_line_no == 0 } then { + regsub -all -- "-fno-diagnostics-show-line-numbers" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + if { $compat_alt_plain_output == 0 } then { + regsub -all -- "-fdiagnostics-plain-output" $TEST_ALWAYS_FLAGS "" TEST_ALWAYS_FLAGS + } + restore_gcc_exec_prefix_env_var + } +} + +# +# compat-use-tst-compiler -- make compiler under test the default +# +proc compat-use-tst-compiler { } { + global GCC_UNDER_TEST compat_save_gcc_under_test + global compat_same_alt + global TEST_ALWAYS_FLAGS compat_save_TEST_ALWAYS_FLAGS + + # We don't need to do this if the alternate compiler is actually + # the same as the compiler under test. + + if { $compat_same_alt == 0 } then { + set GCC_UNDER_TEST $compat_save_gcc_under_test + set TEST_ALWAYS_FLAGS $compat_save_TEST_ALWAYS_FLAGS + set_gcc_exec_prefix_env_var + } +} + +# Find out whether both compilers support decimal float types. +proc compat_setup_dfp { } { + global compat_use_alt + global compat_same_alt + global compat_have_dfp + global compat_alt_caret + global compat_alt_color + global compat_alt_urls + global compat_alt_plain_output + global compat_no_line_no + global TEST_ALWAYS_FLAGS compat_save_TEST_ALWAYS_FLAGS + + set compat_alt_caret 0 + set compat_alt_color 0 + set compat_alt_urls 0 + set compat_alt_plain_output 0 + set compat_no_line_no 0 + set compat_save_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + + verbose "compat_setup_dfp: $compat_use_alt $compat_same_alt" 2 + + # Does the compiler under test support decimal float types? + compat-use-tst-compiler + set compat_have_dfp [check_effective_target_dfprt_nocache] + verbose "compat_have_dfp for tst compiler: $compat_have_dfp" 2 + + if { $compat_use_alt == 1 && $compat_same_alt == 0 } { + compat-use-alt-compiler + if { [check_no_compiler_messages_nocache compat_alt_has_caret object { + int dummy; } "-fno-diagnostics-show-caret"] != 0 } { + set compat_alt_caret 1 + } + if { [check_no_compiler_messages_nocache compat_alt_has_color object { + int dummy; } "-fdiagnostics-color=never"] != 0 } { + set compat_alt_color 1 + } + if { [check_no_compiler_messages_nocache compat_alt_has_urls object { + int dummy; } "-fdiagnostics-urls=never"] != 0 } { + set compat_alt_urls 1 + } + if { [check_no_compiler_messages_nocache compat_alt_has_no_line_no object { + int dummy; } "-fno-diagnostics-show-line-numbers"] != 0 } { + set compat_no_line_no 1 + } + if { [check_no_compiler_messages_nocache compat_alt_has_plain_output object { + int dummy; } "-fdiagnostics-plain-output"] != 0 } { + set compat_alt_plain_output 1 + } + + compat-use-tst-compiler + } + + # If there is an alternate compiler, does it support decimal float types? + if { $compat_have_dfp == 1 && $compat_use_alt == 1 && $compat_same_alt == 0 } { + compat-use-alt-compiler + set compat_have_dfp [check_effective_target_dfprt_nocache] + compat-use-tst-compiler + verbose "compat_have_dfp for alt compiler: $compat_have_dfp" 2 + } + + # If decimal float is not supported, add it to the skip list, which + # affects code in the header files. + if { $compat_have_dfp == 0 } { + global compat_skip_list + lappend compat_skip_list "DECIMAL_FLOAT" + } +} + +# If either compiler does not support decimal float types, skip this test. + +proc dg-require-compat-dfp { args } { + global compat_have_dfp + if { $compat_have_dfp == 0 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/c-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/c-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..ce4bedce26217cf76b27ed63c794f380950bf8ef --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/c-torture.exp @@ -0,0 +1,333 @@ +# Copyright (C) 1992-2022 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 +# . + +# This file was written by Rob Savoye. (rob@cygnus.com) + +load_lib target-supports.exp +load_lib file-format.exp +load_lib target-libpath.exp +load_lib target-utils.exp + +global GCC_UNDER_TEST +if ![info exists GCC_UNDER_TEST] { + set GCC_UNDER_TEST "[find_gcc]" +} + +global orig_environment_saved + +# This file may be sourced, so don't override environment settings +# that have been previously setup. +if { $orig_environment_saved == 0 } { + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars +} + +# The default option list can be overridden by +# TORTURE_OPTIONS="{ list1 } ... { listN }" + +set LTO_TORTURE_OPTIONS "" +if [info exists TORTURE_OPTIONS] { + set C_TORTURE_OPTIONS $TORTURE_OPTIONS +} else { + # It is theoretically beneficial to group all of the O2/O3 options together, + # as in many cases the compiler will generate identical executables for + # all of them--and the c-torture testsuite will skip testing identical + # executables multiple times. + # Also note that -finline-functions is explicitly included in one of the + # items below, even though -O3 is also specified, because some ports may + # choose to disable inlining functions by default, even when optimizing. + set C_TORTURE_OPTIONS [list \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions } \ + { -O3 -g } \ + { -Os } \ + { -Og -g } ] + + if [check_effective_target_lto] { + # When having plugin test both slim and fat LTO and plugin/nonplugin + # path. + if [check_linker_plugin_available] { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -fno-use-linker-plugin -flto-partition=none } \ + { -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects } + ] + } else { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -flto-partition=none } \ + { -O2 -flto } + ] + } + } +} + +if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set C_TORTURE_OPTIONS \ + [concat $C_TORTURE_OPTIONS $ADDITIONAL_TORTURE_OPTIONS] +} + +# +# c-torture-compile -- runs the Tege C-torture test +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc c-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and analyze the results. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [gcc_target_compile "$src" "$output" object $options] + gcc_check_compile $testcase $option $output $comp_output + file_on_host delete $output +} + +# +# c-torture-execute -- utility to compile and execute a testcase +# +# SOURCES is a list of full pathnames to the test source files. +# The first filename in this list forms the "testcase". +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc c-torture-execute { sources args } { + global tmpdir tool srcdir output compiler_conditional_xfail_data + + # Use the first source filename given as the filename under test. + set src [lindex $sources 0] + + if { [llength $args] > 0 } { + set additional_flags [lindex $args 0] + } else { + set additional_flags "" + } + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set executable $tmpdir/[file tail [file rootname $src].x] + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + set count 0 + set oldstatus "foo" + foreach option $option_list { + if { $count > 0 } { + set oldexec $execname + } + set execname "${executable}${count}" + incr count + + # torture_{compile,execute}_xfail are set by the .x script + # (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_{compile,execute} can be set by the .x script + # (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + file_on_host delete $execname + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + set comp_output [gcc_target_compile "$sources" "${execname}" executable $options] + + if ![gcc_check_compile "$testcase compilation" $option $execname $comp_output] { + unresolved "$testcase execution, $option" + file_on_host delete $execname + continue + } + + # See if this source file uses "long long" types, if it does, and + # no_long_long is set, skip execution of the test. + if [target_info exists no_long_long] then { + if [expr [search_for $src "long long"]] then { + unsupported "$testcase execution, $option" + continue + } + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + + # Sometimes we end up creating identical executables for two + # consecutive sets of different of compiler options. + # + # In such cases we know the result of this test will be identical + # to the result of the last test. + # + # So in cases where the time to load and run/simulate the test + # is relatively high, compare the two binaries and avoid rerunning + # tests if the executables are identical. + # + # Do not do this for native testing since the cost to load/execute + # the test is fairly small and the comparison step actually slows + # the entire process down because it usually does not "hit". + set skip 0 + if { ![isnative] && [info exists oldexec] } { + if { [file_on_host cmp $oldexec $execname] == 0 } { + set skip 1 + } + } + if { $skip == 0 } { + set result [gcc_load "$execname" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + } + if { $oldstatus == "pass" } { + file_on_host delete $oldexec + } + $status "$testcase execution, $option" + set oldstatus $status + } + if [info exists status] { + if { $status == "pass" } { + file_on_host delete $execname + } + } +} + +# +# search_for -- looks for a string match in a file +# +proc search_for { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + +# +# c-torture -- the c-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# SRC is the full pathname of the testcase, or just a file name in which case +# we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc c-torture { args } { + global srcdir subdir compiler_conditional_xfail_data + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + # loop through all the options + foreach option $option_list { + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + c-torture-compile $src "$option $options" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/clearcap.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/clearcap.exp new file mode 100644 index 0000000000000000000000000000000000000000..23a9e4b1d1709ea127e7f5340a8a3337365ce389 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/clearcap.exp @@ -0,0 +1,59 @@ +# Copyright (C) 2014-2022 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 +# . + +# Clear hardware capabilities on Solaris. +if [istarget *-*-solaris2*] { + set clearcap_ldflags "-mclear-hwcap" +} + +# +# clearcap-init -- called at the start of each subdir of tests +# + +proc clearcap-init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global clearcap_saved_TEST_ALWAYS_FLAGS + global clearcap_ldflags + + if [info exists TEST_ALWAYS_FLAGS] { + set clearcap_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists clearcap_ldflags] { + if [info exists ALWAYS_CXXFLAGS] { + set ALWAYS_CXXFLAGS [concat "{ldflags=$clearcap_ldflags}" $ALWAYS_CXXFLAGS] + } else { + append TEST_ALWAYS_FLAGS " $clearcap_ldflags" + } + } + return 0 +} + +# +# clearcap-finish -- called at the start of each subdir of tests +# + +proc clearcap-finish { args } { + global TEST_ALWAYS_FLAGS + global clearcap_saved_TEST_ALWAYS_FLAGS + + if [info exists clearcap_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $clearcap_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/compat.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/compat.exp new file mode 100644 index 0000000000000000000000000000000000000000..d414ba772aa31923a34fde1c7685426bd7b64767 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/compat.exp @@ -0,0 +1,390 @@ +# Copyright (C) 2002-2022 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 +# . + +# This file was written by Janis Johnson, + + +# Test interoperability of two compilers that follow the same ABI, or +# compatibility of two versions of GCC. +# +# Each test has a main program that does nothing but call a function, +# plus two additional source files that contain parts of a program that +# rely on the ABI. those source files are compiled into relocatable +# object files with both compilers. Executables are built using various +# combinations of those object files, with the main program compiled +# with the compiler under test and using that compiler's runtime support. + +# The including .exp file must define these callback procedures. +if [string match "" [info procs "compat-use-alt-compiler"]] then { + error "Proc compat-use-alt-compiler is not defined." +} +if [string match "" [info procs "compat-use-tst-compiler"]] then { + error "Proc compat-use-tst-compiler is not defined." +} + +# Each test is run with each pair of compiler options from this list. +# The first set of options in each pair is used by the compiler under +# test, and the second set is used by the alternate compiler. +# The default option lists can be overridden by +# COMPAT_OPTIONS="[list [list {tst_1} {alt_1}]...[list {tst_n} {alt_n}]]" +# where tst_i and alt_i are lists of options. You can put this in the +# environment before site.exp is written or add it to site.exp directly. +if ![info exists COMPAT_OPTIONS] { + set COMPAT_OPTIONS [list \ + [list {} {}]] +} + +set compat_option_list $COMPAT_OPTIONS + +# Subsets of tests can be selectively disabled by members of this list: +# - ATTRIBUTE: disable all tests using the __attribute__ extension, +# - COMPLEX: disable all tests using the complex types feature, +# - COMPLEX_INT: disable all tests using the complex integral types extension, +# - VA: disable all tests using the variable number of arguments feature, +# - VLA_IN_STRUCT: disable all tests using the variable-length arrays as +# structure members extension, +# - ZERO_ARRAY: disable all tests using the zero-sized arrays extension. +# The default skip lists can be overriden by +# COMPAT_SKIPS="[list {skip_1}...{skip_n}]" +# where skip_i are skip identifiers. You can put this in the environment +# before site.exp is written or add it to site.exp directly. +if ![info exists COMPAT_SKIPS] { + set COMPAT_SKIPS [list {}] +} + +global compat_skip_list +set compat_skip_list $COMPAT_SKIPS + +load_lib dg.exp +load_lib gcc-dg.exp + +# +# compat-obj -- compile to an object file +# +# SOURCE is the source file +# DEST is the object file +# OPTALL is the list of compiler options to use with all tests +# OPTFILE is the list of compiler options to use with this file +# OPTSTR is the options to print with test messages +# XFAILDATA is the xfail data to be passed to the compiler +# +proc compat-obj { source dest optall optfile optstr xfaildata } { + global testcase + global tool + global compiler_conditional_xfail_data + global compat_skip_list + + # Add the skip specifiers. + foreach skip $compat_skip_list { + if { ![string match $skip ""] } { + lappend optall "-DSKIP_$skip" + } + } + + # Set up the options for compiling this file. + set options "" + lappend options "additional_flags=$optfile $optall" + + set compiler_conditional_xfail_data $xfaildata + set comp_output [${tool}_target_compile "$source" "$dest" object $options] + ${tool}_check_compile "$testcase $dest compile" $optstr $dest $comp_output +} + +# compat-run -- link and run an executable +# +# TESTNAME is the mixture of object files to link +# OBJLIST is the list of object files to link +# DEST is the name of the executable +# OPTALL is a list of compiler and linker options to use for all tests +# OPTFILE is a list of compiler and linker options to use for this test +# OPTSTR is the list of options to list in messages +# +proc compat-run { testname objlist dest optall optfile optstr } { + global testcase + global tool + + # Check that all of the objects were built successfully. + foreach obj [split $objlist] { + if ![file_on_host exists $obj] then { + unresolved "$testcase $testname link $optstr" + unresolved "$testcase $testname execute $optstr" + return + } + } + + # Set up the options for linking this test. + set options "" + lappend options "additional_flags=$optfile $optall" + + # Link the objects into an executable. + set comp_output [${tool}_target_compile "$objlist" $dest executable \ + "$options"] + if ![${tool}_check_compile "$testcase $testname link" "" \ + $dest $comp_output] then { + return + } + + # Run the self-checking executable. + if ![string match "*/*" $dest] then { + set dest "./$dest" + } + set result [${tool}_load $dest "" ""] + set status [lindex $result 0] + if { $status == "pass" } then { + file_on_host delete $dest + } + $status "$testcase $testname execute $optstr" +} + +# +# compat-get-options-main -- get target requirements for a test and +# options for the primary source file and the test as a whole +# +# SRC is the full pathname of the primary source file. +# +proc compat-get-options-main { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + # dg-options sets a variable called tool_flags. + set tool_flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || [string match "dg-prune-output" $cmd] \ + || [string match "dg-skip-if" $cmd] \ + || [string match "dg-require-*" $cmd] \ + || [string match "dg-timeout-factor" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { ![string compare "dg-xfail-if" $cmd] } { + warning "compat.exp does not support $cmd in primary source file" + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "compat.exp does not support $cmd" + } + } + + # Return flags to use for compiling the primary source file and for + # linking. + return ${dg-extra-tool-flags} +} + +# +# compat-get-options -- get special tool flags to use for a secondary +# source file +# +# SRC is the full pathname of the source file. +# The result is a list of options to use. +# +# This code is copied from proc dg-test in dg.exp from DejaGNU. +# +proc compat-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-xfail-if sets compiler_conditional_xfail_data. + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data "" + + # dg-xfail-if needs access to dg-do-what. + upvar dg-do-what dg-do-what + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || ![string compare "dg-prune-output" $cmd] \ + || ![string compare "dg-xfail-if" $cmd] \ + || ![string compare "dg-timeout-factor" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { [string match "dg-require-*" $cmd] } { + warning "compat.exp does not support $cmd in secondary source files" + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "compat.exp does not support $cmd" + } + } + + return ${dg-extra-tool-flags} +} + +# +# compat-execute -- compile with compatible compilers +# +# SRC1 is the full pathname of the main file of the testcase. +# SID identifies a test suite in the names of temporary files. +# USE_ALT is nonzero if we're using an alternate compiler as well as +# the compiler under test. +# +proc compat-execute { src1 sid use_alt } { + global srcdir tmpdir + global compat_option_list + global tool + global verbose + global testcase + global gluefile + global compiler_conditional_xfail_data + global dg-do-what-default + + # Get extra flags for this test from the primary source file, and + # process other dg-* options that this suite supports. Warn about + # unsupported flags. + verbose "compat-execute: $src1" 1 + set dg-do-what [list ${dg-do-what-default} "" P] + set extra_flags_1 [compat-get-options-main $src1] + + # Set up the names of the other source files. + set dir [file dirname $src1] + set ext [file extension $src1] + set base [file rootname $src1] + set base [string range $base [string length $dir] end] + regsub "_main" $base "" base + set src2 "${dir}/${base}_x${ext}" + set src3 "${dir}/${base}_y${ext}" + + # Use the dg-options mechanism to specify extra flags for this test. + # The extra flags in each file are used to compile that file, and the + # extra flags in *_main.* are also used for linking. + set extra_flags_2 [compat-get-options $src2] + set compile_xfail_2 $compiler_conditional_xfail_data + set extra_flags_3 [compat-get-options $src3] + set compile_xfail_3 $compiler_conditional_xfail_data + + # Define the names of the object files. + regsub "sid" "sid_main_tst.o" $sid obj1 + regsub "sid" "sid_x_tst.o" $sid obj2_tst + regsub "sid" "sid_x_alt.o" $sid obj2_alt + regsub "sid" "sid_y_tst.o" $sid obj3_tst + regsub "sid" "sid_y_alt.o" $sid obj3_alt + + # Get the base name of this test, for use in messages. + set testcase "$src1" + # Remove the $srcdir and $tmpdir prefixes from $src1. (It would + # be possible to use "regsub" here, if we were careful to escape + # all regular expression characters in $srcdir and $tmpdir, but + # that would be more complicated that this approach.) + if {[string first "$srcdir/" "$src1"] == 0} { + set testcase [string range "$src1" [string length "$srcdir/"] end] + } + if {[string first "$tmpdir/" "$testcase"] == 0} { + set testcase [string range "$testcase" [string length "$tmpdir/"] end] + set testcase "tmpdir-$testcase" + } + # If we couldn't rip $srcdir out of `src1' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] then { + set testcase "[file tail [file dirname $src1]]/[file tail $src1]" + } + + # Check whether this test is supported for this target. + if { [lindex ${dg-do-what} 1 ] == "N" } { + unsupported "$testcase" + verbose "$testcase not supported on this target, skipping it" 3 + return + } + + regsub "_main.*" $testcase "" testcase + # Set up the base name of executable files so they'll be unique. + regsub -all "\[./\]" $testcase "-" execbase + + # Loop through all of the option lists used for this test. + + set count 0 + foreach option_pair $compat_option_list { + + # Pick out each set of options. + set tst_option [lindex $option_pair 0] + set alt_option [lindex $option_pair 1] + set optstr "" + if { ![string match $tst_option ""] \ + || ![string match $alt_option ""] } then { + set optstr "\"$tst_option\",\"$alt_option\"" + } + verbose "Testing $testcase, $optstr" 1 + + # There's a unique name for each executable we generate, based on + # the set of options and how the pieces of the tests are compiled. + set execname1 "${execbase}-${count}1.exe" + set execname2 "${execbase}-${count}2.exe" + set execname3 "${execbase}-${count}3.exe" + set execname4 "${execbase}-${count}4.exe" + incr count + + file_on_host delete $execname1 + file_on_host delete $execname2 + file_on_host delete $execname3 + file_on_host delete $execname4 + + # Compile pieces with the alternate compiler; we'll catch problems + # later. Skip this if we don't have an alternate compiler. + if { $use_alt != 0 } then { + compat-use-alt-compiler + compat-obj "$src2" "$obj2_alt" $alt_option $extra_flags_2 \ + $optstr $compile_xfail_2 + compat-obj "$src3" "$obj3_alt" $alt_option $extra_flags_3 \ + $optstr $compile_xfail_3 + } + + # Compile pieces with the compiler under test. + compat-use-tst-compiler + compat-obj "$src1" "$obj1" $tst_option $extra_flags_1 $optstr "" + compat-obj "$src2" "$obj2_tst" $tst_option $extra_flags_2 \ + $optstr $compile_xfail_2 + compat-obj "$src3" "$obj3_tst" $tst_option $extra_flags_3 \ + $optstr $compile_xfail_3 + + # Link (using the compiler under test), run, and clean up tests. + compat-run "${obj2_tst}-${obj3_tst}" \ + "$obj1 $obj2_tst $obj3_tst" $execname1 \ + $tst_option $extra_flags_1 $optstr + + # If we've got an alternate compiler try some combinations. + if { $use_alt != 0 } then { + compat-run "${obj2_tst}-${obj3_alt}" "$obj1 $obj2_tst $obj3_alt" \ + $execname2 $tst_option $extra_flags_1 $optstr + compat-run "${obj2_alt}-${obj3_tst}" "$obj1 $obj2_alt $obj3_tst" \ + $execname3 $tst_option $extra_flags_1 $optstr + compat-run "${obj2_alt}-${obj3_alt}" "$obj1 $obj2_alt $obj3_alt" \ + $execname4 $tst_option $extra_flags_1 $optstr + } + + # Clean up object files. + set files [glob -nocomplain ${sid}_*.o] + if { $files != "" } { + foreach objfile $files { + if { ![info exists gluefile] || $objfile != $gluefile } { + eval "file_on_host delete $objfile" + } + } + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/copy-file.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/copy-file.exp new file mode 100644 index 0000000000000000000000000000000000000000..1ddb76b2ee8336451a338947ff1e607f3f511053 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/copy-file.exp @@ -0,0 +1,35 @@ +# Copyright (C) 2003-2022 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 +# . + +# This file defines a proc for copying regular files as well as +# symlinks. + +proc gcc_copy_files {srcfiles dstdir} { + foreach f $srcfiles { + if { [is_remote host] } { + remote_download host $f $dstdir + } elseif { [catch { set symlink [file readlink $f] } x] } then { + file copy -force $f $dstdir + } else { + if { [regexp "^/" "$symlink"] } then { + file copy -force $symlink $dstdir + } else { + set dirname [file dirname $f] + file copy -force $dirname/$symlink $dstdir + } + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/dejapatches.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/dejapatches.exp new file mode 100644 index 0000000000000000000000000000000000000000..5aa5057fa13845048c92bd94e21953f3381030c2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/dejapatches.exp @@ -0,0 +1,35 @@ +# Copyright (C) 2008-2022 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 +# . + +# Necessary procs and fallbacks for functionality not present in +# pristine dejagnu-1.4.4. Make sure overrides here work with updated +# dejagnu too. + +# The absence of sim_download will cause e.g. the libstdc++ testsuite +# to expose about 59 more FAILs on simulator targets supporting +# fileio. + +if { [info procs sim_download] == "" } { + proc sim_download { dest file args } { + return [remote_download host $file $args] + } +} + +if { [info procs sim_upload] == "" } { + proc sim_upload { dest srcfile args } { + return [remote_upload host $srcfile $args] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/dg-pch.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/dg-pch.exp new file mode 100644 index 0000000000000000000000000000000000000000..97fb32d701910394dee7a93123241e4c4eaf6150 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/dg-pch.exp @@ -0,0 +1,151 @@ +# Copyright (C) 2003-2022 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 +# . + +load_lib copy-file.exp + +proc pch-init { args } { + global pch_unsupported_debug pch_unsupported + + if [info exists pch_unsupported_debug] { + error "pch-init: pch_unsupported_debug is not empty as expected" + } + if [info exists pch_unsupported] { + error "pch-init: pch_unsupported is not empty as expected" + } + + set result [check_compile pchtest object "int i;" "-g -x c-header"] + set pch_unsupported_debug \ + [regexp "debug info cannot be used with pre-compiled headers" \ + [lindex $result 0]] + remote_file build delete [lindex $result 1] + + set pch_unsupported 0 + if { $pch_unsupported_debug } { + verbose -log "pch is unsupported with the debug info format" + + set result [check_compile pchtest object "int i;" "-x c-header"] + set pch_unsupported \ + [regexp "debug info cannot be used with pre-compiled headers" \ + [lindex $result 0]] + remote_file build delete [lindex $result 1] + } +} + +proc pch-finish { args } { + global pch_unsupported_debug pch_unsupported + unset pch_unsupported_debug + unset pch_unsupported +} + +proc check_effective_target_pch_supported_debug { } { + global pch_unsupported_debug + if { $pch_unsupported_debug } { + return 0 + } + return 1 +} + +proc dg-flags-pch { subdir test otherflags options suffix } { + global runtests dg-do-what-default + global pch_unsupported_debug pch_unsupported + + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $test] { + return + } + + if { [istarget "powerpc-ibm-aix*"] } { + set torture_execute_xfail "powerpc-ibm-aix*" + return + } + + set nshort "$subdir/[file tail $test]" + set bname "[file rootname [file tail $nshort]]" + + catch { file_on_host delete "$bname$suffix.gch" } + catch { file_on_host delete "$bname.s" } + catch { file_on_host delete "$bname.s-gch" } + + # We don't try to use the loop-optimizing options, since they are highly + # unlikely to make any difference to PCH. + foreach flags $options { + verbose "Testing $nshort, $otherflags $flags" 1 + + if { $pch_unsupported != 0 \ + || ( $pch_unsupported_debug != 0 && [regexp " -g" " $flags"] ) } { + verbose -log "$nshort unsupported because debug format conflicts with PCH" + unsupported "$nshort $flags" + continue + } + + # For the header files, the default is to precompile. + set dg-do-what-default precompile + catch { file_on_host delete "$bname$suffix" } + gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" + dg-test -keep-output "./$bname$suffix" "$otherflags $flags" "" + + # For the rest, the default is to compile to .s. + set dg-do-what-default compile + + set have_errs [llength [grep $test "{\[ \t\]\+dg-error\[ \t\]\+.*\[ \t\]\+}"]] + + if { [ file_on_host exists "$bname$suffix.gch" ] } { + # Ensure that the PCH file is used, not the original header. + file_on_host delete "$bname$suffix" + + # The flags "-Dwith_PCH" and "-Dwithout_PCH" are to distinguish the + # two compiles in test summary lines. + dg-test -keep-output $test "$otherflags $flags -I. -Dwith_PCH" "" + file_on_host delete "$bname$suffix.gch" + if { !$have_errs } { + if { [ file_on_host exists "$bname.s" ] } { + remote_upload host "$bname.s" "$bname.s-gch" + remote_download host "$bname.s-gch" + gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" + dg-test -keep-output $test "$otherflags $flags -I. -Dwithout_PCH" "" + remote_upload host "$bname.s" + set tmp [ diff "$bname.s" "$bname.s-gch" ] + if { $tmp == 0 } { + verbose -log "assembly file '$bname.s', '$bname.s-gch' comparison error" + fail "$nshort $otherflags $flags assembly comparison" + } elseif { $tmp == 1 } { + pass "$nshort $otherflags $flags assembly comparison" + } else { + fail "$nshort $otherflags $flags assembly comparison" + } + file_on_host delete "$bname$suffix" + file_on_host delete "$bname.s" + file_on_host delete "$bname.s-gch" + } else { + verbose -log "assembly file '$bname.s' missing" + fail "$nshort $flags assembly comparison" + } + } + } elseif { $pch_unsupported_debug == 0 \ + || [llength [grep $test "{\[ \t\]\+dg-require-effective-target\[ \t\]\+pch_supported_debug\[ \t\]\+.*\[ \t\]\+}"]] > 0 } { + verbose -log "pch file '$bname$suffix.gch' missing" + fail "$nshort $flags" + if { !$have_errs } { + verbose -log "assembly file '$bname.s' missing" 1 + fail "$nshort $flags assembly comparison" + } + } + } +} + +proc dg-pch { subdir test options suffix } { + return [dg-flags-pch $subdir $test "" $options $suffix] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/file-format.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/file-format.exp new file mode 100644 index 0000000000000000000000000000000000000000..f196e5842e46217c3c3eff68cf6cc06eba977c7b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/file-format.exp @@ -0,0 +1,95 @@ +# Copyright (C) 1999-2022 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 +# . + +# Please email any bugs, comments, and/or additions to this file to: +# gcc-bugs@gcc.gnu.org + +# This file defines a proc for determining the file format in use by the +# target. This is useful for tests that are only supported by certain file +# formats. This procedure is defined in a separate file so that it can be +# included by other expect library files. + +proc gcc_target_object_format { } { + global gcc_target_object_format_saved + global tool + + if [info exists gcc_target_object_format_saved] { + verbose "gcc_target_object_format returning saved $gcc_target_object_format_saved" 2 + } elseif { [istarget *-*-darwin*] } { + # Darwin doesn't necessarily have objdump, so hand-code it. + set gcc_target_object_format_saved mach-o + } elseif { [istarget hppa*-*-hpux*] } { + # HP-UX doesn't necessarily have objdump, so hand-code it. + if { [istarget hppa*64*-*-hpux*] } { + set gcc_target_object_format_saved elf + } else { + set gcc_target_object_format_saved som + } + } elseif { [istarget *-*-aix*] } { + # AIX doesn't necessarily have objdump, so hand-code it. + set gcc_target_object_format_saved coff + } elseif { [istarget *-*-amdhsa*] } { + # AMD GCN uses LLVM objdump which is not CLI-compatible + set gcc_target_object_format_saved elf + } else { + set objdump_name [find_binutils_prog objdump] + set open_file [open objfmtst.c w] + puts $open_file "void foo(void) { }" + close $open_file + + ${tool}_target_compile objfmtst.c objfmtst.o object "" + file delete objfmtst.c + + set output [remote_exec host "$objdump_name" "--file-headers objfmtst.o"] + set output [lindex $output 1] + + file delete objfmtst.o + + if ![ regexp "file format (.*)arch" $output dummy objformat ] { + verbose "Could not parse objdump output" 2 + set gcc_target_object_format_saved unknown + } else { + switch -regexp $objformat { + elf { + set gcc_target_object_format_saved elf + } + ecoff { + set gcc_target_object_format_saved ecoff + } + coff { + set gcc_target_object_format_saved coff + } + a\.out { + set gcc_target_object_format_saved a.out + } + pe { + set gcc_target_object_format_saved pe + } + som { + set gcc_target_object_format_saved som + } + default { + verbose "Unknown file format: $objformat" 3 + set gcc_target_object_format_saved unknown + } + } + + verbose "gcc_target_object_format returning $gcc_target_object_format_saved" 2 + } + } + + return $gcc_target_object_format_saved +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/fortran-modules.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/fortran-modules.exp new file mode 100644 index 0000000000000000000000000000000000000000..794ed5a4e708c57d7b59942862dbd80742c6c72b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/fortran-modules.exp @@ -0,0 +1,174 @@ +# Copyright (C) 2012-2022 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 +# . + +# helper to deal with fortran modules + +# Remove files for specified Fortran modules. +# This includes both .mod and .smod files. +proc cleanup-modules { modlist } { + global clean + foreach mod [concat $modlist $clean] { + set m [string tolower $mod].mod + verbose "cleanup-module `$m'" 2 + if [is_remote host] { + remote_file host delete $m + } + remote_file build delete $m + } + cleanup-submodules $modlist +} + +# Remove files for specified Fortran submodules. +proc cleanup-submodules { modlist } { + global clean + foreach mod [concat $modlist $clean] { + set m [string tolower $mod].smod + verbose "cleanup-submodule `$m'" 2 + if [is_remote host] { + remote_file host delete $m + } + remote_file build delete $m + } +} + +proc keep-modules { modlist } { + global clean + # if the modlist is empty, keep everything + if {[llength $modlist] < 1} { + set clean {} + } else { + set cleansed {} + foreach cl $clean { + if {[lsearch $cl $modlist] < 0} { + lappend cleansed $cl + } + } + if {[llength $clean] == [llength $cleansed]} { + warning "keep-modules had no effect?! Possible typo in module name." + } + set clean $cleansed + } +} + +# collect all module names from a source-file +proc list-module-names { files } { + global clean + set clean {} + foreach file $files { + foreach mod [list-module-names-1 $file] { + if {[lsearch $clean $mod] < 0} { + lappend clean $mod + } + } + } + return [join $clean " "] +} + +proc list-module-names-1 { file } { + set result {} + if {[file isdirectory $file]} {return} + # Find lines containing INCLUDE, MODULE, and SUBMODULE, excluding the lines containing + # MODULE [PURE|(IMPURE\s+)?ELEMENTAL|RECURSIVE] (PROCEDURE|FUNCTION|SUBROUTINE) + set pat {^\s*((#)?\s*include|(sub)?module(?!\s+((pure|(impure\s+)?elemental|recursive)\s+)?(procedure|function|subroutine)[:\s]+))\s*.*} + set tmp [igrep $file $pat line] + if {![string match "" $tmp]} { + foreach i $tmp { + regexp -nocase {(\d+)\s+#?\s*include\s+["']([^"']*)["']} $i dummy lineno include_file + if {[info exists include_file]} { + set dir [file dirname $file] + set inc "$dir/$include_file" + unset include_file + if {![file readable $inc]} { + # We do not currently use include path search logic, punt + continue + } + verbose "Line $lineno includes `$inc'" 3 + foreach mod [list-module-names-1 $inc] { + if {[lsearch $result $mod] < 0} { + lappend result $mod + } + } + continue + } + regexp -nocase {(\d+)\s+(module|submodule)\s*([^;]*)} $i i lineno keyword mod + if {![info exists mod]} { + continue + } + # Generates the file name mod_name@submod_name from + # (\s*mod_name[:submod_name]\s*)\s*submod_name\s*[! comment] + regsub {\s*!.*} $mod "" mod + regsub {:[^)]*} $mod "" mod + regsub {\(\s*} $mod "" mod + regsub {\s*\)\s*} $mod "@" mod + verbose "Line $lineno mentions module `$mod'" 3 + if {[lsearch $result $mod] < 0} { + lappend result $mod + } + } + } + return $result +} + +# Looks for case insensitive occurrences of a string in a file. +# return:list of lines that matched or NULL if none match. +# args: first arg is the filename, +# second is the pattern, +# third are any options. +# Options: line - puts line numbers of match in list +# +proc igrep { args } { + + set file [lindex $args 0] + set pattern [lindex $args 1] + + verbose "Grepping $file for the pattern \"$pattern\"" 3 + + set argc [llength $args] + if { $argc > 2 } { + for { set i 2 } { $i < $argc } { incr i } { + append options [lindex $args $i] + append options " " + } + } else { + set options "" + } + + set i 0 + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + incr i + if {[regexp -nocase -- "$pattern" $cur_line match]} { + if {![string match "" $options]} { + foreach opt $options { + switch $opt { + "line" { + lappend grep_out [concat $i $match] + } + } + } + } else { + lappend grep_out $match + } + } + } + close $fd + unset fd + unset i + if {![info exists grep_out]} { + set grep_out "" + } + return $grep_out +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/fortran-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/fortran-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..ca0fe5418370cb57b99229f80c2f1a8382f87a5d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/fortran-torture.exp @@ -0,0 +1,431 @@ +# Copyright (C) 2003-2022 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 +# . + +# Please email any bugs, comments, and/or additions to this file to +# the author. + +# This file was written by Steven Bosscher (s.bosscher@student.tudelft.nl) +# based on f-torture.exp, which was written by Rob Savoye. + +load_lib target-supports.exp +load_lib fortran-modules.exp +load_lib target-utils.exp + +# Return the list of options to use for fortran torture tests. +# The default option list can be overridden by +# TORTURE_OPTIONS="{ { list1 } ... { listN } }" +proc get-fortran-torture-options { } { + global TORTURE_OPTIONS + + if [info exists TORTURE_OPTIONS] { + return $TORTURE_OPTIONS + } + + # determine if host supports vectorization, and the necessary set + # of options, based on code from testsuite/vect/vect.exp + + set vectorizer_options [list "-O2" "-ftree-vectorize"] + + if { [istarget powerpc*-*-*] + && [is-effective-target powerpc_altivec_ok] + && [check_vmx_hw_available] } { + lappend vectorizer_options "-maltivec" + set test_tree_vectorize 1 + } elseif { ( [istarget i?86-*-*] || [istarget x86_64-*-*] ) + && [check_effective_target_sse2] + && [check_sse2_hw_available] + && [check_sse_os_support_available] } { + lappend vectorizer_options "-msse2" + set test_tree_vectorize 1 + } elseif { [istarget mips*-*-*] + && [check_effective_target_mpaired_single] + && [check_effective_target_nomips16] } { + lappend vectorizer_options "-mpaired-single" + set test_tree_vectorize 1 + } elseif { [istarget sparc*-*-*] + && [check_effective_target_ultrasparc_hw] } { + lappend vectorizer_options "-mcpu=ultrasparc" "-mvis" + set test_tree_vectorize 1 + } elseif { [istarget alpha*-*-*] + && [check_alpha_max_hw_available] } { + lappend vectorizer_options "-mmax" + set test_tree_vectorize 1 + } elseif [istarget ia64-*-*] { + set test_tree_vectorize 1 + } else { + set test_tree_vectorize 0 + } + + set options {} + + lappend options \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O2 -fomit-frame-pointer -finline-functions } \ + { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \ + { -O2 -fbounds-check } \ + { -O3 -g } \ + { -Os } + if { $test_tree_vectorize } { + lappend options $vectorizer_options + } + + if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set options [concat $options $ADDITIONAL_TORTURE_OPTIONS] + } + + return $options +} + + +# +# fortran-torture-compile -- compile a gfortran.fortran-torture testcase. +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc fortran-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and get results in comp_output. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [gfortran_target_compile "$src" "$output" object $options] + + # See if we got something bad. + set fatal_signal "*95*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + gfortran_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $output } + return + } + + if [string match "$fatal_signal 11" $comp_output] then { + gfortran_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $output } + return + } + + if [regexp -line -- "internal compiler error.*" $comp_output ice] then { + gfortran_fail $testcase "$option ($ice)" + catch { remote_file build delete $output } + return + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*95*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $output } + return + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [gfortran_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + catch { remote_file build delete $output } + return + } + + # remove any leftover LF/CR to make sure any output is legit + regsub -all -- "\[\r\n\]*" $comp_output "" comp_output + + # If any message remains, we fail. + if ![string match "" $comp_output] then { + gfortran_fail $testcase $option + catch { remote_file build delete $output } + return + } + + gfortran_pass $testcase $option + catch { remote_file build delete $output } +} + + +# +# fortran-torture-execute -- compile and execute a testcase. +# +# SRC is the full pathname of the testcase. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc fortran-torture-execute { src } { + global output + global srcdir tmpdir + global tool + global compiler_conditional_xfail_data + global torture_with_loops + + # Check for alternate driver. + set additional_flags "" + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Setup the options for the testcase run. + set option_list $torture_with_loops + set executable $tmpdir/[file tail [file rootname $src].x] + regsub "(?q)$srcdir/" $src "" testcase + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + list-module-names $src + + # Walk the list of options and copmile and run the testcase for all + # options that are not explicitly disabled by the .x script (if present). + foreach option $option_list { + + # Torture_{compile,execute}_xfail are set by the .x script. + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # Torture_execute_before_{compile,execute} can be set by the .x script. + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + # FIXME: We should make sure that the modules required by this testcase + # exist. If not, the testcase should XFAIL. + + # Compile the testcase. + catch { remote_file build delete $executable } + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + set comp_output [gfortran_target_compile "$src" "$executable" executable $options] + + # See if we got something bad. + set fatal_signal "*95*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + gfortran_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $executable } + continue + } + + if [string match "$fatal_signal 11" $comp_output] then { + gfortran_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $executable } + continue + } + + if [regexp -line -- "internal compiler error.*" $comp_output ice] then { + gfortran_fail $testcase "$option ($ice)" + catch { remote_file build delete $executable } + continue + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*95*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $executable } + continue + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [gfortran_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + continue + } elseif ![file exists $executable] { + if ![is3way] { + fail "$testcase compilation, $option" + untested "$testcase execution, $option" + continue + } else { + # FIXME: since we can't test for the existence of a remote + # file without short of doing an remote file list, we assume + # that since we got no output, it must have compiled. + pass "$testcase compilation, $option" + } + } else { + pass "$testcase compilation, $option" + } + + # See if this source file uses INTEGER(KIND=8) types, if it does, and + # no_long_long is set, skip execution of the test. + # FIXME: We should also look for F95 style "_8" or select_int_kind() + # integers, but that is obviously much harder than just regexping this. + # So maybe we should just avoid those in testcases. + if [target_info exists no_long_long] then { + if [expr [search_for_re $src "integer\*8"] \ + +[search_for_re $src "integer *( *8 *)"] \ + +[search_for_re $src "integer *( *kind *= *8 *)"]] \ + then { + untested "$testcase execution, $option" + continue + } + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + # Run the testcase, and analyse the output. + set result [gfortran_load "$executable" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + if { $status == "pass" } { + catch { remote_file build delete $executable } + } + $status "$testcase execution, $option" + } + cleanup-modules "" +} + + +# +# search_for_re -- looks for a string match in a file +# +proc search_for_re { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + set lower [string tolower $cur_line] + if [regexp "$pattern" $lower] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + + +# +# fortran-torture -- the fortran-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# +# SRC is the full pathname of the testcase, or just a file name in which +# case we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc fortran-torture { args } { + global srcdir subdir + global compiler_conditional_xfail_data + global torture_with_loops + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + list-module-names $src + + # loop through all the options + set option_list $torture_with_loops + foreach option $option_list { + + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + fortran-torture-compile $src "$option $options" + cleanup-modules "" + } +} + +# +# add-ieee-options -- add options necessary for 100% ieee conformance. +# +proc add-ieee-options { } { + # Ensure that excess precision does not cause problems. + if { [istarget i?86-*-*] + || [istarget m68k-*-*] } then { + uplevel 1 lappend additional_flags "-ffloat-store" + } + + # Enable full IEEE compliance mode. + if { [istarget alpha*-*-*] + || [istarget sh*-*-*] } then { + uplevel 1 lappend additional_flags "-mieee" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/g++-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/g++-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..59e8081a29dd59ecf6d8505669d6824b4e03b19d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/g++-dg.exp @@ -0,0 +1,76 @@ +# Copyright (C) 1997-2022 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 +# . + +# Define g++ callbacks for dg.exp. + +load_lib gcc-dg.exp + +proc g++-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 g++_target_compile $prog $do_what $extra_tool_flags] +} + + +proc g++-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Modified dg-runtest that runs tests in multiple standard modes, +# unless they specifically specify one standard. +proc g++-dg-runtest { testcases flags default-extra-flags } { + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # If the testcase specifies a standard, use that one. + # If not, run it under several standards, allowing GNU extensions + # if there's a dg-options line. + if ![search_for $test "-std=*++"] { + if [search_for $test "dg-options"] { + set std_prefix "-std=gnu++" + } else { + set std_prefix "-std=c++" + } + + # See g++.exp for the initial value of this list. + global gpp_std_list + if { [llength $gpp_std_list] > 0 } { + set std_list $gpp_std_list + } else { + set std_list { 98 14 17 20 } + } + set option_list { } + foreach x $std_list { + # Handle "concepts" as C++17 plus Concepts TS. + if { $x eq "concepts" } then { set x "17 -fconcepts" + } elseif { $x eq "impcx" } then { set x "23 -fimplicit-constexpr" } + lappend option_list "${std_prefix}$x" + } + } else { + set option_list { "" } + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/g++.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/g++.exp new file mode 100644 index 0000000000000000000000000000000000000000..24ef068b2395361759deb654281e22a9abbf9729 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/g++.exp @@ -0,0 +1,383 @@ +# Copyright (C) 1992-2022 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Many modifications by Jeffrey Wheat (cassidy@cygnus.com) +# With modifications by Mike Stump . + +# +# g++ support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# GXX_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" +# Allow gpp_std_list to be set in configuration files, e.g., ~/.dejagnurc +if ![info exists gpp_std_list] { + set gpp_std_list { } +} +# Allow gpp_std_list to be set from the environment. +if [info exists env(GXX_TESTSUITE_STDS)] { + set gpp_std_list [split $env(GXX_TESTSUITE_STDS) ","] +} + +# +# g++_version -- extract and print the version number of the compiler +# + +proc g++_version { } { + global GXX_UNDER_TEST + + g++_init + + # ignore any arguments after the command + set compiler [lindex $GXX_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# g++_include_flags -- provide new version of g++_include_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# +proc g++_include_flags { paths } { + global srcdir + global HAVE_LIBSTDCXX_V3 + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set gccpath ${paths} + + set odir [lookfor_file ${gccpath} libstdc++-v3] + if { ${odir} != "" } { + append flags [exec sh ${odir}/scripts/testsuite_flags --build-includes] + } + + return "$flags" +} + +# +# g++_link_flags -- provide new version of g++_link_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# + +proc g++_link_flags { paths } { + global srcdir + global ld_library_path + global GXX_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/lib/libstdc++.a"] { + append ld_library_path ":${gccpath}/lib" + } + if [file exists "${gccpath}/libg++/libg++.a"] { + append flags "-L${gccpath}/libg++ " + append ld_library_path ":${gccpath}/libg++" + } + if [file exists "${gccpath}/libstdc++/libstdc++.a"] { + append flags "-L${gccpath}/libstdc++ " + append ld_library_path ":${gccpath}/libstdc++" + } + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] { + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + # Some targets use libstdc++.a%s in their specs, so they need a + # -B option for uninstalled testing. + append flags " -B${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + # Look for libstdc++.${shlib_ext}. + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] { + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + if [file exists "${gccpath}/librx/librx.a"] { + append flags "-L${gccpath}/librx " + } + if [file exists "${gccpath}/libitm/libitm.spec"] { + append flags "-B${gccpath}/libitm/ -L${gccpath}/libitm/.libs" + append ld_library_path ":${gccpath}/libitm/.libs" + } + append ld_library_path [gcc-set-multilib-library-path $GXX_UNDER_TEST] + } else { + global tool_root_dir + + set libgpp [lookfor_file ${tool_root_dir} libg++] + if { $libgpp != "" } { + append flags "-L${libgpp} " + append ld_library_path ":${libgpp}" + } + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++] + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} " + append ld_library_path ":${libstdcpp}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty] + if { $libiberty != "" } { + append flags "-L${libiberty} " + } + set librx [lookfor_file ${tool_root_dir} librx] + if { $librx != "" } { + append flags "-L${librx} " + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# g++_init -- called at the start of each subdir of tests +# + +proc g++_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global objdir srcdir + global ALWAYS_CXXFLAGS + global CXXFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GXX_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + global TEST_ALWAYS_FLAGS + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + # Many hosts now default to a non-ASCII C locale, however, so + # they can set a charset encoding here if they need. + if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII + } + + if ![info exists GXX_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GXX_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GXX_UNDER_TEST [transform c++] + } else { + set GXX_UNDER_TEST [findfile $base_dir/../../xg++ "$base_dir/../../xg++ -B$base_dir/../../" [findfile $base_dir/xg++ "$base_dir/xg++ -B$base_dir/" [transform c++]]] + } + } + } + + # Bleah, nasty. Bad taste. + if [ishost "*-dos-*" ] { + regsub "c\\+\\+" "$GXX_UNDER_TEST" "gcc" GXX_UNDER_TEST + } + + if ![is_remote host] { + if { [which $GXX_UNDER_TEST] == 0 } then { + perror "GXX_UNDER_TEST ($GXX_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + g++_maybe_build_wrapper "${tmpdir}/g++-testglue.o" "-fexceptions" + + if {![info exists CXXFLAGS]} { + set CXXFLAGS "" + } + + set ALWAYS_CXXFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation command. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_CXXFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_CXXFLAGS "additional_flags=[g++_include_flags [get_multilibs ${TOOL_OPTIONS}] ]" + lappend ALWAYS_CXXFLAGS "ldflags=[g++_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend ALWAYS_CXXFLAGS "additional_flags=[g++_include_flags [get_multilibs] ]" + lappend ALWAYS_CXXFLAGS "ldflags=[g++_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_CXXFLAGS "additional_flags=$TOOL_OPTIONS" + } + + # Make sure that lines are not wrapped. That can confuse the + # error-message parsing machinery. + lappend ALWAYS_CXXFLAGS "additional_flags=-fmessage-length=0" + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + if { [istarget *-*-darwin*] } { + lappend ALWAYS_CXXFLAGS "ldflags=-multiply_defined suppress" + } + + verbose -log "ALWAYS_CXXFLAGS set to $ALWAYS_CXXFLAGS" + + verbose "g++ is initialized" 3 +} + +# +# g++_target_compile -- compile a source file +# + +proc g++_target_compile { source dest type options } { + global tmpdir + global gpp_compile_options + global gluefile wrap_flags + global ALWAYS_CXXFLAGS + global GXX_UNDER_TEST + global flags_to_postpone + global board_info + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + global TEST_EXTRA_LIBS + if [info exists TEST_EXTRA_LIBS] { + lappend options "ldflags=$TEST_EXTRA_LIBS" + } + + lappend options "additional_flags=[libio_include_flags]" + lappend options "compiler=$GXX_UNDER_TEST" + lappend options "timeout=[timeout_value]" + + set options [concat $gpp_compile_options $options] + + set options [concat "$ALWAYS_CXXFLAGS" $options] + + # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is + # appended here to multilib_flags as it can be overridden by the latter + # if it was added earlier. After the target_compile, multilib_flags is + # restored to its orignal content. + set tboard [target_info name] + if {[board_info $tboard exists multilib_flags]} { + set orig_multilib_flags "[board_info [target_info name] multilib_flags]" + append board_info($tboard,multilib_flags) " $flags_to_postpone" + } + + set options [dg-additional-files-options $options $source] + + set result [target_compile $source $dest $type $options] + + if {[board_info $tboard exists multilib_flags]} { + set board_info($tboard,multilib_flags) $orig_multilib_flags + set flags_to_postpone "" + } + + return $result +} + +# +# ${tool}_option_help +# +# Changed "additional" to "extra" because runtest.exp treats --a* as --all. +# +# This shouldn't be necessary at all; it should be entirely redundant with +# --tool_opts, except that --tool_opts currently breaks multilib: see +# http://lists.gnu.org/archive/html/dejagnu/2002-10/msg00007.html + +proc ${tool}_option_help { } { + send_user " --extra_opts,OPTIONS\t\tUse OPTIONS to compile the testcase files. OPTIONS should be comma-separated.\n" +} + +# +# ${tool}_option_proc +# + +proc ${tool}_option_proc { option } { + if [regexp "^--extra_opts," $option] { + global gpp_compile_options + regsub "^--extra_opts," $option "" option + foreach x [split $option ","] { + lappend gpp_compile_options "additional_flags=$x" + } + verbose -log "gpp_compile_options set to $gpp_compile_options" + return 1 + } elseif [regexp "^--stds=" $option] { + global gpp_std_list + regsub "^--stds=" $option "" option + foreach x [split $option ","] { + lappend gpp_std_list "$x" + } + verbose -log "gpp_std_list set to $gpp_std_list" + return 1 + } else { + return 0 + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-defs.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-defs.exp new file mode 100644 index 0000000000000000000000000000000000000000..42ef1d8543218368005389122be92d21ad58746f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-defs.exp @@ -0,0 +1,604 @@ +# Copyright (C) 2001-2022 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 +# . + +load_lib target-libpath.exp + +load_lib wrapper.exp + +load_lib target-utils.exp + +# +# ${tool}_check_compile -- Reports and returns pass/fail for a compilation +# + +proc ${tool}_check_compile {testcase option objname gcc_output} { + global tool + set fatal_signal "*cc: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $gcc_output] then { + ${tool}_fail $testcase "Got Signal 6, $option" + return 0 + } + + if [string match "$fatal_signal 11" $gcc_output] then { + ${tool}_fail $testcase "Got Signal 11, $option" + return 0 + } + + if [regexp -line -- "internal compiler error.*" $gcc_output ice] then { + ${tool}_fail $testcase "$option ($ice)" + return 0 + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*cc:*warning:*" $gcc_output] then { + warning "$testcase: (with warnings) $option" + send_log "$gcc_output\n" + unresolved "$testcase, $option" + return 0 + } + + set gcc_output [prune_warnings $gcc_output] + + if { [info proc ${tool}-dg-prune] != "" } { + global target_triplet + set gcc_output [${tool}-dg-prune $target_triplet $gcc_output] + if [string match "*::unsupported::*" $gcc_output] then { + regsub -- "::unsupported::" $gcc_output "" gcc_output + unsupported "$testcase: $gcc_output" + return 0 + } + } else { + set unsupported_message [${tool}_check_unsupported_p $gcc_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + return 0 + } + } + + # remove any leftover LF/CR to make sure any output is legit + regsub -all -- "\[\r\n\]*" $gcc_output "" gcc_output + + # If any message remains, we fail. + if ![string match "" $gcc_output] then { + ${tool}_fail $testcase $option + return 0 + } + + # fail if the desired object file doesn't exist. + # FIXME: there's no way of checking for existence on a remote host. + if {$objname != "" && ![is3way] && ![file exists $objname]} { + ${tool}_fail $testcase $option + return 0 + } + + ${tool}_pass $testcase $option + return 1 +} + +# +# ${tool}_pass -- utility to record a testcase passed +# + +proc ${tool}_pass { testcase cflags } { + if { "$cflags" == "" } { + pass "$testcase" + } else { + pass "$testcase, $cflags" + } +} + +# +# ${tool}_fail -- utility to record a testcase failed +# + +proc ${tool}_fail { testcase cflags } { + if { "$cflags" == "" } { + fail "$testcase" + } else { + fail "$testcase, $cflags" + } +} + +# +# ${tool}_finish -- called at the end of every script that calls ${tool}_init +# +# Hide all quirks of the testing environment from the testsuites. Also +# undo anything that ${tool}_init did that needs undoing. +# + +proc ${tool}_finish { } { + # The testing harness apparently requires this. + global errorInfo + + if [info exists errorInfo] then { + unset errorInfo + } + + # Might as well reset these (keeps our caller from wondering whether + # s/he has to or not). + global prms_id bug_id + set prms_id 0 + set bug_id 0 +} + +# +# ${tool}_exit -- Does final cleanup when testing is complete +# + +proc ${tool}_exit { } { + global gluefile + + if [info exists gluefile] { + file_on_build delete $gluefile + unset gluefile + } +} + +# +# runtest_file_p -- Provide a definition for older dejagnu releases +# and assume the old syntax: foo1.exp bar1.c foo2.exp bar2.c. +# (delete after next dejagnu release). +# + +if { [info procs runtest_file_p] == "" } then { + proc runtest_file_p { runtests testcase } { + if { $runtests != "" && [regexp "\[.\]\[cC\]" $runtests] } then { + if { [lsearch $runtests [file tail $testcase]] >= 0 } then { + return 1 + } else { + return 0 + } + } + return 1 + } +} + +if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \ + && [info procs runtest_file_p] != [list] \ + && [info procs gcc_parallelize_saved_runtest_file_p] == [list] } then { + global gcc_runtest_parallelize_counter + global gcc_runtest_parallelize_counter_minor + global gcc_runtest_parallelize_enable + global gcc_runtest_parallelize_dir + global gcc_runtest_parallelize_last + + # GCC testsuite is parallelised by starting N runtest processes -- each + # with its own test directory. These N runtest processes ALL go through + # the relevant .exp and ALL attempt to run every test. And they go + # through the tests the same order -- this is important, and if there is + # a bug that causes different runtest processes to enumerate the tests + # differently, then things will break and some tests will be skipped, while + # others will be ran several times. + # So, just before a runtest processes runs a specific test it asks + # "runtest_file_p" routine whether a particular test is part of + # the requested testsuite. We override this function so that it + # returns "yes" to the first-arrived runtest process, and "no" to all + # subsequent runtest processes -- this is implemented by creating a marker + # file, which persist till the end of the test run. We optimize this + # a bit by batching 10 tests and using a single marker file for the batch. + # + # Note that the runtest processes all race each other to get to the next + # test batch. This means that batch allocation between testsuite runs + # is very likely to change. + # + # To confirm or deny suspicion that tests are skipped or executed + # multiple times due to runtest processes enumerating tests differently ... + # 1. Uncomment the three below "verbose -log gcc_parallel_test_run_p ..." + # debug print-outs. + # 2. Run the testsuite with "-v" added to RUNTESTFLAGS + # 3. Extract debug print-outs with something like: + # for i in $(find -name "*.log.sep"); do + # grep gcc_parallel_test_run_p $i \ + # | sed -e "s/\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\)/\3 \2/" \ + # | sed -e "s#\(/testsuite/[a-z+]*\)[0-9]*/#\1N/#" > $i.order + # done + # 4. Compare debug print-outs produced by individual runtest processes: + # find -name "*.log.sep.order" | xargs md5sum | sort + # 5. Check that MD5 hashes of all .order files of the same testsuite match + # and investigate if they don't. + set gcc_runtest_parallelize_counter 0 + set gcc_runtest_parallelize_counter_minor 0 + set gcc_runtest_parallelize_enable 1 + set gcc_runtest_parallelize_dir [getenv GCC_RUNTEST_PARALLELIZE_DIR] + set gcc_runtest_parallelize_last 0 + + proc gcc_parallel_test_run_p { testcase } { + global gcc_runtest_parallelize_counter + global gcc_runtest_parallelize_counter_minor + global gcc_runtest_parallelize_enable + global gcc_runtest_parallelize_dir + global gcc_runtest_parallelize_last + + if { $gcc_runtest_parallelize_enable == 0 } { + return 1 + } + + # Only test the filesystem every 10th iteration + incr gcc_runtest_parallelize_counter_minor + if { $gcc_runtest_parallelize_counter_minor == 10 } { + set gcc_runtest_parallelize_counter_minor 0 + } + if { $gcc_runtest_parallelize_counter_minor != 1 } { + #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter $gcc_runtest_parallelize_last" + return $gcc_runtest_parallelize_last + } + + set path $gcc_runtest_parallelize_dir/$gcc_runtest_parallelize_counter + + if {![catch {open $path {RDWR CREAT EXCL} 0600} fd]} { + close $fd + set gcc_runtest_parallelize_last 1 + #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 1" + incr gcc_runtest_parallelize_counter + return 1 + } + set gcc_runtest_parallelize_last 0 + #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 0" + incr gcc_runtest_parallelize_counter + return 0 + } + + proc gcc_parallel_test_enable { val } { + global gcc_runtest_parallelize_enable + set gcc_runtest_parallelize_enable $val + } + + rename runtest_file_p gcc_parallelize_saved_runtest_file_p + proc runtest_file_p { runtests testcase } { + if ![gcc_parallelize_saved_runtest_file_p $runtests $testcase] { + return 0 + } + return [gcc_parallel_test_run_p $testcase] + } + +} else { + + proc gcc_parallel_test_run_p { testcase } { + return 1 + } + + proc gcc_parallel_test_enable { val } { + } + +} + +# Like dg-options, but adds to the default options rather than replacing them. + +proc dg-additional-options { args } { + upvar dg-extra-tool-flags extra-tool-flags + + if { [llength $args] > 3 } { + error "[lindex $args 0]: too many arguments" + return + } + + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "S" { eval lappend extra-tool-flags [lindex $args 1] } + "N" { } + "F" { error "[lindex $args 0]: `xfail' not allowed here" } + "P" { error "[lindex $args 0]: `xfail' not allowed here" } + } + } else { + eval lappend extra-tool-flags [lindex $args 1] + } +} + +# Record additional sources files that must be compiled along with the +# main source file. + +set additional_sources "" +set additional_sources_used "" + +proc dg-additional-sources { args } { + global additional_sources + set additional_sources [lindex $args 1] +} + +# Record additional files -- other than source files -- that must be +# present on the system where the compiler runs. + +set additional_files "" + +proc dg-additional-files { args } { + global additional_files + set additional_files [lindex $args 1] +} + +set gcc_adjusted_linker_flags 0 + +# Add -Wl, before any file names in $opts. Return the modified list. + +proc gcc_adjust_linker_flags_list { args } { + set opts [lindex $args 0] + set nopts {} + set skip "" + foreach opt [split $opts " "] { + if { $opt == "" } then { + continue + } elseif { $skip != "" } then { + set skip "" + } elseif { $opt == "-Xlinker" } then { + set skip $opt + } elseif { ![string match "-*" $opt] \ + && [file isfile $opt] } { + set opt "-Wl,$opt" + } + lappend nopts $opt + } + return $nopts +} + +# Add -Wl, before any file names in the target board's ldflags, libs, +# and ldscript, as well as in global testglue and wrap_flags, so that +# default object files or libraries do not change the names of gcc +# auxiliary outputs. + +proc gcc_adjust_linker_flags {} { + global gcc_adjusted_linker_flags + if {$gcc_adjusted_linker_flags} { + return + } + set gcc_adjusted_linker_flags 1 + + if {![is_remote host]} { + set dest [target_info name] + foreach i { ldflags libs ldscript } { + if {[board_info $dest exists $i]} { + set opts [board_info $dest $i] + set nopts [gcc_adjust_linker_flags_list $opts] + if { $nopts != $opts } { + unset_currtarget_info $i + set_currtarget_info $i "$nopts" + } + } + } + foreach i { gluefile wrap_flags } { + global $i + if {[info exists $i]} { + set opts [set $i] + set nopts [gcc_adjust_linker_flags_list $opts] + if { $nopts != $opts } { + set $i $nopts + } + } + } + } +} + +# Return an updated version of OPTIONS that mentions any additional +# source files registered with dg-additional-sources. SOURCE is the +# name of the test case. + +proc dg-additional-files-options { options source } { + gcc_adjust_linker_flags + + global additional_sources + global additional_sources_used + global additional_files + set to_download [list] + if { $additional_sources != "" } then { + if [is_remote host] { + lappend options "additional_flags=$additional_sources" + } + regsub -all "^| " $additional_sources " [file dirname $source]/" additional_sources + if ![is_remote host] { + lappend options "additional_flags=$additional_sources" + } + set to_download [concat $to_download $additional_sources] + set additional_sources_used "$additional_sources" + set additional_sources "" + # This option restores naming of aux and dump output files + # after input files when multiple input files are named, + # instead of getting them combined with the output name. + lappend options "additional_flags=-dumpbase \"\"" + } + if { $additional_files != "" } then { + regsub -all "^| " $additional_files " [file dirname $source]/" additional_files + set to_download [concat $to_download $additional_files] + set additional_files "" + } + if [is_remote host] { + foreach file $to_download { + remote_download host $file + } + } + + return $options +} + +# Return a colon-separate list of directories to search for libraries +# for COMPILER, including multilib directories. + +proc gcc-set-multilib-library-path { compiler } { + set shlib_ext [get_shlib_extension] + set options [lrange $compiler 1 end] + set compiler [lindex $compiler 0] + + set libgcc_s_x [remote_exec host "$compiler" \ + "$options -print-file-name=libgcc_s.${shlib_ext}"] + if { [lindex $libgcc_s_x 0] == 0 \ + && [set libgcc_s_dir [file dirname [lindex $libgcc_s_x 1]]] != "" } { + set libpath ":${libgcc_s_dir}" + } else { + return "" + } + + set multi_dir_x [remote_exec host "$compiler" \ + "$options -print-multi-directory"] + set multi_lib_x [remote_exec host "$compiler" \ + "$options -print-multi-lib"] + if { [lindex $multi_dir_x 0] == 0 && [lindex $multi_lib_x 0] == 0 } { + set multi_dir [string trim [lindex $multi_dir_x 1]] + set multi_lib [string trim [lindex $multi_lib_x 1]] + if { "$multi_dir" == "." } { + set multi_root "$libgcc_s_dir" + } else { + set multi_match [string last "/$multi_dir" "$libgcc_s_dir"] + if { "$multi_match" < 0 } { + return $libpath + } + set multi_root [string range "$libgcc_s_dir" \ + 0 [expr $multi_match - 1]] + } + foreach i "$multi_lib" { + set mldir "" + regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir + set mldir [string trimright $mldir "\;@"] + if { "$mldir" == "$multi_dir" } { + continue + } + append libpath ":${multi_root}/${mldir}" + } + } + + return $libpath +} + +# A list of all uses of dg-regexp, each entry of the form: +# line-number regexp +# This is cleared at the end of each test by gcc-dg.exp's wrapper for dg-test. +set freeform_regexps [] + +# Directive for looking for a regexp, without any line numbers or other +# prefixes. + +proc dg-regexp { args } { + verbose "dg-regexp: args: $args" 2 + + global freeform_regexps + lappend freeform_regexps $args +} + +# Hook to be called by prune.exp's prune_gcc_output to +# look for the expected dg-regexp expressions, pruning them, +# reporting PASS for those that are found, and FAIL for +# those that weren't found. +# +# It returns a pruned version of its output. + +proc handle-dg-regexps { text } { + global freeform_regexps + global testname_with_flags + + foreach entry $freeform_regexps { + verbose " entry: $entry" 3 + + set linenum [lindex $entry 0] + set rexp [lindex $entry 1] + + # Escape newlines in $rexp so that we can print them in + # pass/fail results. + set escaped_regex [string map {"\n" "\\n"} $rexp] + verbose "escaped_regex: ${escaped_regex}" 4 + + set title "$testname_with_flags dg-regexp $linenum" + + # Use "regsub" to attempt to prune the pattern from $text + if {[regsub -line $rexp $text "" text]} { + # Success; the multiline pattern was pruned. + pass "$title was found: \"$escaped_regex\"" + } else { + fail "$title not found: \"$escaped_regex\"" + } + } + + return $text +} + +# Verify that the initial arg is a valid .dot file +# (by running dot -Tpng on it, and verifying the exit code is 0). + +proc dg-check-dot { args } { + verbose "dg-check-dot: args: $args" 2 + + set testcase [testname-for-summary] + + set dotfile [lindex $args 0] + verbose " dotfile: $dotfile" 2 + + set status [remote_exec host "dot" "-O -Tpng $dotfile"] + verbose " status: $status" 2 + if { [lindex $status 0] != 0 } { + fail "$testcase dg-check-dot $dotfile" + return 0 + } + + pass "$testcase dg-check-dot $dotfile" +} + +# Used by aarch64-with-arch-dg-options to intercept dg-options and make +# the changes required. See there for details. +proc aarch64-arch-dg-options { args } { + upvar dg-do-what do_what + global aarch64_default_testing_arch + + set add_arch 1 + set add_tune 1 + set checks_output [string equal [lindex $do_what 0] "compile"] + set options [lindex $args 1] + + foreach option [split $options] { + switch -glob -- $option { + -march=* { set add_arch 0 } + -mcpu=* { set add_arch 0; set add_tune 0 } + -mtune=* { set add_tune 0 } + -moverride=* { set add_tune 0 } + -save-temps { set checks_output 1 } + --save-temps { set checks_output 1 } + -fdump* { set checks_output 1 } + } + } + + if { $add_arch && ![string equal $aarch64_default_testing_arch ""] } { + # Force SVE if we're not testing it already. + append options " $aarch64_default_testing_arch" + } + + if { $add_tune && $checks_output } { + # Turn off any default tuning and codegen tweaks. + append options " -mtune=generic -moverride=tune=none" + } + + uplevel 1 aarch64-old-dg-options [lreplace $args 1 1 $options] +} + +# Run Tcl code CODE with dg-options modified to work better for some +# AArch64 tests. In particular: +# +# - If the dg-options do not specify an -march or -mcpu option, +# use the architecture options in ARCH (which might be empty). +# +# - If the dg-options do not specify an -mcpu, -mtune or -moverride option, +# and if the test appears to be checking assembly or dump output, +# force the test to use generic tuning. +# +# The idea is to handle toolchains that are configured with a default +# CPU or architecture that's different from the norm. +proc aarch64-with-arch-dg-options { arch code } { + global aarch64_default_testing_arch + + set aarch64_default_testing_arch $arch + + rename dg-options aarch64-old-dg-options + rename aarch64-arch-dg-options dg-options + + uplevel 1 $code + + rename dg-options aarch64-arch-dg-options + rename aarch64-old-dg-options dg-options +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..5e8acb28bcad3a234a7e38be5c78236eb4eea370 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-dg.exp @@ -0,0 +1,1432 @@ +# Copyright (C) 1997-2022 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 +# . + +load_lib dg.exp +load_lib file-format.exp +load_lib target-supports.exp +load_lib target-supports-dg.exp +load_lib scanasm.exp +load_lib scanrtl.exp +load_lib scantree.exp +load_lib scanltranstree.exp +load_lib scanipa.exp +load_lib scanwpaipa.exp +load_lib scanlang.exp +load_lib timeout.exp +load_lib timeout-dg.exp +load_lib prune.exp +load_lib libgloss.exp +load_lib target-libpath.exp +load_lib torture-options.exp +load_lib fortran-modules.exp +load_lib multiline.exp + +# We set LC_ALL and LANG to C so that we get the same error messages as expected. +setenv LC_ALL C +setenv LANG C + +# Many hosts now default to a non-ASCII C locale, however, so +# they can set a charset encoding here if they need. +if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII +} + +# Avoid sporadic data-losses with expect +match_max -d 10000 + +# Ensure GCC_COLORS is unset, for the rare testcases that verify +# how output is colorized. +if [info exists ::env(GCC_COLORS) ] { + unsetenv GCC_COLORS +} + +global GCC_UNDER_TEST +if ![info exists GCC_UNDER_TEST] { + set GCC_UNDER_TEST "[find_gcc]" +} + +# This file may be sourced, so don't override environment settings +# that have been previously setup. +if { $orig_environment_saved == 0 } { + append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST] + set_ld_library_path_env_vars +} + +# Some torture-options cause intermediate code output, unusable for +# testing using e.g. scan-assembler. In this variable are the options +# how to force it, when needed. +global gcc_force_conventional_output +set gcc_force_conventional_output "" + +set LTO_TORTURE_OPTIONS "" +if [info exists TORTURE_OPTIONS] { + set DG_TORTURE_OPTIONS $TORTURE_OPTIONS +} else { + # It is theoretically beneficial to group all of the O2/O3 options together, + # as in many cases the compiler will generate identical executables for + # all of them--and the c-torture testsuite will skip testing identical + # executables multiple times. + # Also note that -finline-functions is explicitly included in one of the + # items below, even though -O3 is also specified, because some ports may + # choose to disable inlining functions by default, even when optimizing. + set DG_TORTURE_OPTIONS [list \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions } \ + { -O3 -g } \ + { -Os } ] + + if [check_effective_target_lto] { + # When having plugin test both slim and fat LTO and plugin/nonplugin + # path. + if [check_linker_plugin_available] { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -fno-use-linker-plugin -flto-partition=none } \ + { -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects } + ] + } else { + set LTO_TORTURE_OPTIONS [list \ + { -O2 -flto -flto-partition=none } \ + { -O2 -flto } + ] + } + set gcc_force_conventional_output "-ffat-lto-objects" + } +} + +if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set DG_TORTURE_OPTIONS \ + [concat $DG_TORTURE_OPTIONS $ADDITIONAL_TORTURE_OPTIONS] +} + +proc dg-final { args } { + upvar dg-final-code final-code + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + } + set line [lindex $args 0] + set code [lindex $args 1] + set directive [lindex $code 0] + switch $directive { + gdb-test { + set code [linsert $code 1 $line] + } + } + append final-code "$code\n" +} + +global orig_environment_saved + +# Deduce generated files from tool flags, return finalcode string +proc schedule-cleanups { opts } { + global additional_sources + set finalcode "" + set testcases {} + lappend testcases [lindex [testname-for-summary] 0] + verbose "Cleanup testcases: $testcases" 4 + if { [info exists additional_sources] && $additional_sources != "" } { + lappend testcases $additional_sources + verbose "Cleanup testcases, additional: $additional_sources" 4 + } + verbose "Cleanup all options: $opts" 4 + + # First some fixups to transform stuff to something manageable .. + # --dump= should translate to -d with joined operand. + if [regexp -- {(^|\s+)--dump=[^\s]+(\s+|$)} $opts] { + regsub -all -- {--dump=} $opts {-d} opts + } + # -da and -dx are treated as shorthand for -fdump-rtl-all here + if [regexp -- {(^|\s+)-d[ax](\s+|$)} $opts] { + verbose "Cleanup -d seen" 4 + lappend opts "-fdump-rtl-all" + } + # .. and don't question why there is --dump=? and -d? + + # Then handle options that generate non-dump files + # TODO + # -fprofile-generate -> cleanup-coverage-files() + # -fstack-usage -> cleanup-stack-usage() + if [regexp -- {(^|\s+)-fstack-usage(\s+|$)} $opts] { + verbose "Cleanup -fstack-usage seen" 4 +# append finalcode "cleanup-stack-usage\n" + } + global keep_saved_temps_suffixes + if [info exists keep_saved_temps_suffixes ] { + verbose "dg-keep-saved-temps ${keep_saved_temps_suffixes}" 2 + } + # -save-temps -> cleanup-saved-temps() + if [regexp -- {(^|\s+)-?-save-temps(\s+|$)} $opts] { + verbose "Cleanup -save-temps seen" 4 + if [info exists keep_saved_temps_suffixes] { + append finalcode "cleanup-saved-temps ${keep_saved_temps_suffixes}\n" + } else { + append finalcode "cleanup-saved-temps\n" + } + } else { + if [info exists keep_saved_temps_suffixes ] { + error "dg-keep-saved-temps specified but testcase does not -save-temps" + return + } + } + # Finally see if there are any dumps in opts, otherwise we are done + if [regexp -- {(?=(?:^|[ \t]+)?)-fdump-[^ \t]+(?=(?:$|[ \t]+)?)} $opts] { + # Lang, Ipa, Rtl, Tree for simplicity + set ptn "{l,i,r,t}" + } else { + return $finalcode + } + # stem.ext.. + # (tree)passes can have multiple instances, thus optional trailing * + set ptn "\[0-9\]\[0-9\]\[0-9\]$ptn.*" + # Handle ltrans files around -flto + if [regexp -- {(^|\s+)-flto(\s+|$)} $opts] { + verbose "Cleanup -flto seen" 4 + set ltrans "{ltrans\[0-9\]*.,}" + } else { + set ltrans "" + } + set ptn "$ltrans$ptn" + verbose "Cleanup final ptn: $ptn" 4 + set tfiles {} + foreach src $testcases { + set basename [file tail $src] + if { $ltrans != "" } { + # ??? should we use upvar 1 output_file instead of this (dup ?) + set stem [file rootname $basename] + set basename_ext [file extension $basename] + if {$basename_ext != ""} { + regsub -- {^.*\.} $basename_ext {} basename_ext + } + lappend tfiles "$stem.{$basename_ext,exe}" + unset basename_ext + } else { + lappend tfiles $basename + } + } + if { [llength $tfiles] > 1 } { + set tfiles [join $tfiles ","] + set tfiles "{$tfiles}" + } + verbose "Cleanup final testcases: $tfiles" 4 + # We have to quote the regex + regsub -all {([][$^?+*()|\\{}])} "$tfiles.$ptn" {\\\1} ptn + set final "" + append final {remove-build-file } + append final "\"$ptn\"" + verbose "Cleanup final: $final" 4 + append finalcode "$final\n" + + return $finalcode +} + +# Define gcc callbacks for dg.exp. + +proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { + # Set up the compiler flags, based on what we're going to do. + + set options [list] + + switch $do_what { + "preprocess" { + set compile_type "preprocess" + set output_file "[file rootname [file tail $prog]].i" + } + "compile" { + set compile_type "assembly" + set output_file "[file rootname [file tail $prog]].s" + } + "assemble" { + set compile_type "object" + set output_file "[file rootname [file tail $prog]].o" + } + "precompile" { + set compile_type "precompiled_header" + set output_file "[file tail $prog].gch" + } + "link" { + set compile_type "executable" + set output_file "[file rootname [file tail $prog]].exe" + # The following line is needed for targets like the i960 where + # the default output file is b.out. Sigh. + } + "repo" { + set compile_type "object" + set output_file "[file rootname [file tail $prog]].o" + } + "run" { + set compile_type "executable" + # FIXME: "./" is to cope with "." not being in $PATH. + # Should this be handled elsewhere? + # YES. + set output_file "./[file rootname [file tail $prog]].exe" + # This is the only place where we care if an executable was + # created or not. If it was, dg.exp will try to run it. + catch { remote_file build delete $output_file } + } + default { + perror "$do_what: not a valid dg-do keyword" + return "" + } + } + + # Let { dg-final { action } } force options as returned by an + # optional proc ${action}_required_options. + upvar 2 dg-final-code finalcode + foreach x [split $finalcode "\n"] { + set finalcmd [lindex $x 0] + if { [info procs ${finalcmd}_required_options] != "" } { + foreach req [${finalcmd}_required_options] { + if { $req != "" + && [lsearch -exact $extra_tool_flags $req] == -1 } { + lappend extra_tool_flags $req + } + } + } + } + + append finalcode [schedule-cleanups "$options $extra_tool_flags"] + if { $extra_tool_flags != "" } { + lappend options "additional_flags=$extra_tool_flags" + } + + verbose "$target_compile $prog $output_file $compile_type $options" 4 + set comp_output [$target_compile "$prog" "$output_file" "$compile_type" $options] + + global expect_ice + # Look for an internal compiler error, which sometimes masks the fact + # that we didn't get an expected error message. XFAIL an ICE via + # dg-xfail-if and use { dg-prune-output ".*internal compiler error.*" } + # to avoid a second failure for excess errors. + # "Error reporting routines re-entered" ICE says "Internal" rather than + # "internal", so match that too. + if [regexp -line -- {[Ii]nternal compiler error.*} $comp_output ice] { + upvar 2 name name + if { $expect_ice == 0 } { + fail "$name ($ice)" + } else { + # We expected an ICE and we got it. + xfail "$name ($ice)" + # Prune the ICE from the output. + set comp_output [prune_ices $comp_output] + } + } elseif { $expect_ice == 1 } { + upvar 2 name name + # We expected an ICE but we didn't get it. + xpass "$name (internal compiler error)" + } + + if { $do_what == "repo" } { + set object_file "$output_file" + set output_file "[file rootname [file tail $prog]].exe" + set comp_output \ + [ concat $comp_output \ + [$target_compile "$object_file" "$output_file" \ + "executable" $options] ] + } + + return [list $comp_output $output_file] +} + +proc gcc-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 gcc_target_compile $prog $do_what $extra_tool_flags] +} + +# Global: should blank lines be allowed in the output? +# By default, they should not be. (PR other/69006) +# However, there are some ways for them to validly occur. +# If this variable is 0, blank lines are not allowed in output, +# if it is 1, they are allowed for a single testcase only and gcc-dg-prune +# will clear it again after checking it, if it is 2, they are disabled +# for all tests. +set allow_blank_lines 0 + +if { [check_effective_target_llvm_binutils] } { + set allow_blank_lines 2 +} + +# A command for use by testcases to mark themselves as expecting +# blank lines in the output. + +proc dg-allow-blank-lines-in-output { args } { + global allow_blank_lines + if { !$allow_blank_lines } { + set allow_blank_lines 1 + } +} + +proc gcc-dg-prune { system text } { + global additional_prunes + + # Extra prune rules that will apply to tests defined in a .exp file. + # Always remember to clear it in .exp file after executed all tests. + global dg_runtest_extra_prunes + + # Complain about blank lines in the output (PR other/69006) + global allow_blank_lines + if { !$allow_blank_lines } { + set num_blank_lines [llength [regexp -all -inline "\n\n" $text]] + if { $num_blank_lines } { + global testname_with_flags + fail "$testname_with_flags $num_blank_lines blank line(s) in output" + } + } + if { $allow_blank_lines == 1 } { + set allow_blank_lines 0 + } + + set text [prune_gcc_output $text] + + foreach p "$additional_prunes $dg_runtest_extra_prunes" { + if { [string length $p] > 0 } { + # Following regexp matches a complete line containing $p. + regsub -all "(^|\n)\[^\n\]*$p\[^\n\]*" $text "" text + } + } + + # If we see "region xxx is full" then the testcase is too big for ram. + # This is tricky to deal with in a large testsuite like c-torture so + # deal with it here. Just mark the testcase as unsupported. + if [regexp "(^|\n)\[^\n\]*: region \[^\n\]* is full" $text] { + # The format here is important. See dg.exp. + return "::unsupported::memory full" + } + + if { [regexp "(^|\n)\[^\n\]*: relocation truncated to fit" $text] + && [check_effective_target_tiny] } { + return "::unsupported::memory full" + } + + if [regexp "(^|\n)\[^\n\]* section.*will not fit in region" $text] { + return "::unsupported::memory full" + } + + if [regexp "(^|\n)\[^\n\]* region.*overflowed by" $text] { + return "::unsupported::memory full" + } + + if { [string match "*error: function pointers not supported*" $text] + && ![check_effective_target_function_pointers] } { + # The format here is important. See dg.exp. + return "::unsupported::funcptr" + } + if { [string match "*error: large return values not supported*" $text] + && ![check_effective_target_large_return_values] } { + # The format here is important. See dg.exp. + return "::unsupported::large return values" + } + + # If exceptions are disabled, mark tests expecting exceptions to be enabled + # as unsupported. + if { ![check_effective_target_exceptions_enabled] } { + if [regexp "(^|\n)\[^\n\]*: error: exception handling disabled" $text] { + return "::unsupported::exception handling disabled" + } + + if [regexp "(^|\n)\[^\n\]*: error: #error .__cpp_exceptions." $text] { + return "::unsupported::exception handling disabled" + } + } + + return $text +} + +# Replace ${tool}_load with a wrapper to provide for an expected nonzero +# exit status. Multiple languages include this file so this handles them +# all, not just gcc. +if { [info procs ${tool}_load] != [list] \ + && [info procs saved_${tool}_load] == [list] } { + rename ${tool}_load saved_${tool}_load + + proc ${tool}_load { program args } { + global tool + global shouldfail + global set_target_env_var + + set saved_target_env_var [list] + if { [info exists set_target_env_var] \ + && [llength $set_target_env_var] != 0 } { + if { [is_remote target] } { + return [list "unsupported" ""] + } + set-target-env-var + } + set result [eval [list saved_${tool}_load $program] $args] + if { [info exists set_target_env_var] \ + && [llength $set_target_env_var] != 0 } { + restore-target-env-var + } + if { $shouldfail != 0 } { + switch [lindex $result 0] { + "pass" { set status "fail" } + "fail" { set status "pass" } + default { set status [lindex $result 0] } + } + set result [list $status [lindex $result 1]] + } + + set result [list [lindex $result 0] [prune_file_path [lindex $result 1]]] + return $result + } +} + +proc dg-set-target-env-var { args } { + global set_target_env_var + if { [llength $args] != 3 } { + error "dg-set-target-env-var: need two arguments" + return + } + set var [lindex $args 1] + set value [lindex $args 2] + verbose "dg-set-target-env-var $var $value" 2 + lappend set_target_env_var [list $var $value] +} + +proc set-target-env-var { } { + global set_target_env_var + upvar 1 saved_target_env_var saved_target_env_var + foreach env_var $set_target_env_var { + set var [lindex $env_var 0] + set value [lindex $env_var 1] + if [info exists ::env($var)] { + lappend saved_target_env_var [list $var 1 $::env($var)] + } else { + lappend saved_target_env_var [list $var 0] + } + setenv $var $value + } +} + +proc restore-target-env-var { } { + upvar 1 saved_target_env_var saved_target_env_var + for { set env_vari [llength $saved_target_env_var] } { + [incr env_vari -1] >= 0 } {} { + set env_var [lindex $saved_target_env_var $env_vari] + set var [lindex $env_var 0] + if [lindex $env_var 1] { + setenv $var [lindex $env_var 2] + } else { + unsetenv $var + } + } +} + +proc dg-set-compiler-env-var { args } { + global set_compiler_env_var + global saved_compiler_env_var + if { [llength $args] != 3 } { + error "dg-set-compiler-env-var: need two arguments" + return + } + set var [lindex $args 1] + set value [lindex $args 2] + verbose "dg-set-compiler-env-var $var $value" 2 + if [info exists ::env($var)] { + lappend saved_compiler_env_var [list $var 1 $::env($var)] + } else { + lappend saved_compiler_env_var [list $var 0] + } + setenv $var $value + lappend set_compiler_env_var [list $var $value] +} + +proc restore-compiler-env-var { } { + global saved_compiler_env_var + for { set env_vari [llength $saved_compiler_env_var] } { + [incr env_vari -1] >= 0 } {} { + set env_var [lindex $saved_compiler_env_var $env_vari] + set var [lindex $env_var 0] + if [lindex $env_var 1] { + setenv $var [lindex $env_var 2] + } else { + unsetenv $var + } + } +} + +# Utility routines. + +# +# search_for -- looks for a string match in a file +# +proc search_for { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc gcc-dg-runtest { testcases flags default-extra-flags } { + global runtests + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS LTO_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS [list {}] $LTO_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + global torture_with_loops torture_without_loops + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + global torture_current_flags + set torture_current_flags "$flags_t" + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} + +# Check if frontend has CTF support +proc gcc-dg-frontend-supports-ctf { target_compile trivial } { + global srcdir subdir + + set comp_output [$target_compile \ + "$srcdir/$subdir/$trivial" "trivial.S" assembly \ + "additional_flags=-gctf"] + if { ! [string match \ + "*CTF debug info requested, but not supported for * frontend*" \ + $comp_output] } { + remove-build-file "trivial.S" + return 1 + } + return 0 +} + +# Check if the target system supports the debug format +proc gcc-dg-target-supports-debug-format { target_compile trivial type } { + global srcdir subdir + + set comp_output [$target_compile \ + "$srcdir/$subdir/$trivial" "trivial.S" assembly \ + "additional_flags=$type"] + if { ! [string match "*: target system does not support the * debug format*" \ + $comp_output] } { + remove-build-file "trivial.S" + return 1 + } + return 0 +} + +proc gcc-dg-debug-runtest { target_compile trivial opt_opts testcases } { + if ![info exists DEBUG_TORTURE_OPTIONS] { + set DEBUG_TORTURE_OPTIONS "" + foreach type {-gctf -gdwarf-2} { + if [expr [gcc-dg-target-supports-debug-format \ + $target_compile $trivial $type]] { + if { $type == "-gctf" } { + if [expr [gcc-dg-frontend-supports-ctf \ + $target_compile $trivial]] { + # At this time, running tests with various opt levels or + # ctf debug info levels does not add value. + lappend DEBUG_TORTURE_OPTIONS [list "${type}"] + } + continue + } + foreach level {1 "" 3} { + if { ($type == "-gdwarf-2") && ($level != "") } { + lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}" "-g${level}" "$opt" ] + } + } else { + lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}${level}" "$opt" ] + } + } + } + } + } + } + + verbose -log "Using options $DEBUG_TORTURE_OPTIONS" + + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags $DEBUG_TORTURE_OPTIONS { + set doit 1 + + # These tests check for information which may be deliberately + # suppressed at -g1. + if { ([string match {*/debug-[126].c} "$nshort"] \ + || [string match {*/enum-1.c} "$nshort"] \ + || [string match {*/enum-[12].C} "$nshort"]) \ + && ([string match "*1" [lindex "$flags" 0] ] + || [lindex "$flags" 1] == "-g1") } { + set doit 0 + } + + # High optimization can remove the variable whose existence is tested. + # Dwarf debugging with commentary (-dA) preserves the symbol name in the + # assembler output, but stabs debugging does not. + # http://gcc.gnu.org/ml/gcc-regression/2003-04/msg00095.html + if { [string match {*/debug-[12].c} "$nshort"] \ + && [string match "*O*" "$flags"] \ + && ( [string match "*coff*" "$flags"] \ + || [string match "*stabs*" "$flags"] ) } { + set doit 0 + } + + # These tests check for information which is not emitted for CTF + # as CTF type information is emitted for entities at file and + # global scope only. + if { ([string match {*/debug-[126].c} "$nshort"] \ + || [string match {*/enum-[12].C} "$nshort"] ) \ + && [string match "*ctf*" "$flags"] } { + set doit 0 + } + + if { $doit } { + verbose -log "Testing $nshort, $flags" 1 + dg-test $test $flags "" + } + } + } +} + +# Prune any messages matching ARGS[1] (a regexp) from test output. +proc dg-prune-output { args } { + global additional_prunes + + if { [llength $args] != 2 } { + error "[lindex $args 1]: need one argument" + return + } + + lappend additional_prunes [lindex $args 1] +} + +# Remove files matching the pattern from the build machine. +proc remove-build-file { pat } { + verbose "remove-build-file `$pat'" 2 + set file_list "[glob -nocomplain $pat]" + verbose "remove-build-file `$file_list'" 2 + foreach output_file $file_list { + if [is_remote host] { + # Ensure the host knows the file is gone by deleting there + # first. + remote_file host delete $output_file + } + remote_file build delete $output_file + } +} + +# Remove runtime-generated profile file for the current test. +proc cleanup-profile-file { } { + remove-build-file "mon.out" + remove-build-file "gmon.out" +} + +# Remove compiler-generated coverage files for the current test. +proc cleanup-coverage-files { } { + global additional_sources_used + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + remove-build-file "[file rootname [file tail $testcase]].gc??" + + # Clean up coverage files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[file rootname [file tail $srcfile]].gc??" + } + } +} + +# Remove a final insns dump file for the current test. +proc cleanup-final-insns-dump { } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + remove-build-file "[file rootname [file tail $testcase]].s.gkd" + + # Clean up files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[file rootname [file tail $srcfile]].s.gkd" + } + } +} + +# Remove a stack usage file for the current test. +proc cleanup-stack-usage { } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + remove-build-file "[file rootname [file tail $testcase]].su" + + # Clean up files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[file rootname [file tail $srcfile]].su" + } + } +} + +# Remove an Ada spec file for the current test. +proc cleanup-ada-spec { } { + global additional_sources_used + set testcase [testname-for-summary] + remove-build-file "[get_ada_spec_filename $testcase]" + + # Clean up files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + remove-build-file "[get_ada_spec_filename $srcfile]" + } + } +} + +# Remove files kept by --save-temps for the current test. +# +# Currently this is only .i, .ii, .s and .o files, but more can be added +# if there are tests generating them. +# ARGS is a list of suffixes to NOT delete. +proc cleanup-saved-temps { args } { + global additional_sources_used + set suffixes {} + + # add the to-be-kept suffixes + foreach suffix {".mii" ".ii" ".i" ".s" ".o" ".gkd" ".res" ".ltrans.out"} { + if {[lsearch $args $suffix] < 0} { + lappend suffixes $suffix + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set testcase [lindex $testcase 0] + foreach suffix $suffixes { + remove-build-file "[file rootname [file tail $testcase]]$suffix" + remove-build-file "[file rootname [file tail $testcase]].exe$suffix" + remove-build-file "[file rootname [file tail $testcase]].exe.ltrans\[0-9\]*$suffix" + # -fcompare-debug dumps + remove-build-file "[file rootname [file tail $testcase]].gk$suffix" + } + + # Clean up saved temp files for additional source files. + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + foreach suffix $suffixes { + remove-build-file "[file rootname [file tail $srcfile]]$suffix" + remove-build-file "[file rootname [file tail $srcfile]].exe$suffix" + remove-build-file "[file rootname [file tail $srcfile]].exe.ltrans\[0-9\]*$suffix" + + # -fcompare-debug dumps + remove-build-file "[file rootname [file tail $srcfile]].gk$suffix" + } + } + } +} + + +# Files to be kept after cleanup of --save-temps for the current test. +# ARGS is a list of suffixes to NOT delete. +proc dg-keep-saved-temps { args } { + global keep_saved_temps_suffixes + set keep_saved_temps_suffixes {} + + # add the to-be-kept suffixes + foreach suffix {".mii" ".ii" ".i" ".s" ".o" ".gkd" ".res" ".ltrans.out"} { + if {[lsearch $args $suffix] >= 0} { + lappend keep_saved_temps_suffixes $suffix + } + } + if { [llength keep_saved_temps_suffixes] < 1 } { + error "dg-keep-saved-temps ${args} did not match any known suffix" + } +} + +# Scan Fortran modules for a given regexp. +# +# Argument 0 is the module name +# Argument 1 is the regexp to match +proc scan-module { args } { + set modfilename [string tolower [lindex $args 0]].mod + set fd [open [list | gzip -dc $modfilename] r] + set text [read $fd] + close $fd + + set testcase [testname-for-summary] + if [regexp -- [lindex $args 1] $text] { + pass "$testcase scan-module [lindex $args 1]" + } else { + fail "$testcase scan-module [lindex $args 1]" + } +} + +# Scan Fortran modules for absence of a given regexp. +# +# Argument 0 is the module name +# Argument 1 is the regexp to match +proc scan-module-absence { args } { + set modfilename [string tolower [lindex $args 0]].mod + set fd [open [list | gzip -dc $modfilename] r] + set text [read $fd] + close $fd + + set testcase [testname-for-summary] + if [regexp -- [lindex $args 1] $text] { + fail "$testcase scan-module [lindex $args 1]" + } else { + pass "$testcase scan-module [lindex $args 1]" + } +} + +# Verify that the compiler output file exists, invoked via dg-final. +proc output-exists { args } { + # Process an optional target or xfail list. + if { [llength $args] >= 1 } { + switch [dg-process-target [lindex $args 0]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # Access variable from gcc-dg-test-1. + upvar 2 output_file output_file + + if [file exists $output_file] { + pass "$testcase output-exists $output_file" + } else { + fail "$testcase output-exists $output_file" + } +} + +# Verify that the compiler output file does not exist, invoked via dg-final. +proc output-exists-not { args } { + # Process an optional target or xfail list. + if { [llength $args] >= 1 } { + switch [dg-process-target [lindex $args 0]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # Access variable from gcc-dg-test-1. + upvar 2 output_file output_file + + if [file exists $output_file] { + fail "$testcase output-exists-not $output_file" + } else { + pass "$testcase output-exists-not $output_file" + } +} + +# We need to make sure that additional_* are cleared out after every +# test. It is not enough to clear them out *before* the next test run +# because gcc-target-compile gets run directly from some .exp files +# (outside of any test). (Those uses should eventually be eliminated.) + +# Because the DG framework doesn't provide a hook that is run at the +# end of a test, we must replace dg-test with a wrapper. + +if { [info procs saved-dg-test] == [list] } { + rename dg-test saved-dg-test + + # Helper function for cleanups that should happen after the call + # to the real dg-test, whether or not it returns normally, or + # fails with an error. + proc cleanup-after-saved-dg-test { } { + global additional_files + global additional_sources + global additional_sources_used + global additional_prunes + global compiler_conditional_xfail_data + global shouldfail + global expect_ice + global testname_with_flags + global set_target_env_var + global set_compiler_env_var + global saved_compiler_env_var + global keep_saved_temps_suffixes + global nn_line_numbers_enabled + global multiline_expected_outputs + global freeform_regexps + global save_linenr_varnames + + set additional_files "" + set additional_sources "" + set additional_sources_used "" + set additional_prunes "" + set shouldfail 0 + set expect_ice 0 + if [info exists set_target_env_var] { + unset set_target_env_var + } + if [info exists set_compiler_env_var] { + restore-compiler-env-var + unset set_compiler_env_var + unset saved_compiler_env_var + } + if [info exists keep_saved_temps_suffixes] { + unset keep_saved_temps_suffixes + } + unset_timeout_vars + if [info exists compiler_conditional_xfail_data] { + unset compiler_conditional_xfail_data + } + if [info exists testname_with_flags] { + unset testname_with_flags + } + set nn_line_numbers_enabled 0 + set multiline_expected_outputs [] + set freeform_regexps [] + + if { [info exists save_linenr_varnames] } { + foreach varname $save_linenr_varnames { + # Cleanup varname + eval global $varname + eval unset $varname + + # Cleanup varname_used, or generate defined-but-not-used + # warning. + set varname_used used_$varname + eval global $varname_used + eval set used [info exists $varname_used] + if { $used } { + eval unset $varname_used + } else { + regsub {^saved_linenr_} $varname "" org_varname + warning "dg-line var $org_varname defined, but not used" + } + } + unset save_linenr_varnames + } + + initialize_prune_notes + } + + proc dg-test { args } { + global errorInfo + + if { [ catch { eval saved-dg-test $args } errmsg ] } { + set saved_info $errorInfo + cleanup-after-saved-dg-test + error $errmsg $saved_info + } + cleanup-after-saved-dg-test + } +} + +if { [info procs saved-dg-warning] == [list] \ + && [info exists gcc_warning_prefix] } { + rename dg-warning saved-dg-warning + + proc dg-warning { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + global gcc_warning_prefix + + process-message saved-dg-warning "$gcc_warning_prefix" "$args" + } +} + +if { [info procs saved-dg-error] == [list] \ + && [info exists gcc_error_prefix] } { + rename dg-error saved-dg-error + + proc dg-error { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + global gcc_error_prefix + + process-message saved-dg-error "$gcc_error_prefix" "$args" + } + + # Override dg-bogus at the same time. It doesn't handle a prefix + # but its expression should include a column number. Otherwise the + # line number can match the column number for other messages, leading + # to insanity. + rename dg-bogus saved-dg-bogus + + proc dg-bogus { args } { + upvar dg-messages dg-messages + process-message saved-dg-bogus "" $args + } +} + +# Set variable VARNAME to LINENR + +proc dg-line { linenr varname } { + set org_varname $varname + set varname "saved_linenr_$varname" + eval global $varname + + # Generate defined-but-previously-defined error. + eval set var_defined [info exists $varname] + if { $var_defined } { + eval set deflinenr \$$varname + error "dg-line var $org_varname defined at line $linenr, but previously defined at line $deflinenr" + return + } + + eval set $varname $linenr + + # Schedule cleanup of varname by cleanup-after-saved-dg-test + global save_linenr_varnames + if { [info exists save_linenr_varnames] } { + lappend save_linenr_varnames $varname + } else { + set save_linenr_varnames [list $varname] + } +} + +# Get the absolute line number corresponding to: +# - a relative line number (a non-null useline is required), or +# - a line number variable reference. +# Argument 0 is the line number on which line was used +# Argument 1 is the relative line number or line number variable reference +# +proc get-absolute-line { useline line } { + if { "$line" == "." } { + return $useline + } + + if { [regsub "^\.\[+-\](\[0-9\]+)$" $line "\\1" num] && $useline != "" } { + # Handle relative line specification, .+1 or .-1 etc. + set num [expr $useline [string index $line 1] $num] + return $num + } + + if { ! [regsub "^(\[a-zA-Z\]\[a-zA-Z0-9_\]*)$" $line "\\1" varname] } { + return $line + } + + # Handle linenr variable defined by dg-line + set org_varname $varname + set varname "saved_linenr_$varname" + eval global $varname + + # Generate used-but-not-defined error. + eval set var_defined [info exists $varname] + if { ! $var_defined } { + if { "$useline" != "" } { + error "dg-line var $org_varname used at line $useline, but not defined" + } else { + error "dg-line var $org_varname used, but not defined" + } + return + } + + # Note that varname has been used. + set varname_used "used_$varname" + eval global $varname_used + eval set $varname_used 1 + + # Get line number from var and use it. + eval set num \$$varname + set line $num +} + +# Modify the regular expression saved by a DejaGnu message directive to +# include a prefix and to force the expression to match a single line. +# MSGPROC is the procedure to call. +# MSGPREFIX is the prefix to prepend. +# DGARGS is the original argument list. + +proc process-message { msgproc msgprefix dgargs } { + upvar dg-messages dg-messages + + if { [llength $dgargs] == 5 } { + set useline [lindex $dgargs 0] + + # Resolve absolute line number. + set line [get-absolute-line $useline [lindex $dgargs 4]] + set dgargs [lreplace $dgargs 4 4 $line] + + if { $line != $useline } { + # Make sure that we get unique test names if different USELINEs + # refer to the same LINE. + set comment "[lindex $dgargs 2] at line $useline" + set dgargs [lreplace $dgargs 2 2 $comment] + } + } + + # Process the dg- directive, including adding the regular expression + # to the new message entry in dg-messages. + set msgcnt [llength ${dg-messages}] + eval $msgproc $dgargs + + # If the target expression wasn't satisfied there is no new message. + if { [llength ${dg-messages}] == $msgcnt } { + return; + } + + # Get the entry for the new message. Prepend the message prefix to + # the regular expression and make it match a single line. + set newentry [lindex ${dg-messages} end] + set expmsg [lindex $newentry 2] + + set column "" + # Handle column numbers from the specified expression (if there is + # one) and set up the search expression that will be used by DejaGnu. + if [regexp {^-:} $expmsg] { + # The expected column is -, so shouldn't appear. + set expmsg [string range $expmsg 2 end] + } elseif [regexp {^[0-9]+:} $expmsg column] { + # The expression in the directive included a column number. + # Remove it from the original expression and move it + # to the proper place in the search expression. + set expmsg [string range $expmsg [string length $column] end] + set column "$column " + } elseif [string match "" [lindex $newentry 0]] { + # The specified line number is 0; don't expect a column number. + } else { + # There is no column number in the search expression, but we + # should expect one in the message itself. + set column {[0-9]+: } + } + set expmsg "$column$msgprefix\[^\n\]*$expmsg" + set newentry [lreplace $newentry 2 2 $expmsg] + + set dg-messages [lreplace ${dg-messages} end end $newentry] + verbose "process-message:\n${dg-messages}" 3 +} + +# Look for messages that don't have standard prefixes. + +proc dg-message { args } { + upvar dg-messages dg-messages + process-message saved-dg-warning "" $args +} + +# Look for a location marker of the form +# file:line:column: +# with no extra text (e.g. a line-span separator). + +proc dg-locus { args } { + upvar dg-messages dg-messages + + # Process the dg- directive, including adding the regular expression + # to the new message entry in dg-messages. + set msgcnt [llength ${dg-messages}] + eval saved-dg-warning $args + + # If the target expression wasn't satisfied there is no new message. + if { [llength ${dg-messages}] == $msgcnt } { + return; + } + + # Get the entry for the new message. Prepend the message prefix to + # the regular expression and make it match a single line. + set newentry [lindex ${dg-messages} end] + set expmsg [lindex $newentry 2] + + set newentry [lreplace $newentry 2 2 $expmsg] + set dg-messages [lreplace ${dg-messages} end end $newentry] + verbose "process-message:\n${dg-messages}" 3 +} + +# Handle output from -fopt-info for MSG_OPTIMIZED_LOCATIONS: +# a successful optimization. + +proc dg-optimized { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + + process-message saved-dg-warning "optimized:" "$args" +} + +# Handle output from -fopt-info for MSG_MISSED_OPTIMIZATION: +# a missed optimization. + +proc dg-missed { args } { + # Make this variable available here and to the saved proc. + upvar dg-messages dg-messages + + process-message saved-dg-warning "missed:" "$args" +} + +# Look for messages with 'note: ' prefixes. +# In addition to standard compiler diagnostics ('DK_NOTE', 'inform' functions, +# "for additional details on an error message"), +# this also includes output from '-fopt-info' for 'MSG_NOTE': +# a general optimization info. +# By default, any *excess* notes are pruned, meaning their appearance doesn't +# trigger *excess errors*. However, if 'dg-note' is used at least once in a +# testcase, they're not pruned and instead must *all* be handled explicitly. +# Thus, if looking for just single instances of messages with 'note: ' prefixes +# without caring for all of them, use 'dg-message "note: [...]"' instead of +# 'dg-note', or use 'dg-note' together with 'dg-prune-output "note: "'. + +variable prune_notes + +proc initialize_prune_notes { } { + global prune_notes + set prune_notes 1 +} + +initialize_prune_notes + +proc dg-note { args } { + upvar dg-messages dg-messages + + global prune_notes + set prune_notes 0 + + process-message saved-dg-warning "note:" "$args" +} + +# Check the existence of a gdb in the path, and return true if there +# is one. +# +# Set env(GDB_FOR_GCC_TESTING) accordingly. + +proc gdb-exists { args } { + if ![info exists ::env(GDB_FOR_GCC_TESTING)] { + global GDB + if ![info exists ::env(GDB_FOR_GCC_TESTING)] { + if [info exists GDB] { + setenv GDB_FOR_GCC_TESTING "$GDB" + } else { + setenv GDB_FOR_GCC_TESTING "[transform gdb]" + } + } + } + if { [which $::env(GDB_FOR_GCC_TESTING)] != 0 } { + return 1; + } + return 0; +} + +# Helper function for scan-symbol and scan-symbol-not. It scans a symbol in +# the final executable and return 1 if present, otherwise fail. +# +# Argument 0 is the regexp to match. +# Argument 1 handles expected failures and the like +proc scan-symbol-common { scan_directive args } { + global nm + global base_dir + + # Access variable from gcc-dg-test-1 or lto-execute. + upvar 3 output_file output_file + + if { [llength $args] >= 2 } { + switch [dg-process-target [lindex $args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find nm like we find g++ in g++.exp. + if ![info exists nm] { + set nm [findfile $base_dir/../../../binutils/nm \ + $base_dir/../../../binutils/nm \ + [findfile $base_dir/../../nm $base_dir/../../nm \ + [findfile $base_dir/nm $base_dir/nm \ + [transform nm]]]] + verbose -log "nm is $nm" + } + + set output_file "[glob -nocomplain $output_file]" + if { $output_file == "" } { + fail "$scan_directive $args: output file does not exist" + return + } + + set fd [open "| $nm $output_file" r] + set text [read $fd] + close $fd + + if [regexp -- [lindex $args 0] $text] { + return 1 + } else { + return 0 + } +} + +# Utility for scanning a symbol in the final executable, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match. +# Argument 1 handles expected failures and the like +proc scan-symbol { args } { + set testcase [testname-for-summary] + if { [scan-symbol-common "scan-symbol" $args]} { + pass "$testcase scan-symbol $args" + } else { + fail "$testcase scan-symbol $args" + } +} + +# Utility for scanning a symbol in the final executable, invoked via dg-final. +# Call pass if pattern is absent, otherwise fail. +# +# Argument 0 is the regexp to match. +# Argument 1 handles expected failures and the like +proc scan-symbol-not { args } { + set testcase [testname-for-summary] + if { [scan-symbol-common "scan-symbol-not" $args]} { + fail "$testcase scan-symbol-not $args" + } else { + pass "$testcase scan-symbol-not $args" + } +} + +set additional_prunes "" +set dg_runtest_extra_prunes "" diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-gdb-test.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-gdb-test.exp new file mode 100644 index 0000000000000000000000000000000000000000..8b355797b3b9e7279987bd22d58ce558548c772a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc-gdb-test.exp @@ -0,0 +1,183 @@ +# Copyright (C) 2009-2022 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 +# . + +# Utility for testing variable values using gdb, invoked via dg-final. +# Call pass if variable has the desired value, otherwise fail. +# +# Argument 0 is the line number on which to put a breakpoint +# Argument 1 is the name of the variable to be checked +# possibly prefixed with type: to get the type of the variable +# instead of the value of the variable (the default). +# Argument 2 is the expected value (or type) of the variable +# When asking for the value, the expected value is produced +# calling print on it in gdb. When asking for the type it is +# the literal string with extra whitespace removed. +# Argument 3 handles expected failures and the like +proc gdb-test { useline args } { + if { ![isnative] || [is_remote target] } { return } + + if { [llength $args] >= 4 } { + switch [dg-process-target [lindex $args 3]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # This assumes that we are three frames down from dg-test, and that + # it still stores the filename of the testcase in a local variable "name". + # A cleaner solution would require a new DejaGnu release. + upvar 2 name testcase + upvar 2 prog prog + + # The command to run on the variable + set arg1 [lindex $args 1] + if { [string equal -length 5 "type:" $arg1] == 1 } { + set command "ptype" + set var [string range $arg1 5 end] + } else { + set command "print" + set var $arg1 + } + + set line [lindex $args 0] + if { [string range $line 0 0] == "@" } { + set line [string range $line 1 end] + } else { + set line [get-absolute-line $useline $line] + } + + set gdb_name $::env(GUALITY_GDB_NAME) + set testname "$testcase line $line [lindex $args 1] == [lindex $args 2]" + set output_file "[file rootname [file tail $prog]].exe" + set cmd_file "[file rootname [file tail $prog]].gdb" + + set fd [open $cmd_file "w"] + puts $fd "break $line" + puts $fd "run" + puts $fd "$command $var" + if { $command == "print" } { + # For values, let gdb interpret them by printing them. + puts $fd "print [lindex $args 2]" + } else { + # Since types can span multiple lines, we need an end marker. + puts $fd "echo TYPE_END\\n" + } + puts $fd "quit" + close $fd + + send_log "Spawning: $gdb_name -nx -nw -quiet -batch -x $cmd_file ./$output_file\n" + set res [remote_spawn target "$gdb_name -nx -nw -quiet -batch -x $cmd_file ./$output_file"] + if { $res < 0 || $res == "" } { + unsupported "$testname" + file delete $cmd_file + return + } + + remote_expect target [timeout_value] { + # Too old GDB + -re "Unhandled dwarf expression|Error in sourced command file|. + +load_lib timeout.exp + +# Utility for running a given test through the simulate-thread harness +# using gdb. This is invoked via dg-final. +# +# Adapted from the guality harness. +# +# Call 'fail' if a given test printed "FAIL:", otherwise call 'pass'. + +proc simulate-thread { args } { + if { ![isnative] || [is_remote target] } { return } + + if { [llength $args] == 1 } { + switch [dg-process-target [lindex $args 0]] { + "F" { setup_xfail "*-*-*" } + } + } + + # This assumes that we are three frames down from dg-test, and that + # it still stores the filename of the testcase in a local variable "name". + # A cleaner solution would require a new DejaGnu release. + upvar 2 name testcase + upvar 2 prog prog + upvar 2 srcdir testsuite_dir + + set gdb_name $::env(GDB_FOR_GCC_TESTING) + set exec_file "[file rootname [file tail $prog]].exe" + set cmd_file "$testsuite_dir/gcc.dg/simulate-thread/simulate-thread.gdb" + + if ![file exists $exec_file] { + return + } + + set message "thread simulation test" + + send_log "Spawning: $gdb_name -nx -nw -batch -x $cmd_file ./$exec_file\n" + set res [remote_spawn target "$gdb_name -nx -nw -batch -x $cmd_file ./$exec_file"] + if { $res < 0 || $res == "" } { + unsupported "$testcase $message" + return + } + + set gdb_worked 0 + + remote_expect target [timeout_value] { + # Too old GDB + -re "Unhandled dwarf expression|Error in sourced command file" { + unsupported "$testcase $message" + remote_close target + return + } + -re "FAIL:" { + fail "$testcase $message" + remote_close target + return + } + # If the gdb output contained simulate_thread_done, assume + # that at the very least, we had a working gdb that was able + # to break in simulate_thread_done. + -re "simulate_thread_done" { + set gdb_worked 1 + exp_continue + } + timeout { + fail "$testcase $message" + remote_close target + return + } + } + + remote_close target + if {$gdb_worked} { + pass "$testcase $message" + } else { + # Unsupported in the absence of a sane GDB. + unsupported "$testcase $message" + } + return +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc.exp new file mode 100644 index 0000000000000000000000000000000000000000..1b25ebec4cffcd8032a863a4798afec3ef3f61f8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcc.exp @@ -0,0 +1,182 @@ +# Copyright (C) 1992-2022 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Currently maintained by Doug Evans (dje@cygnus.com) + +# This file is loaded by the tool init file (eg: unix.exp). It provides +# default definitions for gcc_start, etc. and other supporting cast members. + +# These globals are used by gcc_start if no compiler arguments are provided. +# They are also used by the various testsuites to define the environment: +# where to find stdio.h, libc.a, etc. + +# we want to use libgloss so we can get find_gcc. +load_lib libgloss.exp +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp + +# +# GCC_UNDER_TEST is the compiler under test. +# + +# +# default_gcc_version -- extract and print the version number of the compiler +# + +proc default_gcc_version { } { + global GCC_UNDER_TEST + + gcc_init + + # ignore any arguments after the command + set compiler [lindex $GCC_UNDER_TEST 0] + + if ![is_remote host] { + set compiler_name [which $compiler] + } else { + set compiler_name $compiler + } + + # verify that the compiler exists + if { $compiler_name != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + clone_output "$compiler_name $version\n" + } else { + clone_output "Couldn't determine version of $compiler_name: $output\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gcc_version -- Call default_gcc_version, so we can override it if needed. +# + +proc gcc_version { } { + default_gcc_version +} + +# +# gcc_init -- called at the start of each .exp script. +# +# There currently isn't much to do, but always using it allows us to +# make some enhancements without having to go back and rewrite the scripts. +# + +set gcc_initialized 0 + +proc gcc_init { args } { + global tmpdir + global libdir + global gluefile wrap_flags + global gcc_initialized + global GCC_UNDER_TEST + global TOOL_EXECUTABLE + global gcc_warning_prefix + global gcc_error_prefix + + if { $gcc_initialized == 1 } { return; } + + if ![info exists GCC_UNDER_TEST] { + if [info exists TOOL_EXECUTABLE] { + set GCC_UNDER_TEST $TOOL_EXECUTABLE + } else { + set GCC_UNDER_TEST "[find_gcc]" + } + } + + if ![info exists tmpdir] then { + set tmpdir /tmp + } + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + gcc_maybe_build_wrapper "${tmpdir}/gcc-testglue.o" +} + +# +# gcc_target_compile -- compile a source file +# + +proc gcc_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global GCC_UNDER_TEST + global TOOL_OPTIONS + global TEST_ALWAYS_FLAGS + global flags_to_postpone + global board_info + + if {[target_info needs_status_wrapper] != "" && \ + [target_info needs_status_wrapper] != "0" && \ + [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" + if { $type == "executable" } { + set options [concat "{additional_flags=-dumpbase \"\"}" $options] + } + } + + global TEST_EXTRA_LIBS + if [info exists TEST_EXTRA_LIBS] { + lappend options "ldflags=$TEST_EXTRA_LIBS" + } + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options] + } + + # TOOL_OPTIONS must come first, so that it doesn't override testcase + # specific options. + if [info exists TOOL_OPTIONS] { + set options [concat "{additional_flags=$TOOL_OPTIONS}" $options] + } + + # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is + # appended here to multilib_flags as it can be overridden by the latter + # if it was added earlier. After the target_compile, multilib_flags is + # restored to its orignal content. + set tboard [target_info name] + if {[board_info $tboard exists multilib_flags]} { + set orig_multilib_flags "[board_info [target_info name] multilib_flags]" + append board_info($tboard,multilib_flags) " $flags_to_postpone" + } + + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GCC_UNDER_TEST" + set options [dg-additional-files-options $options $source] + set return_val [target_compile $source $dest $type $options] + + if {[board_info $tboard exists multilib_flags]} { + set board_info($tboard,multilib_flags) $orig_multilib_flags + set flags_to_postpone "" + } + + return $return_val +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcov.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcov.exp new file mode 100644 index 0000000000000000000000000000000000000000..9d5b2cdb86bbecac463fb1f850a1049c80c0514e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gcov.exp @@ -0,0 +1,434 @@ +# Copyright (C) 1997-2022 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 +# . + +# Verify various kinds of gcov output: line counts, branch percentages, +# and call return percentages. None of this is language-specific. + +load_lib "target-supports.exp" + +global GCOV + +# +# clean-gcov-file -- delete a working file the compiler creates for gcov +# +# TESTCASE is the name of the test. +# SUFFIX is file suffix + +proc clean-gcov-file { testcase suffix } { + set basename [file tail $testcase] + set base [file rootname $basename] + remote_file host delete $base.$suffix +} + +# +# clean-gcov -- delete the working files the compiler creates for gcov +# +# TESTCASE is the name of the test. +# +proc clean-gcov { testcase } { + clean-gcov-file $testcase "gcno" + clean-gcov-file $testcase "gcda" + clean-gcov-file $testcase "h.gcov" + remote_file host delete "$testcase.gcov" +} + +# +# verify-lines -- check that line counts are as expected +# +# TESTNAME is the name of the test, including unique flags. +# TESTCASE is the name of the test file. +# FILE is the name of the gcov output file. +# +proc verify-lines { testname testcase file } { + #send_user "verify-lines\n" + global subdir + + set failed 0 + set fd [open $file r] + while { [gets $fd line] >= 0 } { + # We want to match both "-" and "#####" as count as well as numbers, + # since we want to detect lines that shouldn't be marked as covered. + if [regexp "^ *(\[^:]*): *(\[0-9\\-#]+):.*count\\((\[0-9\\-#=\\.kMGTPEZY\*]+)\\)(.*)" \ + "$line" all is n shouldbe rest] { + if [regexp "^ *{(.*)}" $rest all xfailed] { + switch [dg-process-target $xfailed] { + "N" { continue } + "F" { setup_xfail "*-*-*" } + } + } + if { $is == "" } { + fail "$testname line $n: no data available" + incr failed + } elseif { $is != $shouldbe } { + fail "$testname line $n: is $is:should be $shouldbe" + incr failed + } else { + pass "$testname count for line $n" + } + } + } + close $fd + return $failed +} + + +# +# verify-branches -- check that branch percentages are as expected +# +# TESTNAME is the name of the test, including unique flags. +# TESTCASE is the name of the test file. +# FILE is the name of the gcov output file. +# +# Checks are based on comments in the source file. This means to look for +# branch percentages 10 or 90, 20 or 80, and # 70 or 30: +# /* branch(10, 20, 70) */ +# This means that all specified percentages should have been seen by now: +# /* branch(end) */ +# All specified percentages must also be seen by the next branch(n) or +# by the end of the file. +# +# Each check depends on the compiler having generated the expected +# branch instructions. Don't check for branches that might be +# optimized away or replaced with predicated instructions. +# +proc verify-branches { testname testcase file } { + #send_user "verify-branches\n" + + set failed 0 + set shouldbe "" + set fd [open $file r] + set n 0 + while { [gets $fd line] >= 0 } { + regexp "^\[^:\]+: *(\[0-9\]+):" "$line" all n + if [regexp "branch" $line] { + verbose "Processing branch line $n: $line" 3 + if [regexp "branch\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] { + # All percentages in the current list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected branch percentages not found: $shouldbe" + incr failed + set shouldbe "" + } + set shouldbe $new_shouldbe + #send_user "$n: looking for: $shouldbe\n" + # Record the percentages to check for. Replace percentage + # n > 50 with 100-n, since block ordering affects the + # direction of a branch. + for {set i 0} {$i < [llength $shouldbe]} {incr i} { + set num [lindex $shouldbe $i] + if {$num > 50} { + set shouldbe [lreplace $shouldbe $i $i [expr 100 - $num]] + } + } + } elseif [regexp "branch +\[0-9\]+ taken (-\[0-9\]+)%" "$line" \ + all taken] { + # Percentages should never be negative. + fail "$testname line $n: negative percentage: $taken" + incr failed + } elseif [regexp "branch +\[0-9\]+ taken (\[0-9\]+)%" "$line" \ + all taken] { + #send_user "$n: taken = $taken\n" + # Percentages should never be greater than 100. + if {$taken > 100} { + fail "$testname line $n: branch percentage greater than 100: $taken" + incr failed + } + if {$taken > 50} { + set taken [expr 100 - $taken] + } + # If this percentage is one to check for then remove it + # from the list. It's normal to ignore some reports. + set i [lsearch $shouldbe $taken] + if {$i != -1} { + set shouldbe [lreplace $shouldbe $i $i] + } + } elseif [regexp "branch\\(end\\)" "$line"] { + # All percentages in the list should have been seen by now. + if {[llength $shouldbe] != 0} { + fail "$testname line n: expected branch percentages not found: $shouldbe" + incr failed + } + set shouldbe "" + } + } + } + # All percentages in the list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected branch percentages not found: $shouldbe" + incr failed + } + close $fd + return $failed +} + +# +# verify-calls -- check that call return percentages are as expected +# +# TESTNAME is the name of the test, including unique flags. +# TESTCASE is the name of the test file. +# FILE is the name of the gcov output file. +# +# Checks are based on comments in the source file. This means to look for +# call return percentages 50, 20, 33: +# /* returns(50, 20, 33) */ +# This means that all specified percentages should have been seen by now: +# /* returns(end) */ +# All specified percentages must also be seen by the next returns(n) or +# by the end of the file. +# +# Each check depends on the compiler having generated the expected +# call instructions. Don't check for calls that are inserted by the +# compiler or that might be inlined. +# +proc verify-calls { testname testcase file } { + #send_user "verify-calls\n" + + set failed 0 + set shouldbe "" + set fd [open $file r] + set n 0 + while { [gets $fd line] >= 0 } { + regexp "^\[^:\]+: *(\[0-9\]+):" "$line" all n + if [regexp "return" $line] { + verbose "Processing returns line $n: $line" 3 + if [regexp "returns\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] { + # All percentages in the current list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected return percentages not found: $shouldbe" + incr failed + set shouldbe "" + } + # Record the percentages to check for. + set shouldbe $new_shouldbe + } elseif [regexp "call +\[0-9\]+ returned (-\[0-9\]+)%" "$line" \ + all returns] { + # Percentages should never be negative. + fail "$testname line $n: negative percentage: $returns" + incr failed + } elseif [regexp "call +\[0-9\]+ returned (\[0-9\]+)%" "$line" \ + all returns] { + # For branches we check that percentages are not greater than + # 100 but call return percentages can be, as for setjmp(), so + # don't count that as an error. + # + # If this percentage is one to check for then remove it + # from the list. It's normal to ignore some reports. + set i [lsearch $shouldbe $returns] + if {$i != -1} { + set shouldbe [lreplace $shouldbe $i $i] + } + } elseif [regexp "returns\\(end\\)" "$line"] { + # All percentages in the list should have been seen by now. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected return percentages not found: $shouldbe" + incr failed + } + set shouldbe "" + } + } + } + # All percentages in the list should have been seen. + if {[llength $shouldbe] != 0} { + fail "$testname line $n: expected return percentages not found: $shouldbe" + incr failed + } + close $fd + return $failed +} + +proc gcov-pytest-format-line { args } { + global subdir + + set testcase [lindex $args 0] + set pytest_script [lindex $args 1] + set output_line [lindex $args 2] + + set index [string first "::" $output_line] + set test_output [string range $output_line [expr $index + 2] [string length $output_line]] + + return "$subdir/$testcase ${pytest_script}::${test_output}" +} + +# Call by dg-final to run gcov --json-format which produces a JSON file +# that is later analysed by a pytest Python script. +# We pass filename of a test via GCOV_PATH environment variable. + +proc run-gcov-pytest { args } { + global GCOV + global srcdir subdir + # Extract the test file name from the arguments. + set testcase [lindex $args 0] + + verbose "Running $GCOV $testcase in $srcdir/$subdir" 2 + set testcase [remote_download host $testcase] + set result [remote_exec host $GCOV "$testcase -i"] + + set pytest_script [lindex $args 1] + if { ![check_effective_target_pytest3] } { + unsupported "$pytest_script pytest python3 is missing" + return + } + + setenv GCOV_PATH $testcase + spawn -noecho python3 -m pytest --color=no -rap -s --tb=no $srcdir/$subdir/$pytest_script + + set prefix "\[^\r\n\]*" + expect { + -re "FAILED($prefix)\[^\r\n\]+\r\n" { + set output [gcov-pytest-format-line $testcase $pytest_script $expect_out(1,string)] + fail $output + exp_continue + } + -re "ERROR($prefix)\[^\r\n\]+\r\n" { + set output [gcov-pytest-format-line $testcase $pytest_script $expect_out(1,string)] + fail $output + exp_continue + } + -re "PASSED($prefix)\[^\r\n\]+\r\n" { + set output [gcov-pytest-format-line $testcase $pytest_script $expect_out(1,string)] + pass $output + exp_continue + } + } + + clean-gcov $testcase +} + +# Called by dg-final to run gcov and analyze the results. +# +# ARGS consists of the optional strings "branches" and/or "calls", +# (indicating that these things should be verified) followed by a +# list of arguments to provide to gcov, including the name of the +# source file. + +proc run-gcov { args } { + global GCOV + global srcdir subdir + + set gcov_args "" + set gcov_verify_calls 0 + set gcov_verify_branches 0 + set gcov_verify_lines 1 + set gcov_verify_intermediate 0 + set gcov_remove_gcda 0 + set xfailed 0 + + foreach a $args { + if { $a == "calls" } { + set gcov_verify_calls 1 + } elseif { $a == "branches" } { + set gcov_verify_branches 1 + } elseif { $a == "intermediate" } { + set gcov_verify_intermediate 1 + set gcov_verify_calls 0 + set gcov_verify_branches 0 + set gcov_verify_lines 0 + } elseif { $a == "remove-gcda" } { + set gcov_remove_gcda 1 + } elseif { $gcov_args == "" } { + set gcov_args $a + } else { + switch [dg-process-target $a] { + "N" { return } + "F" { set xfailed 1 } + } + } + } + + set testname [testname-for-summary] + + # Extract the test file name from the arguments. + set testcase [lindex $gcov_args end] + + if { $gcov_remove_gcda } { + verbose "Removing $testcase.gcda" + clean-gcov-file $testcase "gcda" + } + + verbose "Running $GCOV $testcase" 2 + set testcase [remote_download host $testcase] + set result [remote_exec host $GCOV $gcov_args] + if { [lindex $result 0] != 0 } { + if { $xfailed } { + setup_xfail "*-*-*" + } + fail "$testname gcov failed: [lindex $result 1]" + clean-gcov $testcase + return + } + + set builtin_index [string first "File ''" $result] + if { $builtin_index != -1 } { + fail "$testname gcov failed: .gcov should not be created" + clean-gcov $testcase + return + } + + # Get the gcov output file after making sure it exists. + set files [glob -nocomplain $testcase.gcov] + if { $files == "" } { + if { $xfailed } { + setup_xfail "*-*-*" + } + fail "$testname gcov failed: $testcase.gcov does not exist" + clean-gcov $testcase + return + } + remote_upload host $testcase.gcov $testcase.gcov + + # Check that line execution counts are as expected. + if { $gcov_verify_lines } { + # Check that line execution counts are as expected. + set lfailed [verify-lines $testname $testcase $testcase.gcov] + } else { + set lfailed 0 + } + + # If requested via the .x file, check that branch and call information + # is correct. + if { $gcov_verify_branches } { + set bfailed [verify-branches $testname $testcase $testcase.gcov] + } else { + set bfailed 0 + } + if { $gcov_verify_calls } { + set cfailed [verify-calls $testname $testcase $testcase.gcov] + } else { + set cfailed 0 + } + if { $gcov_verify_intermediate } { + # Check that intermediate format has the expected format + set ifailed [verify-intermediate $testname $testcase $testcase.gcov] + } else { + set ifailed 0 + } + + # Report whether the gcov test passed or failed. If there were + # multiple failures then the message is a summary. + set tfailed [expr $lfailed + $bfailed + $cfailed + $ifailed] + if { $xfailed } { + setup_xfail "*-*-*" + } + if { $tfailed > 0 } { + fail "$testname gcov: $lfailed failures in line counts, $bfailed in branch percentages, $cfailed in return percentages, $ifailed in intermediate format" + if { $xfailed } { + clean-gcov $testcase + } + } else { + pass "$testname gcov" + clean-gcov $testcase + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..ebd0093c27a38f48df72d75ccb1f1146a538d9d2 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc-dg.exp @@ -0,0 +1,105 @@ +# Copyright (C) 2012-2022 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 +# . + +load_lib gcc-dg.exp + +# Define gdc callbacks for dg.exp. + +proc gdc-dg-test { prog do_what extra_tool_flags } { + upvar dg-do-what dg-do-what + + # Demote link and run tests to compile-only if D runtime is missing. + if ![check_effective_target_d_runtime] { + switch $do_what { + link - + run { + set do_what compile + set dg-do-what compile + } + } + } + + # Strip gdc.test prefix off test names to avoid pathname failures in + # some tests. + set prog [dg-trim-dirname gdc.test $prog] + + set result \ + [gcc-dg-test-1 gdc_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + return [list $comp_output $output_file] +} + +proc gdc-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +# + +proc gdc-dg-runtest { testcases flags default-extra-flags } { + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Use TORTURE_OPTIONS to cycle through an option list. + if [torture-options-exist] then { + global torture_with_loops + set option_list $torture_with_loops + } else { + set option_list { "" } + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } +} + +# +# gdc_load -- wrapper around default gdc_load to handle tests that +# require program arguments passed to them. +# + +if { [info procs gdc_load] != [list] \ + && [info procs prev_gdc_load] == [list] } { + rename gdc_load prev_gdc_load + + proc gdc_load { program args } { + global GDC_EXECUTE_ARGS + if [info exists GDC_EXECUTE_ARGS] then { + set args [concat "{$GDC_EXECUTE_ARGS}"] + } + #print "Running: $program [lindex $args 0]" + set result [eval [list prev_gdc_load $program] $args ] + return $result + } +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc-utils.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc-utils.exp new file mode 100644 index 0000000000000000000000000000000000000000..ffbaa277e8ed0a1c604de86b2df2513888aa6bef --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc-utils.exp @@ -0,0 +1,555 @@ +# Copyright (C) 2012-2022 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 +# . + +# Test using the DMD testsuite. + +# +# Convert DMD arguments to GDC equivalent +# + +proc gdc-convert-args { args } { + set out "" + + foreach arg [split [lindex $args 0] " "] { + # List of switches kept in ASCII collated order. + if [string match "-D" $arg] { + upvar 1 compilable_output_file_ext compilable_output_file_ext + set compilable_output_file_ext "html" + lappend out "-fdoc" + + } elseif [string match "-H" $arg] { + upvar 1 compilable_output_file_ext compilable_output_file_ext + set compilable_output_file_ext "di" + lappend out "-H" + + } elseif [string match "-HC" $arg] { + upvar 1 compilable_output_file_ext compilable_output_file_ext + upvar 1 name name + set compilable_output_file_ext "h" + lappend out "-fdump-c++-spec=[file rootname $name].h" + + } elseif [string match "-HC=verbose" $arg] { + lappend out "-fdump-c++-spec-verbose" + + } elseif { [regexp -- {^-I([\w+/-]+)} $arg pattern path] } { + lappend out "-I$path" + + } elseif { [regexp -- {^-J([\w+/-]+)} $arg pattern path] } { + lappend out "-J$path" + + } elseif [string match "-X" $arg] { + upvar 1 compilable_output_file_ext compilable_output_file_ext + set compilable_output_file_ext "json" + lappend out "-X" + + } elseif [string match "-allinst" $arg] { + lappend out "-fall-instantiations" + + } elseif [string match "-betterC" $arg] { + lappend out "-fno-druntime" + + } elseif { [string match "-boundscheck" $arg] + || [string match "-boundscheck=on" $arg] } { + lappend out "-fbounds-check=on" + + } elseif { [string match "-boundscheck=off" $arg] + || [string match "-noboundscheck" $arg] } { + lappend out "-fbounds-check=off" + + } elseif [string match "-boundscheck=safeonly" $arg] { + lappend out "-fbounds-check=safeonly" + + } elseif [string match "-c" $arg] { + lappend out "-c" + + } elseif [regexp -- {^-check=(\w+)=off} $arg pattern value] { + lappend out "-fno-check=$value" + + } elseif [string match "-checkaction=context" $arg] { + lappend out "-fcheckaction=context" + + } elseif [string match "-d" $arg] { + lappend out "-Wno-deprecated" + + } elseif [string match "-de" $arg] { + lappend out "-Wdeprecated" + lappend out "-Werror" + + } elseif [string match "-debug" $arg] { + lappend out "-fdebug" + + } elseif [regexp -- {^-debug=(\w+)} $arg pattern value] { + lappend out "-fdebug=$value" + + } elseif [string match "-dip25" $arg] { + lappend out "-fpreview=dip25" + + } elseif [string match "-dip1000" $arg] { + lappend out "-fpreview=dip1000" + + } elseif [string match "-dip1008" $arg] { + lappend out "-fpreview=dip1008" + + } elseif [string match "-dw" $arg] { + lappend out "-Wdeprecated" + lappend out "-Wno-error" + + } elseif [regexp -- {^-extern-std=([\w+]+)} $arg pattern value] { + lappend out "-fextern-std=$value" + + } elseif [string match "-fPIC" $arg] { + lappend out "-fPIC" + + } elseif [string match "-fPIE" $arg] { + lappend out "-fPIE" + + } elseif { [string match "-g" $arg] + || [string match "-gc" $arg] } { + lappend out "-g" + + } elseif [string match "-ignore" $arg] { + lappend out "-fignore-unknown-pragmas" + + } elseif [string match "-inline" $arg] { + lappend out "-finline-functions" + + } elseif [string match "-main" $arg] { + lappend out "-fmain" + + } elseif [regexp -- {^-mv=([\w+=./-]+)} $arg pattern value] { + lappend out "-fmodule-file=$value" + + } elseif [string match "-O" $arg] { + lappend out "-O2" + + } elseif [regexp -- {^-preview=(\w+)} $arg pattern value] { + lappend out "-fpreview=[string tolower $value]" + + } elseif [string match "-release" $arg] { + lappend out "-frelease" + + } elseif [regexp -- {^-revert=(\w+)} $arg pattern value] { + lappend out "-frevert=[string tolower $value]" + + } elseif [regexp -- {^-transition=(\w+)} $arg pattern value] { + lappend out "-ftransition=[string tolower $value]" + + } elseif [string match "-unittest" $arg] { + lappend out "-funittest" + + } elseif [string match "-verrors=spec" $arg] { + lappend out "-Wspeculative" + + } elseif [regexp -- {^-verrors=(\d+)} $arg pattern num] { + lappend out "-fmax-errors=$num" + + } elseif [regexp -- {^-version=(\w+)} $arg pattern value] { + lappend out "-fversion=$value" + + } elseif [string match "-o-" $arg] { + upvar 2 compilable_do_what compilable_do_what + set compilable_do_what "compile" + + } elseif [string match "-vgc" $arg] { + lappend out "-ftransition=nogc" + + } elseif [string match "-vtemplates" $arg] { + lappend out "-ftransition=templates" + + } elseif [string match "-vtls" $arg] { + lappend out "-ftransition=tls" + + } elseif [string match "-w" $arg] { + lappend out "-Wall" + lappend out "-Werror" + + } elseif [string match "-wi" $arg] { + lappend out "-Wall" + lappend out "-Wno-error" + + } else { + # print "Unhandled Argument: $arg" + } + } + + return $out +} + +proc gdc-copy-file { srcdir filename } { + # Split folder/file from the filename. + set targetdir [file dirname $filename] + + # print "Filename: $srcdir - $filename" + + file mkdir $targetdir + file copy -force $srcdir/$filename $filename + + # Remove file once test is finished. + upvar 2 cleanup_extra_files cleanups + lappend cleanups $filename +} + +# +# Translate DMD test directives to dejagnu equivalent. +# +# This procedure copies the test and all its dependencies from its source +# location in `$srcdir/$type' to `$base_dir/$type'. A stub dejagnu test file +# is then created in `$base_dir/gdc.test/$type' containing all translated test +# directives. This stub is then the test that is handed over to `dg-test'. +# Before invoking the compiler, the `gdc.test' prefix is trimmed from the test +# `$prog' name in `gdc-dg-test' so that all copied tests then get picked up +# with the correct path names. +# +# The following directives are recognized: +# +# COMPILE_SEPARATELY: Not handled. +# EXECUTE_ARGS: Parameters to add to the execution of the test. +# COMPILED_IMPORTS: List of modules files that are imported by the main +# source file that should be included in compilation. +# Currently handled the same as EXTRA_SOURCES. +# DFLAGS: Overrides the DFLAGS environment variable if specified +# in the test. No values are permitted; an error will be +# emitted if the value is not empty. +# EXTRA_SOURCES: List of extra sources to build and link along with +# the test. +# EXTRA_CPP_SOURCES: List of extra C++ files to build and link along with +# the test. +# CXXFLAGS: list of extra arguments passed when compiling C++ +# sources defined in EXTRA_CPP_SOURCES. +# EXTRA_OBJC_SOURCES: List of extra Objective-C file to build and link along +# with the test. Currently not handled. +# EXTRA_FILES: List of extra files to copy for the test runs. +# PERMUTE_ARGS: The set of arguments to permute in multiple compiler +# invocations. An empty set means only one permutation +# with no arguments. +# ARG_SETS: Not handled. +# LINK: Enables linking. +# TEST_OUTPUT: The output expected from the compilation. +# POST_SCRIPT: Not handled. +# REQUIRED_ARGS: Arguments to add to the compiler command line. +# DISABLED: Not handled. +# + +proc gdc-convert-test { base test } { + global DEFAULT_DFLAGS + global PERMUTE_ARGS + global GDC_EXECUTE_ARGS + + set PERMUTE_ARGS "" + set GDC_EXECUTE_ARGS "" + + set extra_sources "" + set extra_files "" + set needs_phobos 0 + set saw_test_flags 0 + + upvar 1 compilable_do_what compilable_do_what + set compilable_output_file_ext "" + + # Split folder/file from the test. + set type [file dirname $test] + set name [file tail $test] + + # print "Filename: $base - $test" + gdc-copy-file $base $test + + # Read in all test directives, and save the dejagnu equivalents to a new + # file that will be returned as the test to run. + set fdin [open $base/$test r] + #fconfigure $fdin -encoding binary + + # Include gdc.test prefix so test names follow DejaGnu conventions. + set testdir [file tail $base] + file mkdir $testdir/$type + set fdout [open $testdir/$test w] + #fconfigure $fdout -encoding binary + + while { [gets $fdin copy_line] >= 0 } { + + if [regexp -- {COMPILE_SEPARATELY} $copy_line] { + # COMPILE_SEPARATELY is not handled. + + } elseif [regexp -- {DISABLED} $copy_line] { + # DISABLED is not handled. + + } elseif [regexp -- {LINK:} $copy_line] { + # LINK sets dg-do-what-default "link" + set compilable_do_what "link" + + } elseif [regexp -- {ARG_SETS} $copy_line] { + # ARG_SETS is not handled. + regsub -- {ARG_SETS.*$} $copy_line "" out_line + + } elseif [regexp -- {POST_SCRIPT} $copy_line] { + # POST_SCRIPT is not handled + + } elseif [regexp -- {DFLAGS\s*:\s*(.*)} $copy_line match args] { + # DFLAGS overrides the default value of PERMUTE_ARGS. + if { $args != "" } { + error "gdc-convert-test: DFLAGS is not empty as expected" + } + set saw_test_flags 1 + + } elseif [regexp -- {PERMUTE_ARGS\s*:\s*(.*)} $copy_line match args] { + # PERMUTE_ARGS is handled by gdc-do-test. + set PERMUTE_ARGS [gdc-convert-args $args] + set saw_test_flags 1 + + } elseif [regexp -- {EXECUTE_ARGS\s*:\s*(.*)} $copy_line match args] { + # EXECUTE_ARGS is handled by gdc_load. + foreach arg $args { + lappend GDC_EXECUTE_ARGS $arg + } + + } elseif [regexp -- {REQUIRED_ARGS\s*:\s*(.*)} $copy_line match args] { + # Convert all listed arguments to from dmd to gdc-style. + puts $fdout "// { dg-additional-options \"[gdc-convert-args $args]\" }" + + } elseif [regexp -- {EXTRA_SOURCES\s*:\s*(.*)} $copy_line match sources] { + # EXTRA_SOURCES are appended to extra_sources list + foreach srcfile $sources { + lappend extra_sources $srcfile + } + + } elseif [regexp -- {EXTRA_CPP_SOURCES\s*:\s*(.*)} $copy_line match sources] { + # EXTRA_CPP_SOURCES are appended to extra_sources list + foreach srcfile $sources { + # C++ sources are found in the extra-files directory. + lappend extra_sources "extra-files/$srcfile" + } + + } elseif [regexp -- {CXXFLAGS\s*:\s*(.*)} $copy_line match args] { + # Both C++ and D sources are compiled together, so include each + # other's command line flags too. + set new_option "{ dg-additional-options \"$args\" }" + regsub -- {CXXFLAGS.*$} $copy_line $new_option out_line + + } elseif [regexp -- {EXTRA_OBJC_SOURCES\s*:\s*(.*)} $copy_line match sources] { + # EXTRA_OBJC_SOURCES is not handled. + regsub -- {EXTRA_OBJC_SOURCES.*$} $copy_line "" out_line + + } elseif [regexp -- {EXTRA_FILES\s*:\s*(.*)} $copy_line match files] { + # EXTRA_FILES are appended to extra_files list + foreach file $files { + lappend extra_files $file + } + + } elseif [regexp -- {COMPILED_IMPORTS\s*:\s*(.*)} $copy_line match sources] { + # COMPILED_IMPORTS are appended to extra_sources list + foreach import $sources { + lappend extra_sources $import + } + + } elseif [regexp -- {RUNNABLE_PHOBOS_TEST} $copy_line match sources] { + # RUNNABLE_PHOBOS_TEST annotates tests that import the std module. + # It will need skipping if phobos is not available on the target. + set needs_phobos 1 + + } elseif [regexp -- {COMPILABLE_MATH_TEST} $copy_line match sources] { + # COMPILABLE_MATH_TEST annotates tests that import the std.math + # module. Which will need skipping if not available on the target. + set needs_phobos 1 + } + } + + # Now that all extra sources and files have been collected, copy them all + # to the testsuite build directory. + if { [llength $extra_sources] > 0 } { + foreach srcfile $extra_sources { + gdc-copy-file $base "$type/$srcfile" + } + puts $fdout "// { dg-additional-sources \"$extra_sources\" }" + } + + if { [llength $extra_files] > 0 } { + foreach file $extra_files { + gdc-copy-file $base "$type/$file" + } + puts $fdout "// { dg-additional-files \"$extra_files\" }" + } + + # Add specific options for test type + + # DMD's testsuite is extremely verbose, compiler messages from constructs + # such as pragma(msg, ...) would otherwise cause tests to fail. + puts $fdout "// { dg-prune-output .* }" + + # Compilable files are successful if an output is generated. + # Fail compilable are successful if an output is not generated. + # Runnable must compile, link, and return 0 to be successful by default. + switch $type { + runnable_cxx - + runnable { + if ![isnative] { + puts $fdout "// { dg-final { output-exists } }" + } + if $needs_phobos { + puts $fdout "// { dg-skip-if \"imports phobos\" { ! d_runtime_has_std_library } }" + } + # Run runnable tests with all default permutations if not + # explicitly set in the test file. + if !$saw_test_flags { + set PERMUTE_ARGS $DEFAULT_DFLAGS + } + } + + compilable { + puts $fdout "// { dg-final { output-exists } }" + + # Compilable test may require checking another kind of output file. + if { $compilable_output_file_ext != "" } { + # Check that file generation tests output the expected file. + set genfile "[file rootname $name].$compilable_output_file_ext" + puts $fdout "// { dg-final { if \[file exists $genfile\] \\{ } }" + puts $fdout "// { dg-final { pass \"$testdir/$test (file exists $genfile)\" } }" + puts $fdout "// { dg-final { \\} else \\{ } }" + puts $fdout "// { dg-final { fail \"$testdir/$test (file exists $genfile)\" } }" + puts $fdout "// { dg-final { \\} } }" + # Cleanup extra generated files. + puts $fdout "// { dg-final { file delete $genfile } }" + } + if $needs_phobos { + puts $fdout "// { dg-skip-if \"imports phobos\" { ! d_runtime_has_std_library } }" + } + } + + fail_compilation { + # Fail compilation tests only check for language errors from the + # front-end. No need to run all permutations of the default DFLAGS. + if { $PERMUTE_ARGS == $DEFAULT_DFLAGS } { + set PERMUTE_ARGS "" + } + puts $fdout "// { dg-final { output-exists-not } }" + } + } + + close $fdin + close $fdout + + return $testdir/$test +} + +proc gdc-permute-options { options } { + set result { } + set n [expr 1<<[llength $options]] + for { set i 0 } { $i<$n } { incr i } { + set option "" + for { set j 0 } { $j<[llength $options] } { incr j } { + if [expr $i & 1 << $j] { + append option [lindex $options $j] + append option " " + } + } + lappend result $option + + } + return $result +} + +# +# Main loop for running all tests for the subdirectory in gdc.test +# + +proc gdc-do-test { testcases } { + global dg-do-what-default + global verbose + + # If a testcase doesn't have special options, use these. + global DEFAULT_DFLAGS + if ![info exists DEFAULT_DFLAGS] then { + set DEFAULT_DFLAGS "-g -O2 -frelease" + #set DEFAULT_DFLAGS "-O2" + } + + # These are special options to use on testcase, and override DEFAULT_DFLAGS + global PERMUTE_ARGS + + # Set if an extra option should be passed to link to shared druntime. + global SHARED_OPTION + + # Additional arguments for gdc_load + global GDC_EXECUTE_ARGS + + # Allow blank linkes in output for all of gdc.test. + global allow_blank_lines + set save_allow_blank_lines $allow_blank_lines + if { !$allow_blank_lines } { + set allow_blank_lines 2 + } + + set saved-dg-do-what-default ${dg-do-what-default} + + # Main loop. + + # set verbose 1 + # set dg-final-code "" + # Find all tests and pass to routine. + foreach test $testcases { + regexp -- "(.*)/(.+)/(.+)\.(.+)$" $test match base type name ext + + # Convert to DG test. + set imports [format "-I%s" $type] + set cleanup_extra_files "" + set compilable_do_what "compile" + set filename "[gdc-convert-test $base $type/$name.$ext]" + + if { $type == "runnable" || $type == "runnable_cxx" } { + append PERMUTE_ARGS " $SHARED_OPTION" + } + + set options [gdc-permute-options [lsort -unique $PERMUTE_ARGS]] + + switch $type { + runnable_cxx - + runnable { + for { set i 0 } { $i<[llength $options] } { incr i } { + set flags [lindex $options $i] + if [isnative] { + set dg-do-what-default "run" + } else { + set dg-do-what-default "link" + } + gdc-dg-runtest $filename $flags $imports + } + } + + compilable { + for { set i 0 } { $i<[llength $options] } { incr i } { + set flags [lindex $options $i] + set dg-do-what-default $compilable_do_what + gdc-dg-runtest $filename $flags $imports + } + } + + fail_compilation { + for { set i 0 } { $i<[llength $options] } { incr i } { + set flags [lindex $options $i] + set dg-do-what-default "assemble" + gdc-dg-runtest $filename $flags $imports + } + } + } + + # Cleanup test directory. + foreach srcfile $cleanup_extra_files { + file delete $srcfile + } + file delete $filename + } + + set dg-do-what-default ${saved-dg-do-what-default} + set allow_blank_lines $save_allow_blank_lines +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc.exp new file mode 100644 index 0000000000000000000000000000000000000000..73bc61780c8802a297b23463dc3b4ac3f83f6e4c --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gdc.exp @@ -0,0 +1,298 @@ +# Copyright (C) 2012-2022 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 +# . + +# +# gdc support library routines +# + +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# GDC_UNDER_TEST is the compiler under test. +# + +set gdc_compile_options "" + + +# +# gdc_version -- extract and print the version number of the compiler +# + +proc gdc_version { } { + global GDC_UNDER_TEST + + gdc_init + + # ignore any arguments after the command + set compiler [lindex $GDC_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gdc_include_flags -- include flags for the gcc tree structure +# + +proc gdc_include_flags { paths } { + global srcdir + global GDC_INCLUDE_CXX_FLAGS + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + if [info exists GDC_INCLUDE_CXX_FLAGS] { + set include_cxx_flags $GDC_INCLUDE_CXX_FLAGS + } else { + set include_cxx_flags 0 + } + + set gccpath ${paths} + + if { $gccpath != "" } { + if [file exists "${gccpath}/libphobos/libdruntime"] { + append flags "-I${gccpath}/libphobos/libdruntime " + } + } + append flags "-I${srcdir}/../../libphobos/libdruntime " + append flags "-I${srcdir}/../../libphobos/src " + + # For the tests that mix C++ and D, need to know where headers are located. + if $include_cxx_flags { + set odir [lookfor_file ${gccpath} libstdc++-v3] + if { ${odir} != "" && [file exists ${odir}/scripts/testsuite_flags] } { + set cxxflags [exec sh ${odir}/scripts/testsuite_flags --build-includes] + set idx [lsearch $cxxflags "-nostdinc++"] + append flags [lreplace $cxxflags $idx $idx] + } + } + + return "$flags" +} + +# +# gdc_link_flags -- linker flags for the gcc tree structure +# + +proc gdc_link_flags { paths } { + global srcdir + global ld_library_path + global GDC_UNDER_TEST + global GDC_INCLUDE_CXX_FLAGS + global shlib_ext + global SHARED_OPTION + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + set SHARED_OPTION "" + verbose "shared lib extension: $shlib_ext" + + if [info exists GDC_INCLUDE_CXX_FLAGS] { + set include_cxx_flags $GDC_INCLUDE_CXX_FLAGS + } else { + set include_cxx_flags 0 + } + + if { $gccpath != "" } { + # Path to libgphobos.spec. + append flags "-B${gccpath}/libphobos/src " + # Path to drtbegin.o/drtend.o. + if { [file exists "${gccpath}/libphobos/libdruntime/gcc/drtbegin.o"] } { + append flags "-B${gccpath}/libphobos/libdruntime/gcc " + } + + if { [file exists "${gccpath}/libphobos/src/.libs/libgphobos.a"] \ + || [file exists "${gccpath}/libphobos/src/.libs/libgphobos.${shlib_ext}"] } { + append flags "-L${gccpath}/libphobos/src/.libs " + append ld_library_path ":${gccpath}/libphobos/src/.libs" + } + # Static linking is default. If only the shared lib is available adjust + # flags to always use it. If both are available, set SHARED_OPTION which + # will be added to PERMUTE_ARGS + if { [file exists "${gccpath}/libphobos/src/.libs/libgphobos.${shlib_ext}"] } { + if { [file exists "${gccpath}/libphobos/src/.libs/libgphobos.a"] } { + set SHARED_OPTION "-shared-libphobos" + } else { + append flags "-shared-libphobos " + } + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + # For the tests that mix C++ and D, need to know where library is located. + if $include_cxx_flags { + if { [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] \ + || [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] } { + append flags "-L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + } + append ld_library_path [gcc-set-multilib-library-path $GDC_UNDER_TEST] + } else { + global tool_root_dir + + set libphobos [lookfor_file ${tool_root_dir} libgphobos] + if { $libphobos != "" } { + append flags "-B${libphobos} -L${libphobos} " + append ld_library_path ":${libphobos}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty] + if { $libiberty != "" } { + append flags "-L${libiberty} " + } + if $include_cxx_flags { + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++] + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} " + append ld_library_path ":${libstdcpp}" + } + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# gdc_init -- called at the start of each subdir of tests +# + +proc gdc_init { args } { + global gdc_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global TOOL_EXECUTABLE + global GDC_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + if ![info exists GDC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GDC_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GDC_UNDER_TEST [transform gdc] + } else { + set GDC_UNDER_TEST [findfile $base_dir/../../gdc "$base_dir/../../gdc -B$base_dir/../../" [findfile $base_dir/gdc "$base_dir/gdc -B$base_dir/" [transform gdc]]] + } + } + } + + if ![is_remote host] { + if { [which $GDC_UNDER_TEST] == 0 } then { + perror "GDC_UNDER_TEST ($GDC_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + gdc_maybe_build_wrapper "${tmpdir}/d-testglue.o" + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + verbose "gdc is initialized" 3 +} + +# +# gdc_target_compile -- compile a source file +# + +proc gdc_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global GDC_UNDER_TEST + global TOOL_OPTIONS + global TEST_ALWAYS_FLAGS + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + set always_dflags "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend always_dflags "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend always_dflags "additional_flags=[gdc_include_flags [get_multilibs ${TOOL_OPTIONS}] ]" + lappend always_dflags "ldflags=[gdc_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend always_dflags "additional_flags=[gdc_include_flags [get_multilibs] ]" + lappend always_dflags "ldflags=[gdc_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend always_dflags "additional_flags=$TOOL_OPTIONS" + } + + verbose "always_dflags set to: $always_dflags" + + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GDC_UNDER_TEST" + + set options [concat "$always_dflags" $options] + set options [dg-additional-files-options $options $source] + return [target_compile $source $dest $type $options] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gfortran-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gfortran-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..d4a245e0bfec1aac708d21478f8ebf470c0bccde --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gfortran-dg.exp @@ -0,0 +1,231 @@ +# Copyright (C) 2004-2022 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 +# . + +load_lib gcc-dg.exp +load_lib torture-options.exp + +# Define gfortran callbacks for dg.exp. + +proc gfortran-dg-test { prog do_what extra_tool_flags } { + set result \ + [gcc-dg-test-1 gfortran_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + # gcc's default is to print the caret and source code, but + # most test cases implicitly use the flag -fno-diagnostics-show-caret + # to disable caret (and source code) printing. + # + # However, a few test cases override this back to the default by + # explicily supplying "-fdiagnostics-show-caret", so that we can have + # test coverage for caret/source code printing. + # + # gfortran error messages with caret-printing look like this: + # [name]:[locus]: + # + # some code + # 1 + # Error: Some error at (1) + # or + # [name]:[locus]: + # + # some code + # 1 + # [name]:[locus2]: + # + # some other code + # 2 + # Error: Some error at (1) and (2) + # or + # [name]:[locus]: + # + # some code and some more code + # 1 2 + # Error: Some error at (1) and (2) + # + # If this is such a test case, skip the rest of this function, so + # that the test case can explicitly verify the output that it expects. + if {[string first "-fdiagnostics-show-caret" $extra_tool_flags] >= 0} { + return [list $comp_output $output_file] + } + + # Otherwise, caret-printing is disabled. + # gfortran errors with caret-printing disabled look like this: + # [name]:[locus]: Error: Some error + # or + # [name]:[locus]: Error: (1) + # [name]:[locus2]: Error: Some error at (1) and (2) + # + # Where [locus] is either [line] or [line].[column] or + # [line].[column]-[column] . + # + # We collapse these to look like: + # [name]:[line]:[column]: Error: Some error at (1) and (2) + # or + # [name]:[line]:[column]: Error: Some error at (1) and (2) + # [name]:[line2]:[column]: Error: Some error at (1) and (2) + # + # Note that these regexps only make sense in the combinations used below. + # Note also that is imperative that we first deal with the form with + # two loci. + set locus_regexp "(\[^\n\]+:\[0-9\]+)\[\.:\](\[0-9\]+)(-\[0-9\]+)?:\n\n\[^\n\]+\n\[^\n\]+\n" + set diag_regexp "(\[^\n\]+)\n" + + # We proceed in steps: + + # 1. We add first a column number if none exists. + # (Some Fortran diagnostics have the locus after Warning|Error) + set colnum_regexp "(^|\n)(Warning: |Error: )?(\[^:\n\]+:\[0-9\]+):(\[ \n\])" + regsub -all $colnum_regexp $comp_output "\\1\\3:0:\\4\\2" comp_output + verbose "comput_output0:\n$comp_output" + + # 2. We deal with the form with two different locus lines, + set two_loci "(^|\n)$locus_regexp$locus_regexp$diag_regexp" + regsub -all $two_loci $comp_output "\\1\\2:\\3: \\8\n\\5\:\\6: \\8\n" comp_output + verbose "comput_output1:\n$comp_output" + + set locus_prefix "(\[^:\n\]+:\[0-9\]+:\[0-9\]+: )(Warning: |Error: )" + set two_loci2 "(^|\n)$locus_prefix\\(1\\)\n$locus_prefix$diag_regexp" + regsub -all $two_loci2 $comp_output "\\1\\2\\3\\6\n\\4\\5\\6\n" comp_output + verbose "comput_output2:\n$comp_output" + + # 3. then with the form with only one locus line. + set single_locus "(^|\n)$locus_regexp$diag_regexp" + regsub -all $single_locus $comp_output "\\1\\2:\\3: \\5\n" comp_output + verbose "comput_output3:\n$comp_output" + + # 4. Add a line number if none exists + regsub -all "(^|\n)(Warning: |Error: )" $comp_output "\\1:0:0: \\2" comp_output + verbose "comput_output4:\n$comp_output" + return [list $comp_output $output_file] +} + +proc gfortran-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc gfortran-dg-runtest { testcases flags default-extra-flags } { + global runtests + global torture_with_loops + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # look if this is dg-do-run test, in which case + # we cycle through the option list, otherwise we don't + if [expr [search_for $test "dg-do run"]] { + set option_list $torture_with_loops + } else { + set option_list [list { -O } ] + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + list-module-names $test + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + cleanup-modules "" + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} + +proc gfortran-dg-debug-runtest { target_compile trivial opt_opts testcases } { + global srcdir subdir DEBUG_TORTURE_OPTIONS + + if ![info exists DEBUG_TORTURE_OPTIONS] { + set DEBUG_TORTURE_OPTIONS "" + set type_list [list "-gdwarf-2" ] + foreach type $type_list { + set comp_output [$target_compile \ + "$srcdir/$subdir/$trivial" "trivial.S" assembly \ + "additional_flags=$type"] + if { [string match "exit status *" $comp_output] } { + continue + } + if { [string match \ + "* target system does not support the * debug format*" \ + $comp_output] + } { + continue + } + remove-build-file "trivial.S" + foreach level {1 "" 3} { + if { ($type == "-gdwarf-2") && ($level != "") } { + lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}" "-g${level}" "$opt" ] + } + } else { + lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"] + foreach opt $opt_opts { + lappend DEBUG_TORTURE_OPTIONS \ + [list "${type}${level}" "$opt" ] + } + } + } + } + } + + verbose -log "Using options $DEBUG_TORTURE_OPTIONS" + + global runtests + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + list-module-names $test + + foreach flags $DEBUG_TORTURE_OPTIONS { + set doit 1 + # gcc-specific checking removed here + + if { $doit } { + verbose -log "Testing $nshort, $flags" 1 + dg-test $test $flags "" + cleanup-modules "" + } + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gfortran.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gfortran.exp new file mode 100644 index 0000000000000000000000000000000000000000..5f692d8f3507b09882b6219caa0df943a774dc42 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gfortran.exp @@ -0,0 +1,282 @@ +# Copyright (C) 2003-2022 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 +# . + +# This file is just 'sed -e 's/77/fortran/g' \ +# -e 's/f2c/gfortran' g77.exp > gfortran.exp' +# +# with some minor modifications to make it work. + +# +# gfortran support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp +load_lib target-supports.exp + +# +# GFORTRAN_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" + + +# +# gfortran_version -- extract and print the version number of the compiler +# + +proc gfortran_version { } { + global GFORTRAN_UNDER_TEST + + gfortran_init + + # ignore any arguments after the command + set compiler [lindex $GFORTRAN_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gfortran_link_flags -- provide new version of gfortran_link_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# + +proc gfortran_link_flags { paths } { + global srcdir + global ld_library_path + global GFORTRAN_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/libgfortran/.libs/libgfortran.a"] { + # Some targets use libgfortran.a%s in their specs, so they need a -B option + # for uninstalled testing. + append flags "-B${gccpath}/libgfortran/.libs " + append flags "-L${gccpath}/libgfortran/.libs " + append ld_library_path ":${gccpath}/libgfortran/.libs" + } + if [file exists "${gccpath}/libgfortran/.libs/libgfortran.${shlib_ext}"] { + append flags "-L${gccpath}/libgfortran/.libs " + append ld_library_path ":${gccpath}/libgfortran/.libs" + } + if [file exists "${gccpath}/libgfortran/libgforbegin.a"] { + append flags "-L${gccpath}/libgfortran " + } + if [file exists "${gccpath}/libatomic/.libs/libatomic.${shlib_ext}"] { + append flags "-L${gccpath}/libatomic/.libs " + append ld_library_path ":${gccpath}/libatomic/.libs" + } + if [file exists "${gccpath}/libatomic/libatomic.a"] { + append flags "-L${gccpath}/libatomic " + } + if [file exists "${gccpath}/libquadmath/.libs/libquadmath.a"] { + # Some targets use libquadmath.a%s in their specs, so they need a -B option + # for uninstalled testing. + append flags "-B${gccpath}/libquadmath/.libs " + append flags "-L${gccpath}/libquadmath/.libs " + append ld_library_path ":${gccpath}/libquadmath/.libs" + } + if [file exists "${gccpath}/libquadmath/.libs/libquadmath.${shlib_ext}"] { + append flags "-L${gccpath}/libquadmath/.libs " + append ld_library_path ":${gccpath}/libquadmath/.libs" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + append ld_library_path \ + [gcc-set-multilib-library-path $GFORTRAN_UNDER_TEST ] + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# gfortran_init -- called at the start of each subdir of tests +# + +proc gfortran_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global objdir srcdir + global ALWAYS_GFORTRANFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GFORTRAN_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + global TEST_ALWAYS_FLAGS + global gfortran_init_set_GFORTRAN_UNDER_TEST + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + set gcc_warning_prefix "\[Ww\]arning:" + set gcc_error_prefix "(Fatal )?\[Ee\]rror:" + + # Many hosts now default to a non-ASCII C locale, however, so + # they can set a charset encoding here if they need. + if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII + } + + # GFORTRAN_UNDER_TEST as set below contains $specpath, which depends on + # the used multilib config. Thus, its value may need to be reset; + # that's tracked via gfortran_init_set_GFORTRAN_UNDER_TEST. + if { ![info exists GFORTRAN_UNDER_TEST] + || [info exists gfortran_init_set_GFORTRAN_UNDER_TEST] } then { + if [info exists TOOL_EXECUTABLE] { + set GFORTRAN_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GFORTRAN_UNDER_TEST [transform gfortran] + } else { + if [info exists TOOL_OPTIONS] { + set specpath [get_multilibs ${TOOL_OPTIONS}] + } else { + set specpath [get_multilibs] + } + set gfortran_init_set_GFORTRAN_UNDER_TEST 1 + set GFORTRAN_UNDER_TEST [findfile $base_dir/../../gfortran "$base_dir/../../gfortran -B$base_dir/../../ -B$specpath/libgfortran/" [findfile $base_dir/gfortran "$base_dir/gfortran -B$base_dir/" [transform gfortran]]] + } + } + } + + if ![is_remote host] { + if { [which $GFORTRAN_UNDER_TEST] == 0 } then { + perror "GFORTRAN_UNDER_TEST ($GFORTRAN_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + gfortran_maybe_build_wrapper "${tmpdir}/gfortran-testglue.o" + + set ALWAYS_GFORTRANFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TOOL_OPTIONS" + } + + verbose -log "ALWAYS_GFORTRANFLAGS set to $ALWAYS_GFORTRANFLAGS" + + verbose "gfortran is initialized" 3 +} + +# +# gfortran_target_compile -- compile a source file +# + +proc gfortran_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global ALWAYS_GFORTRANFLAGS + global GFORTRAN_UNDER_TEST + global TEST_ALWAYS_FLAGS + global flags_to_postpone + global board_info + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options] + } + + # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is + # appended here to multilib_flags as it can be overridden by the latter + # if it was added earlier. After the target_compile, multilib_flags is + # restored to its orignal content. + set tboard [target_info name] + if {[board_info $tboard exists multilib_flags]} { + set orig_multilib_flags "[board_info [target_info name] multilib_flags]" + append board_info($tboard,multilib_flags) " $flags_to_postpone" + } + + lappend options "compiler=$GFORTRAN_UNDER_TEST" + lappend options "timeout=[timeout_value]" + + set options [concat "$ALWAYS_GFORTRANFLAGS" $options] + set options [dg-additional-files-options $options $source] + set return_val [target_compile $source $dest $type $options] + + if {[board_info $tboard exists multilib_flags]} { + set board_info($tboard,multilib_flags) $orig_multilib_flags + set flags_to_postpone "" + } + + return $return_val +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gnat-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gnat-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..199c9c24938b684d55260717a8a9fa9dd92eff79 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gnat-dg.exp @@ -0,0 +1,89 @@ +# Copyright (C) 2006-2022 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 +# . + +load_lib gcc-dg.exp + +# Remove VALUE from LIST_VARIABLE. +proc lremove {list_variable value} { + upvar 1 $list_variable var + set idx [lsearch -exact $var $value] + set var [lreplace $var $idx $idx] +} + +# Define gcc callbacks for dg.exp. + +proc gnat-dg-test { prog do_what extra_tool_flags } { + if { $do_what == "compile" } { + lappend extra_tool_flags "-c" + lappend extra_tool_flags "-u" + } + set result [gcc-dg-test-1 gnat_target_compile $prog $do_what $extra_tool_flags] + + # Remove additional output files apart from $output_file, which may be + # needed by dg-final. + set output_file [lindex $result 1] + set basename [file rootname $output_file] + set clean_result [remote_exec host [find_gnatclean] "-c -q -n $basename"] + if { [lindex $clean_result 0] != -1 } { + set clean_files [lindex $clean_result 1] + # Purge NL from clean_files. + regsub -all "\[\r\n\]+" $clean_files " " clean_files + # Remove ./ so lremove works. + regsub -all "\./" $clean_files "" clean_files + lremove clean_files $output_file + eval remote_file host delete $clean_files + } + + return $result +} + +proc gnat-dg-prune { system text } { + global additional_prunes + + lappend additional_prunes "gnatmake" + lappend additional_prunes "compilation abandoned" + lappend additional_prunes "fatal error: maximum errors reached" + lappend additional_prunes "linker input file" + + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# +# gnat_load -- wrapper around default gnat_load to declare tasking tests +# unsupported on platforms that lack such support +# + +if { [info procs gnat_load] != [list] \ + && [info procs prev_gnat_load] == [list] } { + rename gnat_load prev_gnat_load + + proc gnat_load { program args } { + upvar name testcase + + set result [eval [list prev_gnat_load $program] $args] + set output [lindex $result 1] + if { [regexp "tasking not implemented" $output] } { + return [list "unsupported" $output] + } + return $result + } +} + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gnat.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gnat.exp new file mode 100644 index 0000000000000000000000000000000000000000..2b732da59898edcf9e37a1acadfb797153b731e6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/gnat.exp @@ -0,0 +1,248 @@ +# Copyright (C) 2006-2022 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 +# . + +# This file was written by James A. Morrison (ja2morri@uwaterloo.ca) +# based on gcc.exp written by Rob Savoye (rob@cygnus.com). + +# This file is loaded by the tool init file (eg: unix.exp). It provides +# default definitions for gnat_start, etc. and other supporting cast members. + +load_lib prune.exp +load_lib gcc-defs.exp +load_lib gcc.exp +load_lib timeout.exp + +# +# GNAT_UNDER_TEST is the compiler under test. +# + +# +# default_gnat_version -- extract and print the version number of the compiler +# + +proc default_gnat_version { } { + global GNAT_UNDER_TEST + + gnat_init + + # ignore any arguments after the command + set compiler [lindex $GNAT_UNDER_TEST 0] + + if ![is_remote host] { + set compiler_name [which $compiler] + } else { + set compiler_name $compiler + } + + # verify that the compiler exists + if { $compiler_name != 0 } then { + set tmp [remote_exec host "$compiler --version"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp "^GNATMAKE (\[^\n\r\]*)" $output verline version + if { $status == 0 && [info exists version] } then { + # test_summary expects "version" as second field. + clone_output "$compiler_name version $version\n" + } else { + clone_output "Couldn't determine version of $compiler_name: $output\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# gnat_version -- Call default_gnat_version, so we can override it if needed. +# + +proc gnat_version { } { + default_gnat_version +} + +# +# gnat_init -- called at the start of each .exp script. +# + +set gnat_initialized 0 + +proc gnat_init { args } { + global rootme + global tmpdir + global libdir + global gluefile wrap_flags + global gnat_initialized + global GNAT_UNDER_TEST + global TOOL_EXECUTABLE + global gnat_target_current + + set gnat_target_current "" + + if { $gnat_initialized == 1 } { return } + + if ![info exists GNAT_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GNAT_UNDER_TEST "$TOOL_EXECUTABLE" + } else { + set GNAT_UNDER_TEST "[local_find_gnatmake]" + } + } + + if ![info exists tmpdir] then { + set tmpdir /tmp + } +} + +proc gnat_target_compile { source dest type options } { + global rootme + global tmpdir + global gluefile wrap_flags + global srcdir + global GNAT_UNDER_TEST + global TOOL_OPTIONS + global gnat_target_current + global TEST_ALWAYS_FLAGS + + # dg-require-effective-target tests must be compiled as C. + if [ string match "*.c" $source ] then { + return [gcc_target_compile $source $dest $type $options] + } + + # If we detect a change of target, we need to recompute both + # GNAT_UNDER_TEST and the appropriate RTS. + if { $gnat_target_current!="[current_target_name]" } { + set gnat_target_current "[current_target_name]" + if [info exists TOOL_OPTIONS] { + set rtsdir "[get_multilibs ${TOOL_OPTIONS}]/libada" + } else { + set rtsdir "[get_multilibs]/libada" + } + if [info exists TOOL_EXECUTABLE] { + set GNAT_UNDER_TEST "$TOOL_EXECUTABLE" + } else { + set GNAT_UNDER_TEST "[local_find_gnatmake]" + } + set GNAT_UNDER_TEST "$GNAT_UNDER_TEST --RTS=$rtsdir" + + # gnatlink looks for system.ads itself and has no --RTS option, so + # specify via environment + setenv ADA_INCLUDE_PATH "$rtsdir/adainclude" + setenv ADA_OBJECTS_PATH "$rtsdir/adainclude" + # Always log so compilations can be repeated manually. + verbose -log "ADA_INCLUDE_PATH=$rtsdir/adainclude" + verbose -log "ADA_OBJECTS_PATH=$rtsdir/adainclude" + } + + lappend options "compiler=$GNAT_UNDER_TEST -q -f" + lappend options "timeout=[timeout_value]" + + if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" + } + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options] + } + + # TOOL_OPTIONS must come first, so that it doesn't override testcase + # specific options. + if [info exists TOOL_OPTIONS] { + set options [concat "additional_flags=$TOOL_OPTIONS" $options] + } + + set options [concat "{ada}" $options] + + return [target_compile $source $dest $type $options] +} + +# Prune messages from GNAT that aren't useful. + +proc prune_gnat_output { text } { + #send_user "Before:$text\n" + regsub -all "(^|\n)\[^\n\]*: In (function|method) \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: At top level:\[^\n\]*" $text "" text + + # prune the output from gnatmake. + regsub -all "(^|\n)\[^\n\]*gnatmake: [^\n\]*" $text "" text + + # It would be nice to avoid passing anything to gnat that would cause it to + # issue these messages (since ignoring them seems like a hack on our part), + # but that's too difficult in the general case. For example, sometimes + # you need to use -B to point gnat at crt0.o, but there are some targets + # that don't have crt0.o. + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text + + #send_user "After:$text\n" + + return $text +} + +# find_gnatmake for some version of DejaGnu will hardcode a -I...rts/ada flag +# which prevent multilib from working, so define a new one. + +proc local_find_gnatmake {} { + global tool_root_dir + + if ![is_remote host] { + set file [lookfor_file $tool_root_dir gnatmake] + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/gnatmake] + } + if { $file != "" } { + set root [file dirname $file] + # Need to pass full --GCC, including multilib flags, to gnatlink, + # otherwise gcc from PATH is invoked. + set dest [target_info name] + set gnatlink_gcc "--GCC=$root/xgcc -B$root [board_info $dest multilib_flags]" + # Escape blanks to get them through DejaGnu's exec machinery. + regsub -all {\s} "$gnatlink_gcc" {\\&} gnatlink_gcc + set CC "$file --GCC=$root/xgcc --GNATBIND=$root/gnatbind --GNATLINK=$root/gnatlink -cargs -B$root -largs $gnatlink_gcc -margs"; + } else { + set CC [transform gnatmake] + } + } else { + set CC [transform gnatmake] + } + return $CC +} + +proc find_gnatclean {} { + global tool_root_dir + + if ![is_remote host] { + set file [lookfor_file $tool_root_dir gnatclean] + if { $file == "" } { + set file [lookfor_file $tool_root_dir gcc/gnatclean] + } + if { $file != "" } { + set gnatclean $file; + } else { + set gnatclean [transform gnatclean] + } + } else { + set gnatclean [transform gnatclean] + } + return $gnatclean +} + +# Local Variables: +# tcl-indent-level:4 +# End: diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..9aa77efa705f448556a7e2c25b2bb90341440c7f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go-dg.exp @@ -0,0 +1,65 @@ +# Copyright (C) 2009-2022 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 +# . + +load_lib gcc-dg.exp + +# Define go callbacks for dg.exp. + +proc go-dg-test { prog do_what extra_tool_flags } { + set result \ + [gcc-dg-test-1 go_target_compile $prog $do_what $extra_tool_flags] + + set comp_output [lindex $result 0] + set output_file [lindex $result 1] + + return [list $comp_output $output_file] +} + +proc go-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc go-dg-runtest { testcases flags default-extra-flags } { + global runtests + global TORTURE_OPTIONS + + foreach test $testcases { + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # look if this is dg-do-run test, in which case + # we cycle through the option list, otherwise we don't + if [expr [search_for $test "dg-do run"]] { + set option_list $TORTURE_OPTIONS + } else { + set option_list [list { -O } ] + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + verbose "Testing $nshort, $flags $flags_t" 1 + dg-test $test "$flags $flags_t" ${default-extra-flags} + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..f86eb89db16aaa2477fa745694c2c8d107d44e73 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go-torture.exp @@ -0,0 +1,382 @@ +# Copyright (C) 2009-2022 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 +# . + +# Please email any bugs, comments, and/or additions to this file to +# the author. + +# This file was written by Ian Lance Taylor based on +# fortran-torture.exp by Steven Bosscher and Rob Savoye. + +load_lib target-supports.exp + +load_lib target-utils.exp + +# The default option list can be overridden by +# TORTURE_OPTIONS="{ { list1 } ... { listN } }" + +if ![info exists TORTURE_OPTIONS] { + set TORTURE_OPTIONS [list \ + { -O0 } { -O1 } { -O2 } \ + { -O2 -fomit-frame-pointer -finline-functions } \ + { -O2 -fomit-frame-pointer -finline-functions -funroll-loops } \ + { -O2 -fbounds-check } \ + { -O3 -g } \ + { -Os }] + + if [check_effective_target_lto] { + set TORTURE_OPTIONS \ + [concat $TORTURE_OPTIONS [list {-flto}]] + } +} + +# +# go-torture-compile -- compile a go.go-torture testcase. +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc go-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and get results in comp_output. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [go_target_compile "$src" "$output" object $options] + + # See if we got something bad. + set fatal_signal "*go*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + go_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $output } + return + } + + if [string match "$fatal_signal 11" $comp_output] then { + go_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $output } + return + } + + if [regexp -line -- "internal compiler error.*" $comp_output ice] then { + go_fail $testcase "$option ($ice)" + catch { remote_file build delete $output } + return + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*go*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $output } + return + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [go_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + catch { remote_file build delete $output } + return + } + + # remove any leftover LF/CR to make sure any output is legit + regsub -all -- "\[\r\n\]*" $comp_output "" comp_output + + # If any message remains, we fail. + if ![string match "" $comp_output] then { + go_fail $testcase $option + catch { remote_file build delete $output } + return + } + + go_pass $testcase $option + catch { remote_file build delete $output } +} + + +# +# go-torture-execute -- compile and execute a testcase. +# +# SRC is the full pathname of the testcase. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc go-torture-execute { src } { + global output + global srcdir tmpdir + global tool + global compiler_conditional_xfail_data + global TORTURE_OPTIONS + global go_compile_args + global go_execute_args + + # Check for alternate driver. + set additional_flags "" + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Setup the options for the testcase run. + set option_list $TORTURE_OPTIONS + set executable $tmpdir/[file tail [file rootname $src].x] + regsub "(?q)$srcdir/" $src "" testcase + + if { ! [info exists go_compile_args] } { + set go_compile_args "" + } + if { ! [info exists go_execute_args] } { + set go_execute_args "" + } + + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + # Walk the list of options and copmile and run the testcase for all + # options that are not explicitly disabled by the .x script (if present). + foreach option $option_list { + + # Torture_{compile,execute}_xfail are set by the .x script. + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # Torture_execute_before_{compile,execute} can be set by the .x script. + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + # FIXME: We should make sure that the modules required by this testcase + # exist. If not, the testcase should XFAIL. + + # Compile the testcase. + catch { remote_file build delete $executable } + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + if { $go_compile_args != "" } { + lappend options "additional_flags=$go_compile_args" + } + set comp_output [go_target_compile "$src" "$executable" executable $options] + + # See if we got something bad. + set fatal_signal "*go*: Internal compiler error: program*got fatal signal" + + if [string match "$fatal_signal 6" $comp_output] then { + go_fail $testcase "Got Signal 6, $option" + catch { remote_file build delete $executable } + continue + } + + if [string match "$fatal_signal 11" $comp_output] then { + go_fail $testcase "Got Signal 11, $option" + catch { remote_file build delete $executable } + continue + } + + if [regexp -line -- "internal compiler error.*" $comp_output ice] then { + go_fail $testcase "$option ($ice)" + catch { remote_file build delete $executable } + continue + } + + # We shouldn't get these because of -w, but just in case. + if [string match "*go*:*warning:*" $comp_output] then { + warning "$testcase: (with warnings) $option" + send_log "$comp_output\n" + unresolved "$testcase, $option" + catch { remote_file build delete $executable } + continue + } + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + # Report if the testcase is not supported. + set unsupported_message [go_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$testcase: $unsupported_message" + continue + } elseif ![file exists $executable] { + if ![is3way] { + fail "$testcase compilation, $option" + untested "$testcase execution, $option" + continue + } else { + # FIXME: since we can't test for the existence of a remote + # file without short of doing an remote file list, we assume + # that since we got no output, it must have compiled. + pass "$testcase compilation, $option" + } + } else { + pass "$testcase compilation, $option" + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + # Run the testcase, and analyse the output. + set result [go_load "$executable" "$go_execute_args" ""] + set status [lindex $result 0] + set output [lindex $result 1] + + # In order to cooperate nicely with the master Go testsuite, + # if the output contains the string BUG, we treat the test as + # failing. + if [ string match "*BUG*" $output ] { + set status "fail" + } + + if { $status == "pass" } { + catch { remote_file build delete $executable } + } + $status "$testcase execution, $option" + } +} + + +# +# search_for_re -- looks for a string match in a file +# +proc search_for_re { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + set lower [string tolower $cur_line] + if [regexp "$pattern" $lower] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + + +# +# go-torture -- the go-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# +# SRC is the full pathname of the testcase, or just a file name in which +# case we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc go-torture { args } { + global srcdir subdir + global compiler_conditional_xfail_data + global TORTURE_OPTIONS + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # loop through all the options + set option_list $TORTURE_OPTIONS + foreach option $option_list { + + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + go-torture-compile $src "$option $options" + } +} + +# +# add-ieee-options -- add options necessary for 100% ieee conformance. +# +proc add-ieee-options { } { + # Ensure that excess precision does not cause problems. + if { [istarget i?86-*-*] + || [istarget m68k-*-*] } then { + uplevel 1 lappend additional_flags "-ffloat-store" + } + + # Enable full IEEE compliance mode. + if { [istarget alpha*-*-*] + || [istarget sh*-*-*] } then { + uplevel 1 lappend additional_flags "-mieee" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go.exp new file mode 100644 index 0000000000000000000000000000000000000000..019f2cdb30ae6024dfd3bb05d2ec7a05b682d6a3 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/go.exp @@ -0,0 +1,226 @@ +# Copyright (C) 2009-2022 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 +# . + +# +# go support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# GOC_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" + + +# +# go_version -- extract and print the version number of the compiler +# + +proc go_version { } { + global GOC_UNDER_TEST + + go_init + + # ignore any arguments after the command + set compiler [lindex $GOC_UNDER_TEST 0] + + # verify that the compiler exists + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# go_include_flags -- include flags for the gcc tree structure +# + +proc go_include_flags { paths } { + global srcdir + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set gccpath ${paths} + + if { $gccpath != "" } { + if [file exists "${gccpath}/libgo/os.gox"] { + append flags "-I${gccpath}/libgo " + } + } +} + +# +# go_link_flags -- linker flags for the gcc tree structure +# + +proc go_link_flags { paths } { + global srcdir + global ld_library_path + global GOC_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/libgo/libgobegin.a"] { + append flags "-L${gccpath}/libgo " + } + if { [file exists "${gccpath}/libgo/.libs/libgo.a"] \ + || [file exists "${gccpath}/libgo/.libs/libgo.${shlib_ext}"] } { + append flags "-L${gccpath}/libgo/.libs " + append ld_library_path ":${gccpath}/libgo/.libs" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags "-L${gccpath}/libiberty " + } + append ld_library_path \ + [gcc-set-multilib-library-path $GOC_UNDER_TEST] + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# go_init -- called at the start of each subdir of tests +# + +proc go_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags + global objdir srcdir + global ALWAYS_GOCFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global GOC_UNDER_TEST + global TESTING_IN_BUILD_TREE + global TEST_ALWAYS_FLAGS + + # We set LC_ALL and LANG to C so that we get the same error messages as expected. + setenv LC_ALL C + setenv LANG C + + if ![info exists GOC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set GOC_UNDER_TEST $TOOL_EXECUTABLE + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set GOC_UNDER_TEST [transform gccgo] + } else { + set GOC_UNDER_TEST [findfile $base_dir/../../gccgo "$base_dir/../../gccgo -B$base_dir/../../" [findfile $base_dir/gccgo "$base_dir/gccgo -B$base_dir/" [transform gccgo]]] + } + } + } + + if ![is_remote host] { + if { [which $GOC_UNDER_TEST] == 0 } then { + perror "GOC_UNDER_TEST ($GOC_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + go_maybe_build_wrapper "${tmpdir}/go-testglue.o" + + set ALWAYS_GOCFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_GOCFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GOCFLAGS "additional_flags=[go_include_flags [get_multilibs ${TOOL_OPTIONS}] ]" + lappend ALWAYS_GOCFLAGS "ldflags=[go_link_flags [get_multilibs ${TOOL_OPTIONS}] ]" + } else { + lappend ALWAYS_GOCFLAGS "additional_flags=[go_include_flags [get_multilibs] ]" + lappend ALWAYS_GOCFLAGS "ldflags=[go_link_flags [get_multilibs] ]" + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_GOCFLAGS "additional_flags=$TOOL_OPTIONS" + } + + verbose -log "ALWAYS_GOCFLAGS set to $ALWAYS_GOCFLAGS" + + verbose "go is initialized" 3 +} + +# +# go_target_compile -- compile a source file +# + +proc go_target_compile { source dest type options } { + global tmpdir + global gluefile wrap_flags + global ALWAYS_GOCFLAGS + global GOC_UNDER_TEST + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + lappend options "timeout=[timeout_value]" + lappend options "compiler=$GOC_UNDER_TEST" + + set options [concat "$ALWAYS_GOCFLAGS" $options] + set options [dg-additional-files-options $options $source] + return [target_compile $source $dest $type $options] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/hwasan-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/hwasan-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..54d0f60a429fc77e4ba6ab6e20986fa8e1bdd335 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/hwasan-dg.exp @@ -0,0 +1,167 @@ +# Copyright (C) 2020-2022 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 +# . + +load_lib asan-dg.exp + +# Return 1 if target can compile a binary for hardware address +# sanitization, 0 otherwise. +# +# NOTE: This should only be used between calls to hwasan_init and +# hwasan_finish. It is therefore defined here rather than in +# target-supports.exp. + +proc check_effective_target_fsanitize_hwaddress {} { + if ![check_no_compiler_messages fsanitize_hwaddress executable { + int main (void) { return 0; } + }] { + return 0; + } + return 1; +} + +# Return 1 if target can compile and run a binary for hardware address +# sanitization, 0 otherwise. +# +# NOTE: This should only be used between calls to hwasan_init and +# hwasan_finish. It is therefore defined here rather than in +# target-supports.exp. + +proc check_effective_target_hwaddress_exec {} { + if ![check_runtime hwaddress_exec { + #ifdef __cplusplus + extern "C" { + #endif + extern int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long); + #ifdef __cplusplus + } + #endif + int main (void) { + #define PR_SET_TAGGED_ADDR_CTRL 55 + #define PR_GET_TAGGED_ADDR_CTRL 56 + #define PR_TAGGED_ADDR_ENABLE (1UL << 0) + if (prctl (PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) == -1) + return 1; + if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == -1 + || !prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) + return 1; + return 0; + } + }] { + return 0; + } + return 1; +} + +proc hwasan_include_flags {} { + global srcdir + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set flags "-I$srcdir/../../libsanitizer/include" + + return "$flags" +} + +# +# hwasan_link_flags -- compute library path and flags to find libhwasan. +# (implementation in asan-dg.exp) +# + +proc hwasan_link_flags { paths } { + return [asan_link_flags_1 $paths hwasan] +} + +# +# hwasan_init -- called at the start of each subdir of tests +# + +proc hwasan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global hwasan_saved_TEST_ALWAYS_FLAGS + global hwasan_saved_ALWAYS_CXXFLAGS + + setenv HWASAN_OPTIONS "random_tags=0" + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[hwasan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[hwasan_link_flags [get_multilibs]]" + } + } + + set include_flags "[hwasan_include_flags]" + + if [info exists TEST_ALWAYS_FLAGS] { + set hwasan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set hwasan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=hwaddress --param hwasan-random-frame-tag=0 -g $include_flags" + } + } +} + +# +# hwasan_finish -- called at the start of each subdir of tests +# + +proc hwasan_finish { args } { + global TEST_ALWAYS_FLAGS + global hwasan_saved_TEST_ALWAYS_FLAGS + global hwasan_saved_ALWAYS_CXXFLAGS + global hwasan_saved_library_path + global ld_library_path + + unsetenv HWASAN_OPTIONS + + if [info exists hwasan_saved_ALWAYS_CXXFLAGS ] { + set ALWAYS_CXXFLAGS $hwasan_saved_ALWAYS_CXXFLAGS + } else { + if [info exists hwasan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $hwasan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + if [info exists hwasan_saved_library_path] { + set ld_library_path $hwasan_saved_library_path + set_ld_library_path_env_vars + } + clear_effective_target_cache +} + +# Utility for running gtest hwasan emulation under dejagnu, invoked via dg-final. +# Call pass if variable has the desired value, otherwise fail. +# +# Argument 0 handles expected failures and the like +proc hwasan-gtest { args } { + asan-gtest {*}$args +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/lto.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/lto.exp new file mode 100644 index 0000000000000000000000000000000000000000..35f1ec511c8ffc0f190dcc07a1fa54689a22d10e --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/lto.exp @@ -0,0 +1,903 @@ +# Copyright (C) 2009-2022 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 +# . + +# Contributed by Diego Novillo + +# A subroutine of lto_handle_diagnostics: check TEXT for the expected +# diagnostics for one specific source file, issuing PASS/FAIL results. +# Return TEXT, stripped of any diagnostics that were handled. +# +# NAME is the testcase name to use when reporting PASS/FAIL results. +# FILENAME is the name (with full path) of the file we're interested in. +# MESSAGES_FOR_FILE is a list of expected messages, akin to DejaGnu's +# "dg-messages" variable. +# TEXT is the textual output from the LTO link. + +proc lto_handle_diagnostics_for_file { name filename messages_for_file text } { + global dg-linenum-format + + set filename_without_path [file tail $filename] + + # This loop is adapted from the related part of DejaGnu's dg-test, + # with changes as detailed below to cope with the LTO case. + + foreach i ${messages_for_file} { + verbose "Scanning for message: $i" 4 + + # Remove all error messages for the line [lindex $i 0] + # in the source file. If we find any, success! + set line [lindex $i 0] + set pattern [lindex $i 2] + set comment [lindex $i 3] + verbose "line: $line" 4 + verbose "pattern: $pattern" 4 + verbose "comment: $comment" 4 + #send_user "Before:\n$text\n" + + # Unlike dg-test, we use $filename_without_path in this pattern. + # This is to ensure that we have the correct file/line combination. + # This imposes the restriction that the filename can't contain + # any regexp control characters. We have to strip the path, since + # e.g. the '+' in "g++.dg" wouldn't be valid. + set pat "(^|\n)(\[^\n\]+$filename_without_path$line\[^\n\]*($pattern)\[^\n\]*\n?)+" + if {[regsub -all $pat $text "\n" text]} { + set text [string trimleft $text] + set ok pass + set uhoh fail + } else { + set ok fail + set uhoh pass + } + #send_user "After:\n$text\n" + + # $line will either be a formatted line number or a number all by + # itself. Delete the formatting. + scan $line ${dg-linenum-format} line + + # Unlike dg-test, add the filename to the PASS/FAIL message (rather + # than just the line number) so that the user can identify the + # pertinent directive. + set describe_where "$filename_without_path line $line" + + # Issue the PASS/FAIL, adding "LTO" to the messages (e.g. "LTO errors") + # to distinguish them from the non-LTO case (in case we ever need to + # support both). + switch [lindex $i 1] { + "ERROR" { + $ok "$name $comment (test for LTO errors, $describe_where)" + } + "XERROR" { + x$ok "$name $comment (test for LTO errors, $describe_where)" + } + "WARNING" { + $ok "$name $comment (test for LTO warnings, $describe_where)" + } + "XWARNING" { + x$ok "$name $comment (test for LTO warnings, $describe_where)" + } + "BOGUS" { + $uhoh "$name $comment (test for LTO bogus messages, $describe_where)" + } + "XBOGUS" { + x$uhoh "$name $comment (test for LTO bogus messages, $describe_where)" + } + "BUILD" { + $uhoh "$name $comment (test for LTO build failure, $describe_where)" + } + "XBUILD" { + x$uhoh "$name $comment (test for LTO build failure, $describe_where)" + } + "EXEC" { } + "XEXEC" { } + } + } + return $text +} + +# Support for checking for link-time diagnostics: check for +# the expected diagnostics within TEXT, issuing PASS/FAIL results. +# Return TEXT, stripped of any diagnostics that were handled. +# +# TEXT is the textual output from the LTO link. + +proc lto_handle_diagnostics { text } { + global testcase + + upvar dg-messages-by-file messages_by_file + + verbose "lto_handle_diagnostics: entry: $text" 2 + + if { ![array exists messages_by_file] } { + error "lto_handle_diagnostics: messages_by_file not defined" + } + + foreach src [lsort [array names messages_by_file]] { + set dg-messages $messages_by_file($src) + verbose " messages for $src: ${dg-messages}" 3 + set text [lto_handle_diagnostics_for_file $testcase $src \ + ${dg-messages} $text] + } + + verbose "lto_handle_diagnostics: exit: $text" 2 + + return $text +} + +# Prune messages that aren't useful. + +proc lto_prune_warns { text } { + + verbose "lto_prune_warns: entry: $text" 2 + + # Many tests that use visibility will still pass on platforms that don't support it. + regsub -all "(^|\n)\[^\n\]*: warning: visibility attribute not supported in this configuration; ignored\[^\n\]*" $text "" text + + # Allow mixed-language LTO tests to pass with make check-c++0x + regsub -all "(^|\n)\[^\n\]*: warning: command line option '-std=\[^\n\]*" $text "" text + + # And any stray location lines. + regsub -all "(^|\n)\[^\n\]*: In function \[^\n\]*" $text "" text + regsub -all "(^|\n)In file included from \[^\n\]*" $text "" text + regsub -all "(^|\n)\[ \t\]*from \[^\n\]*" $text "" text + + # Sun ld warns about common symbols with differing sizes. Unlike GNU ld + # --warn-common (off by default), they cannot be disabled. + regsub -all "(^|\n)ld: warning: symbol \[`'\]\[^\n\]*' has differing sizes:" $text "" text + regsub -all "(^|\n)\[ \t\]*\[\(\]file \[^\n\]* value=\[^\n\]*; file \[^\n\]* value=\[^\n\]*\[)\];" $text "" text + regsub -all "(^|\n)\[ \t\]*\[^\n\]* definition taken" $text "" text + + # Ignore missing jobserver for tests that do more than 1 LTRANS unit + regsub -all "(^|\n)\[^\n\]*: warning: using serial compilation of \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: note: see the \[^\n\]*'-flto' option documentation\[^\n\]* for more information" $text "" text + + global prune_notes + if { $prune_notes } { + # Ignore informational notes. + regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text + } + + verbose "lto_prune_warns: exit: $text" 2 + + return $text +} + +# lto_init -- called at the start of each subdir of tests + +proc lto_init { args } { + global LTO_OPTIONS + + if {[info exists args] && $args == "no-mathlib"} { + global board_info + global saved_mathlib + + set dest [target_info name] + if [board_info $dest exists mathlib] { + set saved_mathlib [board_info $dest mathlib] + } + set board_info($dest,mathlib) " " + } + + # Each test is run with the compiler options from this list. + # The default option lists can be overridden by LTO_OPTIONS="[list + # {opts_1} {opts_2}... {opts_n}]" where opts_i are lists of options. + # You can put this in the environment before site.exp is written or + # add it to site.exp directly. + if ![info exists LTO_OPTIONS] { + if [check_linker_plugin_available] { + set LTO_OPTIONS [list \ + {-O0 -flto -flto-partition=none -fuse-linker-plugin} \ + {-O2 -flto -flto-partition=none -fuse-linker-plugin -fno-fat-lto-objects } \ + {-O0 -flto -flto-partition=1to1 -fno-use-linker-plugin } \ + {-O2 -flto -flto-partition=1to1 -fno-use-linker-plugin } \ + {-O0 -flto -fuse-linker-plugin -fno-fat-lto-objects } \ + {-O2 -flto -fuse-linker-plugin} \ + ] + } else { + set LTO_OPTIONS [list \ + {-O0 -flto -flto-partition=none } \ + {-O2 -flto -flto-partition=none } \ + {-O0 -flto -flto-partition=1to1 } \ + {-O2 -flto -flto-partition=1to1 } \ + {-O0 -flto } \ + {-O2 -flto} \ + ] + } + } +} + +# +# lto_finish -- called at the end of each subdir of tests if mathlib is +# changed. +# + +proc lto_finish { } { + global board_info + global saved_mathlib + + set dest [target_info name] + if [info exists saved_mathlib] { + set board_info($dest,mathlib) $saved_mathlib + } elseif [board_info $dest exists mathlib] { + unset board_info($dest,mathlib) + } +} + +# Subsets of tests can be selectively disabled by members of this list: +# - ATTRIBUTE: disable all tests using the __attribute__ extension, +# - COMPLEX: disable all tests using the complex types feature, +# - COMPLEX_INT: disable all tests using the complex integral types extension, +# - VA: disable all tests using the variable number of arguments feature, +# - VLA_IN_STRUCT: disable all tests using the variable-length arrays as +# structure members extension, +# - ZERO_ARRAY: disable all tests using the zero-sized arrays extension. +# The default skip lists can be overriden by +# LTO_SKIPS="[list {skip_1}...{skip_n}]" +# where skip_i are skip identifiers. You can put this in the environment +# before site.exp is written or add it to site.exp directly. +if ![info exists LTO_SKIPS] { + set LTO_SKIPS [list {}] +} + +global lto_skip_list +set lto_skip_list $LTO_SKIPS + +load_lib dg.exp +load_lib gcc-dg.exp +load_lib gcc.exp + +# lto-obj -- compile to an object file +# +# SOURCE is the source file +# DEST is the object file +# OPTALL is the list of compiler options to use with all tests +# OPTFILE is the list of compiler options to use with this file +# OPTSTR is the options to print with test messages +# XFAILDATA is the xfail data to be passed to the compiler +proc lto-obj { source dest optall optfile optstr xfaildata } { + global testcase + global tool + global compiler_conditional_xfail_data + global lto_skip_list + + # Add the skip specifiers. + foreach skip $lto_skip_list { + if { ![string match $skip ""] } { + lappend optall "-DSKIP_$skip" + } + } + + # Set up the options for compiling this file. + set options "" + lappend options "additional_flags=$optall $optfile" + + set compiler_conditional_xfail_data $xfaildata + + # Allow C source files to mix freely with other languages + if [ string match "*.c" $source ] then { + set comp_output [gcc_target_compile "$source" "$dest" object $options] + } else { + set comp_output [${tool}_target_compile "$source" "$dest" object $options] + } + # Prune unimportant visibility warnings before checking output. + set comp_output [lto_prune_warns $comp_output] + ${tool}_check_compile "$testcase $dest assemble" $optstr $dest $comp_output +} + +# lto-link-and-maybe-run -- link the object files and run the executable +# if compile_type is set to "run" +# +# TESTNAME is the mixture of object files to link +# OBJLIST is the list of object files to link +# DEST is the name of the executable +# OPTALL is a list of compiler and linker options to use for all tests +# OPTFILE is a list of compiler and linker options to use for this test +# OPTSTR is the list of options to list in messages +proc lto-link-and-maybe-run { testname objlist dest optall optfile optstr } { + global testcase + global tool + global compile_type + global board_info + + upvar dg-messages-by-file dg-messages-by-file + + verbose "lto-link-and-maybe-run" 2 + + # Check that all of the objects were built successfully. + foreach obj [split $objlist] { + if ![file_on_host exists $obj] then { + unresolved "$testcase $testname link $optstr" + unresolved "$testcase $testname execute $optstr" + return + } + } + + # Set up the options for linking this test. + set options "" + lappend options "additional_flags=$optall $optfile" + + set target_board [target_info name] + set relocatable 0 + + # Some LTO tests do relocatable linking. Some target boards set + # a linker script which can't be used for relocatable linking. + # Use the default linker script instead. + if { [lsearch -exact [split "$optall $optfile"] "-r"] >= 0 } { + set relocatable 1 + } + + if { $relocatable } { + set saved_ldscript [board_info $target_board ldscript] + set board_info($target_board,ldscript) "" + } + + # Link the objects into an executable. + set comp_output [${tool}_target_compile "$objlist" $dest executable \ + "$options"] + + if { $relocatable } { + set board_info($target_board,ldscript) $saved_ldscript + } + + # Check for diagnostics specified by directives + set comp_output [lto_handle_diagnostics $comp_output] + + # Prune unimportant visibility warnings before checking output. + set comp_output [lto_prune_warns $comp_output] + + if ![${tool}_check_compile "$testcase $testname link" $optstr \ + $dest $comp_output] then { + if { ![string compare "execute" $compile_type] } { + unresolved "$testcase $testname execute $optstr" + } + return + } + + # Return if we only needed to link. + if { ![string compare "link" $compile_type] } { + return + } + + # Run the self-checking executable. + if ![string match "*/*" $dest] then { + set dest "./$dest" + } + set result [${tool}_load $dest "" ""] + set status [lindex $result 0] + if { $status == "pass" } then { + file_on_host delete $dest + } + $status "$testcase $testname execute $optstr" +} + +# Potentially handle the given dg- directive (a list) +# Return true is the directive was handled, false otherwise. + +proc lto-can-handle-directive { op } { + set cmd [lindex $op 0] + + # dg-warning and dg-message append to dg-messages. + upvar dg-messages dg-messages + + # A list of directives to recognize, and a list of directives + # to remap them to. + # For example, "dg-lto-warning" is implemented by calling "dg-warning". + set directives { dg-lto-warning dg-lto-message dg-lto-note } + set remapped_directives { dg-warning dg-message dg-note } + + set idx [lsearch -exact $directives $cmd] + if { $idx != -1 } { + verbose "remapping from: $op" 4 + + set remapped_cmd [lindex $remapped_directives $idx] + set op [lreplace $op 0 0 $remapped_cmd] + + verbose "remapped to: $op" 4 + + set status [catch "$op" errmsg] + if { $status != 0 } { + if { 0 && [info exists errorInfo] } { + # This also prints a backtrace which will just confuse + # testcase writers, so it's disabled. + perror "$name: $errorInfo\n" + } else { + perror "$name: $errmsg for \"$op\"\n" + } + # ??? The call to unresolved here is necessary to clear `errcnt'. + # What we really need is a proc like perror that doesn't set errcnt. + # It should also set exit_status to 1. + unresolved "$name: $errmsg for \"$op\"" + } + + return true + } + + return false +} + +# lto-get-options-main -- get target requirements for a test and +# options for the primary source file and the test as a whole +# +# SRC is the full pathname of the primary source file. +proc lto-get-options-main { src } { + global compile_type + global dg-extra-ld-options + global dg-suppress-ld-options + + set dg-extra-ld-options "" + set dg-suppress-ld-options "" + + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-options sets a variable called tool_flags. + set tool_flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + upvar dg-final-code dg-final-code + set dg-final-code "" + + # dg-warning and dg-message append to dg-messages. + upvar dg-messages-by-file dg-messages-by-file + set dg-messages "" + + set tmp [dg-get-options $src] + verbose "getting options for $src: $tmp" + foreach op $tmp { + set cmd [lindex $op 0] + verbose "cmd is $cmd" + if { [string match "dg-skip-if" $cmd] \ + || [string match "dg-require-*" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { [string match "dg-lto-options" $cmd] } { + set op [lreplace $op 0 0 "dg-options"] + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { ![string compare "dg-xfail-if" $cmd] \ + || ![string compare "dg-options" $cmd] } { + warning "lto.exp does not support $cmd in primary source file" + } elseif { ![string compare "dg-lto-do" $cmd] } { + if { [llength $op] > 3 } { + set kw [lindex [lindex $op 3] 0] + if [string match "target" $kw] { + perror "$src: dg-lto-do does not support \"target\"" + } elseif [string match "xfail" $kw] { + perror "$src: dg-lto-do does not support \"xfail\"" + } else { + perror "$src: dg-lto-do takes a single argument" + } + } + set dgdo [lindex $op 2] + verbose "dg-lto-do command for \"$op\" is $dgdo" + if { ![string compare "assemble" $dgdo] } { + set compile_type "assemble" + } elseif { ![string compare "run" $dgdo] } { + set compile_type "run" + } elseif { ![string compare "link" $dgdo] } { + set compile_type "link" + } else { + warning "lto.exp does not support dg-lto-do $dgdo" + } + } elseif { ![string compare "dg-extra-ld-options" $cmd] } { + if { [llength $op] > 4 } { + error "[lindex $op 0]: too many arguments" + } else { + if { [llength $op] == 3 + || ([llength $op] > 3 + && [dg-process-target [lindex $op 3]] == "S") } { + set dg-extra-ld-options [lindex $op 2] + verbose \ + "dg-extra-ld-options for main is ${dg-extra-ld-options}" + } + } + } elseif { ![string compare "dg-suppress-ld-options" $cmd] } { + if { [llength $op] > 4 } { + error "[lindex $op 0]: too many arguments" + } else { + if { [llength $op] == 3 + || ([llength $op] > 3 + && [dg-process-target [lindex $op 3]] == "S") } { + set dg-suppress-ld-options [lindex $op 2] + verbose \ + "dg-suppress-ld-options for main is ${dg-suppress-ld-options}" + } + } + } elseif { ![string compare "dg-final" $cmd] } { + if { [llength $op] > 3 } { + error "[lindex $op 0]: too many arguments" + } else { + append dg-final-code "[lindex $op 2]\n" + } + } elseif { ![lto-can-handle-directive $op] } { + # Ignore unrecognized dg- commands, but warn about them. + warning "lto.exp does not support $cmd" + } + } + + verbose "dg-messages: ${dg-messages}" 3 + set dg-messages-by-file($src) ${dg-messages} + + # Return flags to use for compiling the primary source file and for + # linking. + verbose "dg-extra-tool-flags for main is ${dg-extra-tool-flags}" + return ${dg-extra-tool-flags} +} + + +# lto-get-options -- get special tool flags to use for a secondary +# source file +# +# SRC is the full pathname of the source file. +# The result is a list of options to use. +# +# This code is copied from proc dg-test in dg.exp from DejaGNU. +proc lto-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-xfail-if sets compiler_conditional_xfail_data. + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data "" + + # dg-xfail-if needs access to dg-do-what. + upvar dg-do-what dg-do-what + + # dg-warning appends to dg-messages. + upvar dg-messages-by-file dg-messages-by-file + set dg-messages "" + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || ![string compare "dg-xfail-if" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } elseif { [string match "dg-require-*" $cmd] } { + warning "lto.exp does not support $cmd in secondary source files" + } elseif { ![lto-can-handle-directive $op] } { + # Ignore unrecognized dg- commands, but warn about them. + warning "lto.exp does not support $cmd in secondary source files" + } + } + + verbose "dg-messages: ${dg-messages}" 3 + if { [info exists dg-messages-by-file($src)] } { + append dg-messages-by-file($src) ${dg-messages} + } else { + set dg-messages-by-file($src) ${dg-messages} + } + + return ${dg-extra-tool-flags} +} + +# lto-execute -- compile multi-file tests +# +# SRC1 is the full pathname of the main file of the testcase. +# SID identifies a test suite in the names of temporary files. +proc lto-execute-1 { src1 sid } { + global srcdir tmpdir + global lto_option_list + global tool + global verbose + global testcase + global gluefile + global compiler_conditional_xfail_data + global dg-do-what-default + global compile_type + global dg-extra-ld-options + global dg-suppress-ld-options + global LTO_OPTIONS + global dg-final-code + global testname_with_flags + + # Get extra flags for this test from the primary source file, and + # process other dg-* options that this suite supports. Warn about + # unsupported flags. + verbose "lto-execute: $src1" 1 + set compile_type "run" + set dg-do-what [list ${dg-do-what-default} "" P] + array set dg-messages-by-file [list] + set extra_flags(0) [lto-get-options-main $src1] + set compile_xfail(0) "" + + # If the main file defines dg-options, those flags are used to + # overwrite the default lto_option_list taken from LTO_OPTIONS. + if { [string length $extra_flags(0)] > 0 } { + set lto_option_list $extra_flags(0) + set extra_flags(0) "" + } else { + set lto_option_list $LTO_OPTIONS + } + + # Set up the names of the other source files. + set dir [file dirname $src1] + set base [file rootname $src1] + set base [string range $base [string length $dir] end] + regsub "_0" $base "" base + regsub "/" $base "" base + set src_list $src1 + set i 1 + set done 0 + while { !$done } { + set names [glob -nocomplain -types f -- "${dir}/${base}_${i}.*"] + if { [llength ${names}] > 1 } { + warning "lto-execute: more than one file matched ${dir}/${base}_${i}.*" + } + if { [llength ${names}] == 1 } { + lappend src_list [lindex ${names} 0] + incr i + } else { + set num_srcs ${i} + set done 1 + } + } + + # Use the dg-options mechanism to specify extra flags for each + # of the secondary files. + # The extra flags in each file are used to compile that file, and the + # extra flags in *_0.* are also used for linking. + verbose "\tsrc_list is: $src_list" + for {set i 1} {$i < $num_srcs} {incr i} { + set extra_flags($i) [lto-get-options [lindex $src_list $i]] + set compile_xfail($i) $compiler_conditional_xfail_data + } + + # Define the names of the object files. + set obj_list "" + for {set i 0} {$i < $num_srcs} {incr i} { + lappend obj_list "${sid}_${base}_${i}.o" + } + + # Get the base name of this test, for use in messages. + set testcase [lindex ${src_list} 0] + + # Remove the $srcdir and $tmpdir prefixes from $src1. (It would + # be possible to use "regsub" here, if we were careful to escape + # all regular expression characters in $srcdir and $tmpdir, but + # that would be more complicated that this approach.) + if {[string first "$srcdir/" "${testcase}"] == 0} { + set testcase [string range "${testcase}" [string length "$srcdir/"] end] + } + if {[string first "$tmpdir/" "$testcase"] == 0} { + set testcase [string range "$testcase" [string length "$tmpdir/"] end] + set testcase "tmpdir-$testcase" + } + # If we couldn't rip $srcdir out of `src1' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] then { + set testcase "[file tail [file dirname $src1]]/[file tail $src1]" + } + + # Check whether this test is supported for this target. + if { [lindex ${dg-do-what} 1 ] == "N" } { + unsupported "$testcase" + verbose "$testcase not supported on this target, skipping it" 3 + return + } + # Should be safe for non-fortran too but be paranoid.. + if {$sid eq "f_lto"} { + list-module-names $src_list + } + regsub "_0.*" $testcase "" testcase + + # Set up the base name of executable files so they'll be unique. + regsub -all "\[./\]" $testcase "-" execbase + + # Loop through all of the option lists used for this test. + set count 0 + foreach option $lto_option_list { + verbose "Testing $testcase, $option" + + # There's a unique name for each executable we generate. + set execname "${execbase}-${count}1.exe" + + # The LTO tests don't use dg-test, so testname_with_flags and + # output_file need to be defined explicitly for each file. scan-symbol + # directives rely on both of these to be defined to find the symbol to + # scan and for the text to print in the PASS/FAIL since they can also + # be called from dg-test. testname_with_flags is also used via + # testname-for-summary when calling into generic function below to + # clean temporary files. + set output_file $execname + set testname_with_flags $execname + + incr count + + file_on_host delete $execname + + # Compile pieces with the compiler under test. + set i 0 + foreach src $src_list obj $obj_list { + lto-obj $src $obj $option $extra_flags($i) $option \ + $compile_xfail($i) + incr i + } + + # Link (using the compiler under test), run, and clean up tests. + if { ![string compare "run" $compile_type] \ + || ![string compare "link" $compile_type] } { + + # Filter out any link options we were asked to suppress. + set reduced {} + foreach x [split $option] { + if {[lsearch ${dg-suppress-ld-options} $x] == -1} { + lappend reduced $x + } + } + set filtered [join $reduced " "] + + lto-link-and-maybe-run \ + "[lindex $obj_list 0]-[lindex $obj_list end]" \ + $obj_list $execname $filtered ${dg-extra-ld-options} \ + $filtered + } + + + # Are there any further tests to perform? + # Note that if the program has special run-time requirements, running + # of the program can be delayed until here. Ditto for other situations. + # It would be a bit cumbersome though. + + if ![string match ${dg-final-code} ""] { + regsub -all "\\\\(\[{}\])" ${dg-final-code} "\\1" dg-final-code + # Note that the use of `args' here makes this a varargs proc. + proc dg-final-proc { args } ${dg-final-code} + verbose "Running dg-final tests." 3 + verbose "dg-final-proc:\n[info body dg-final-proc]" 4 + if [catch "dg-final-proc $src1" errmsg] { + perror "$src1: error executing dg-final: $errmsg" + # ??? The call to unresolved here is necessary to clear + # `errcnt'. What we really need is a proc like perror that + # doesn't set errcnt. It should also set exit_status to 1. + unresolved "$src1: error executing dg-final: $errmsg" + } + } + + # Clean up object files. + set files [glob -nocomplain ${sid}_*.o] + if { $files != "" } { + foreach objfile $files { + if { ![info exists gluefile] || $objfile != $gluefile } { + eval "file_on_host delete $objfile" + } + } + } + + # Clean up after -save-temps. + eval "cleanup-saved-temps" + + for {set i 0} {$i < $num_srcs} {incr i} { + set testname_with_flags "${base}_${i}" + eval "cleanup-saved-temps" + set testname_with_flags "${sid}_${base}_${i}" + eval "cleanup-saved-temps" + } + + unset testname_with_flags + + if { ![string compare "run" $compile_type] \ + || ![string compare "link" $compile_type] } { + file_on_host delete $execname + } + # Should be safe for non-fortran too but be paranoid.. + if {$sid eq "f_lto"} { + cleanup-modules "" + } + } +} + +proc lto-execute { src1 sid } { + lto-execute-1 $src1 $sid + + # LTO testing doesn't use 'dg-runtest'/'dg-test', and thus doesn't call + # 'cleanup-after-saved-dg-test', so we have to clean up manually. + initialize_prune_notes +} + +# Call pass if object readelf is ok, otherwise fail. +# example: /* { dg-final { object-readelf Tag_ABI_enum_size int} } */ +proc object-readelf { args } { + global readelf + global base_dir + upvar 2 execname execname + + if { [llength $args] < 2 } { + error "object-readelf: too few arguments" + return + } + if { [llength $args] > 3 } { + error "object-readelf: too many arguments" + return + } + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find size like we find g++ in g++.exp. + if ![info exists readelf] { + set readelf [findfile $base_dir/../../../binutils/readelf \ + $base_dir/../../../binutils/readelf \ + [findfile $base_dir/../../readelf $base_dir/../../readelf \ + [findfile $base_dir/readelf $base_dir/readelf \ + [transform readelf]]]] + verbose -log "readelf is $readelf" + } + + set what [lindex $args 0] + set with [lindex $args 1] + + if ![file_on_host exists $execname] { + verbose -log "$execname does not exist" + unresolved "object-readelf $what " + return + } + + set output [remote_exec host "$readelf -A" "$execname"] + set status [lindex $output 0] + if { $status != 0 } { + verbose -log "object-readelf: $readelf failed" + unresolved "object-readelf $what $execname" + return + } + + set text [lindex $output 1] + set lines [split $text "\n"] + + set done 0 + set i 0 + while { !$done } { + set line_tex [lindex $lines $i] + if { [llength ${line_tex}] > 1} { + incr i + if [regexp -- $what $line_tex] { + set match [regexp -- $with $line_tex] + set done 1 + } + } else { + set done 1 + } + } + + verbose -log "$what size is $with;" + if { $match == 1 } { + pass "object-readelf $what size is correct." + } else { + fail "object-readelf $what size is incorrect." + } +} + + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/mike-g++.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/mike-g++.exp new file mode 100644 index 0000000000000000000000000000000000000000..22f01b800fc81aa7b95716fd0a3e2d5a1af473e8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/mike-g++.exp @@ -0,0 +1,263 @@ +# Copyright (C) 1988-2022 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 +# . + +# This file was written by Mike Stump + +load_lib target-utils.exp + +# +# mike_cleanup -- remove any files that are created by the testcase +# +proc mike_cleanup { src_code output_file assembly_file } { + remote_file build delete $output_file $assembly_file +} + +# +# prebase -- sets up a Mike Stump (mrs@cygnus.com) style G++ test +# +proc prebase { } { + global compiler_output + global not_compiler_output + global compiler_result + global not_compiler_result + global program_output + global groups + global run + global actions + global target_regexp + + set compiler_output "^$" + set not_compiler_output ".*Internal compiler error.*" + set compiler_result "" + set not_compiler_result "" + set program_output ".*PASS.*" + set groups {} + set run no + set actions assemble + set target_regexp ".*" +} + +# +# run the test +# +proc postbase { src_code run groups args } { + global verbose + global srcdir + global subdir + global not_compiler_output + global compiler_output + global compiler_result + global not_compiler_result + global program_output + global actions + global target_regexp + global host_triplet + global target_triplet + global tool + global tmpdir + global objdir + global base_dir + + if ![regexp $target_regexp $target_triplet] { + unsupported $subdir/$src_code + return + } + + if { [llength $args] > 0 } { + set comp_options [lindex $args 0] + } else { + set comp_options "" + } + + set fail_message $subdir/$src_code + set pass_message $subdir/$src_code + + if [info exists GROUP] { + if {[lsearch $groups $GROUP] == -1} { + return + } + } + + if [string match $run yes] { + set actions run + } + + set output_file "$tmpdir/[file tail [file rootname $src_code]]" + set assembly_file "$output_file" + append assembly_file ".S" + + set compile_type "none" + + case $actions { + compile + { + set compile_type "assembly" + set output_file $assembly_file + } + assemble + { + set compile_type "object" + append output_file ".o" + } + link + { + set compile_type "executable" + append output_file ".exe" + } + run + { + set compile_type "executable" + append output_file ".exe" + set run yes + } + default + { + set output_file "" + set compile_type "none" + } + } + + set src_file "$srcdir/$subdir/$src_code" + set options "" + + if { $comp_options != "" } { + lappend options "additional_flags=$comp_options" + } + + if ![ishost "*-dos-*"] { + lappend options "libs=-lstdc++ -lg++" + } else { + lappend options "libs=-lstdcxx -lgxx" + } + + set comp_output [g++_target_compile $src_file $output_file $compile_type $options] + + set pass no + + # Delete things like "ld.so warning" messages. + set comp_output [prune_warnings $comp_output] + + if [regexp -- $not_compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "\nChecking:\n$not_compiler_output\nto make sure it does not match:\n$comp_output\nbut it does.\n\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + fail $fail_message + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + mike_cleanup $src_code $output_file $assembly_file + return + } + + # remove any leftover CRs. + regsub -all -- "\r" $comp_output "" comp_output + + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $comp_output "" comp_output + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $comp_output "" comp_output + + set unsupported_message [${tool}_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$subdir/$src_code: $unsupported_message" + mike_cleanup $src_code $output_file $assembly_file + return + } + + if { $verbose > 1 } { + send_user "\nChecking:\n$compiler_output\nto see if it matches:\n$comp_output\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + if [regexp -- $compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + set pass yes + if [file exists [file rootname [file tail $src_code]].s] { + set fd [open [file rootname [file tail $src_code]].s r] + set dot_s [read $fd] + close $fd + if { $compiler_result != "" } { + verbose "Checking .s file for $compiler_result" 2 + if [regexp -- $compiler_result $dot_s] { + verbose "Yes, it matches." 2 + } else { + verbose "Nope, doesn't match." 2 + verbose $dot_s 4 + set pass no + } + } + if { $not_compiler_result != "" } { + verbose "Checking .s file for not $not_compiler_result" 2 + if ![regexp -- $not_compiler_result $dot_s] { + verbose "Nope, not found (that's good)." 2 + } else { + verbose "Uh oh, it was found." 2 + verbose $dot_s 4 + set pass no + } + } + } + if [string match $run yes] { + set result [g++_load $output_file] + set status [lindex $result 0] + set output [lindex $result 1] + + if { $status == -1 } { + mike_cleanup $src_code $output_file $assembly_file + return + } + if { $verbose > 1 } { + send_user "Checking:\n$program_output\nto see if it matches:\n$output\n\n" + } + if ![regexp -- $program_output $output] { + set pass no + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } else { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + } + } + } else { + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } + + if [string match $pass "yes"] { + pass $pass_message + } else { + fail $fail_message + } + + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + + mike_cleanup $src_code $output_file $assembly_file +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/mike-gcc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/mike-gcc.exp new file mode 100644 index 0000000000000000000000000000000000000000..f485632b74a1b039b05e0d603e29ab44b58c31a9 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/mike-gcc.exp @@ -0,0 +1,261 @@ +# Copyright (C) 1988-2022 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 +# . + +# This file was derived from mike-g++.exp written by Mike Stump + +load_lib target-utils.exp + +# +# mike_cleanup -- remove any files that are created by the testcase +# +proc mike_cleanup { src_code output_file assembly_file } { + remote_file build delete $output_file $assembly_file +} + +# +# prebase -- sets up a Mike Stump (mrs@cygnus.com) style gcc test +# +proc prebase { } { + global compiler_output + global not_compiler_output + global compiler_result + global not_compiler_result + global program_output + global groups + global run + global actions + global target_regexp + + set compiler_output "^$" + set not_compiler_output ".*Internal compiler error.*" + set compiler_result "" + set not_compiler_result "" + set program_output ".*PASS.*" + set groups {} + set run no + set actions assemble + set target_regexp ".*" +} + +# +# run the test +# +proc postbase { src_code run groups args } { + global verbose + global srcdir + global subdir + global not_compiler_output + global compiler_output + global compiler_result + global not_compiler_result + global program_output + global actions + global target_regexp + global host_triplet + global target_triplet + global tool + global tmpdir + global GCC_UNDER_TEST + global GROUP + + if ![info exists GCC_UNDER_TEST] { + error "No compiler specified for testing." + } + + if ![regexp $target_regexp $target_triplet] { + unsupported $subdir/$src_code + return + } + + if { [llength $args] > 0 } { + set comp_options [lindex $args 0] + } else { + set comp_options "" + } + + set fail_message $subdir/$src_code + set pass_message $subdir/$src_code + + if [info exists GROUP] { + if {[lsearch $groups $GROUP] == -1} { + return + } + } + + if [string match $run yes] { + set actions run + } + + set output_file "$tmpdir/[file tail [file rootname $src_code]]" + set assembly_file "$output_file" + append assembly_file ".S" + + set compile_type "none" + + case $actions { + compile + { + set compile_type "assembly" + set output_file $assembly_file + } + assemble + { + set compile_type "object" + append output_file ".o" + } + link + { + set compile_type "executable" + append output_file ".exe" + } + run + { + set compile_type "executable" + append output_file ".exe" + set run yes + } + default + { + set output_file "" + set compile_type "none" + } + } + + set src_file "$srcdir/$subdir/$src_code" + set options "" + lappend options "compiler=$GCC_UNDER_TEST" + + if { $comp_options != "" } { + lappend options "additional_flags=$comp_options" + } + + set comp_output [gcc_target_compile $src_file $output_file $compile_type $options] + + set pass no + + # Delete things like "ld.so warning" messages. + set comp_output [prune_warnings $comp_output] + + if [regexp -- $not_compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "\nChecking:\n$not_compiler_output\nto make sure it does not match:\n$comp_output\nbut it does.\n\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + fail $fail_message + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + mike_cleanup $src_code $output_file $assembly_file + return + } + + # remove any leftover CRs. + regsub -all -- "\r" $comp_output "" comp_output + + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $comp_output "" comp_output + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $comp_output "" comp_output + + set unsupported_message [${tool}_check_unsupported_p $comp_output] + if { $unsupported_message != "" } { + unsupported "$subdir/$src_code: $unsupported_message" + mike_cleanup $src_code $output_file $assembly_file + return + } + + if { $verbose > 1 } { + send_user "\nChecking:\n$compiler_output\nto see if it matches:\n$comp_output\n" + } else { + send_log "\nCompiler output:\n$comp_output\n\n" + } + if [regexp -- $compiler_output $comp_output] { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + set pass yes + if [file exists [file rootname [file tail $src_code]].s] { + set fd [open [file rootname [file tail $src_code]].s r] + set dot_s [read $fd] + close $fd + if { $compiler_result != "" } { + verbose "Checking .s file for $compiler_result" 2 + if [regexp -- $compiler_result $dot_s] { + verbose "Yes, it matches." 2 + } else { + verbose "Nope, doesn't match." 2 + verbose $dot_s 4 + set pass no + } + } + if { $not_compiler_result != "" } { + verbose "Checking .s file for not $not_compiler_result" 2 + if ![regexp -- $not_compiler_result $dot_s] { + verbose "Nope, not found (that's good)." 2 + } else { + verbose "Uh oh, it was found." 2 + verbose $dot_s 4 + set pass no + } + } + } + if [string match $run yes] { + set result [gcc_load $output_file] + set status [lindex $result 0] + set output [lindex $result 1] + if { $status == -1 } { + mike_cleanup $src_code $output_file $assembly_file + return + } + if { $verbose > 1 } { + send_user "Checking:\n$program_output\nto see if it matches:\n$output\n\n" + } + if ![regexp -- $program_output $output] { + set pass no + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } else { + if { $verbose > 1 } { + send_user "Yes, it matches.\n\n" + } + } + } + } else { + if { $verbose > 1 } { + send_user "Nope, does not match.\n\n" + } + } + + if [string match $pass "yes"] { + pass $pass_message + } else { + fail $fail_message + } + + # The framework doesn't like to see any error remnants, + # so remove them. + uplevel { + if [info exists errorInfo] { + unset errorInfo + } + } + + mike_cleanup $src_code $output_file $assembly_file +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/multiline.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/multiline.exp new file mode 100644 index 0000000000000000000000000000000000000000..d31331bd5819e8439008886336dc1b18d30fbeca --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/multiline.exp @@ -0,0 +1,356 @@ +# Copyright (C) 2015-2022 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 +# . + +# Testing of multiline output + +# We have pre-existing testcases like this: +# |typedef struct _GMutex GMutex; // { dg-message "previously declared here"} +# (using "|" here to indicate the start of a line), +# generating output like this: +# |gcc/testsuite/g++.dg/diagnostic/wrong-tag-1.C:4:16: note: 'struct _GMutex' was previously declared here +# where the location of the dg-message determines the expected line at +# which the error should be reported. +# +# To handle rich error-reporting, we want to be able to verify that we +# get output like this: +# |gcc/testsuite/g++.dg/diagnostic/wrong-tag-1.C:4:16: note: 'struct _GMutex' was previously declared here +# | typedef struct _GMutex GMutex; // { dg-message "previously declared here"} +# | ^~~~~~~ +# where the compiler's first line of output is as before, but in +# which it then echoes the source lines, adding annotations. +# +# We want to be able to write testcases that verify that the +# emitted source-and-annotations are sane. +# +# A complication here is that the source lines contain comments +# containing DejaGnu directives (such as the "dg-message" above). +# +# We punt this somewhat by only matching the beginnings of lines. +# so that we can write e.g. +# |/* { dg-begin-multiline-output "" } +# | typedef struct _GMutex GMutex; +# | ^~~~~~~ +# | { dg-end-multiline-output "" } */ +# to have the testsuite verify the expected output. + +############################################################################ +# Global variables. +############################################################################ + +# This is intended to only be used from within multiline.exp. +# The line number of the last dg-begin-multiline-output directive. +set _multiline_last_beginning_line -1 + +# A list of +# first-line-number, last-line-number, lines +# where each "lines" is a list of strings. +# This is cleared at the end of each test by gcc-dg.exp's wrapper for dg-test. +set multiline_expected_outputs [] + +# Was dg-enable-nn-line-numbers called? +set nn_line_numbers_enabled 0 + +############################################################################ +# Exported functions. +############################################################################ + +# Mark the beginning of an expected multiline output +# All lines between this and the next dg-end-multiline-output are +# expected to be seen. + +proc dg-begin-multiline-output { args } { + global _multiline_last_beginning_line + verbose "dg-begin-multiline-output: args: $args" 3 + set line [expr [lindex $args 0] + 1] + + # Complain if there hasn't been a dg-end-multiline-output + # since the last dg-begin-multiline-output + if { $_multiline_last_beginning_line != -1 } { + set last_directive_line [expr $_multiline_last_beginning_line - 1] + error "$last_directive_line: unterminated dg-begin-multiline-output" + } + + set _multiline_last_beginning_line $line +} + +# Mark the end of an expected multiline output +# All lines up to here since the last dg-begin-multiline-output are +# expected to be seen. +# +# dg-end-multiline-output comment [{ target/xfail selector }] + +proc dg-end-multiline-output { args } { + global _multiline_last_beginning_line + verbose "dg-end-multiline-output: args: $args" 3 + set first_line $_multiline_last_beginning_line + + # Complain if there hasn't been a dg-begin-multiline-output + if { $first_line == -1 } { + error "[lindex $args 0]: dg-end-multiline-output without dg-begin-multiline-output" + return + } + set _multiline_last_beginning_line -1 + + set last_line [expr [lindex $args 0] - 1] + verbose "multiline output lines: $first_line-$last_line" 3 + + if { [llength $args] > 3 } { + error "[lindex $args 0]: too many arguments" + return + } + + set maybe_x "" + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "F" { set maybe_x "x" } + "P" { set maybe_x "" } + "N" { + # If we get "N", this output doesn't apply to us so ignore it. + return + } + } + } + + upvar 1 prog prog + verbose "prog: $prog" 3 + # "prog" now contains the filename + # Load it and split it into lines + + set lines [_get_lines $prog $first_line $last_line] + + verbose "lines: $lines" 3 + # Create an entry of the form: first-line, last-line, lines, maybe_x + set entry [list $first_line $last_line $lines $maybe_x] + global multiline_expected_outputs + lappend multiline_expected_outputs $entry + verbose "within dg-end-multiline-output: multiline_expected_outputs: $multiline_expected_outputs" 3 +} + +# Hook to be called by prune.exp's prune_gcc_output to +# look for the expected multiline outputs, pruning them, +# reporting PASS for those that are found, and FAIL for +# those that weren't found. +# +# It returns a pruned version of its output. + +proc handle-multiline-outputs { text } { + global multiline_expected_outputs + global testname_with_flags + set index 0 + foreach entry $multiline_expected_outputs { + verbose " entry: $entry" 3 + set start_line [lindex $entry 0] + set end_line [lindex $entry 1] + set multiline [lindex $entry 2] + set maybe_x [lindex $entry 3] + verbose " multiline: $multiline" 3 + set rexp [_build_multiline_regex $multiline $index] + verbose "rexp: ${rexp}" 4 + # Escape newlines in $rexp so that we can print them in + # pass/fail results. + set escaped_regex [string map {"\n" "\\n"} $rexp] + verbose "escaped_regex: ${escaped_regex}" 4 + + set title "$testname_with_flags expected multiline pattern lines $start_line-$end_line" + + # Use "regsub" to attempt to prune the pattern from $text + if {[regsub -line $rexp $text "" text]} { + # The multiline pattern was pruned. + ${maybe_x}pass "$title was found: \"$escaped_regex\"" + } else { + ${maybe_x}fail "$title not found: \"$escaped_regex\"" + } + + set index [expr $index + 1] + } + + return $text +} + +# DejaGnu directive to enable post-processing the line numbers printed in +# the left-hand margin when printing the source code, converting them to +# "NN", e.g from: +# +# 100 | if (flag) +# | ^ +# | | +# | (1) following 'true' branch... +# 101 | { +# 102 | foo (); +# | ^ +# | | +# | (2) ...to here +# +# to: +# +# NN | if (flag) +# | ^ +# | | +# | (1) following 'true' branch... +# NN | { +# NN | foo (); +# | ^ +# | | +# | (2) ...to here +# +# This is useful e.g. when testing how interprocedural paths are printed +# via dg-begin/end-multiline-output, to avoid depending on precise line +# numbers. + +proc dg-enable-nn-line-numbers { args } { + verbose "dg-nn-line-numbers: args: $args" 2 + global nn_line_numbers_enabled + set nn_line_numbers_enabled 1 +} + +# Hook to be called by prune.exp's prune_gcc_output to convert such line +# numbers to "NN" form. +# +# Match substrings of the form: +# " 25 |" +# and convert them to: +# " NN |" +# +# It returns a copy of its input, with the above changes. + +proc maybe-handle-nn-line-numbers { text } { + global testname_with_flags + + verbose "maybe-handle-nn-line-numbers" 3 + + global nn_line_numbers_enabled + if { [expr {!$nn_line_numbers_enabled}] } { + verbose "nn_line_numbers_enabled false; bailing out" 3 + return $text + } + + verbose "maybe-handle-nn-line-numbers: text before: ${text}" 4 + + # dg.exp's dg-test trims leading whitespace from the output + # in this line: + # set comp_output [string trimleft $comp_output] + # so we can't rely on the exact leading whitespace for the + # first line in the output. + # Match initial input lines that start like: + # "25 |" + # and convert them to: + # " NN |" + set rexp2 {(^[0-9]+ \|)} + set count_a [regsub -all $rexp2 $text " NN |" text] + verbose "maybe-handle-nn-line-numbers: count_a: $count_a" 4 + + # Match lines that start like: + # " 25 |" + # and convert them to: + # " NN |" + set rexp {([ ]+[0-9]+ \|)} + set count_b [regsub -all $rexp $text " NN |" text] + verbose "maybe-handle-nn-line-numbers: count_b: $count_b" 4 + + verbose "maybe-handle-nn-line-numbers: text after: ${text}" 4 + + return $text +} + +############################################################################ +# Internal functions +############################################################################ + +# Load FILENAME and extract the lines from FIRST_LINE +# to LAST_LINE (inclusive) as a list of strings. + +proc _get_lines { filename first_line last_line } { + verbose "_get_lines" 3 + verbose " filename: $filename" 3 + verbose " first_line: $first_line" 3 + verbose " last_line: $last_line" 3 + + set fp [open $filename r] + set file_data [read $fp] + close $fp + set data [split $file_data "\n"] + set linenum 1 + set lines [] + foreach line $data { + verbose "line $linenum: $line" 4 + if { $linenum >= $first_line && $linenum <= $last_line } { + lappend lines $line + } + set linenum [expr $linenum + 1] + } + + return $lines +} + +# Convert $multiline from a list of strings to a multiline regex +# We need to support matching arbitrary followup text on each line, +# to deal with comments containing containing DejaGnu directives. + +proc _build_multiline_regex { multiline index } { + verbose "_build_multiline_regex: $multiline $index" 4 + + set rexp "" + foreach line $multiline { + verbose " line: $line" 4 + + # We need to escape "^" and other regexp metacharacters. + set line [string map {"^" "\\^" + "(" "\\(" + ")" "\\)" + "[" "\\[" + "]" "\\]" + "{" "\\{" + "}" "\\}" + "." "\\." + "\\" "\\\\" + "?" "\\?" + "+" "\\+" + "*" "\\*" + "|" "\\|"} $line] + + append rexp $line + if {[string match "*^" $line] || [string match "*~" $line]} { + # Assume a line containing a caret/range. This must be + # an exact match. + } else { + # Assume that we have a quoted source line. + if {![string equal "" $line] } { + # Support arbitrary followup text on each non-empty line, + # to deal with comments containing containing DejaGnu + # directives. + append rexp "\[^\\n\\r\]*" + } + } + append rexp "\n" + } + + # dg.exp's dg-test trims leading whitespace from the output + # in this line: + # set comp_output [string trimleft $comp_output] + # so we can't rely on the exact leading whitespace for the + # first line in the *first* multiline regex. + # + # Trim leading whitespace from the regexp, replacing it with + # a "\s*", to match zero or more whitespace characters. + if { $index == 0 } { + set rexp [string trimleft $rexp] + set rexp "\\s*$rexp" + } + + verbose "rexp: $rexp" 4 + + return $rexp +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/obj-c++-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/obj-c++-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..7ea54ed191400d0a0fe3b72bdee00521666198ce --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/obj-c++-dg.exp @@ -0,0 +1,73 @@ +# Copyright (C) 2004-2022 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 +# . + +# Define obj-c++ callbacks for dg.exp. + +load_lib gcc-dg.exp + +proc obj-c++-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 obj-c++_target_compile $prog $do_what $extra_tool_flags] +} + + +proc obj-c++-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc obj-c++-dg-runtest { testcases flags default-extra-flags } { + global runtests + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS LTO_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS [list {}] $LTO_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + global torture_with_loops torture_without_loops + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + # combine flags so that dg-skip & xfail will see the extras. + set combined_flags "$flags $flags_t ${default-extra-flags}" + verbose "Testing $nshort, $combined_flags" 1 + dg-test $test $combined_flags "" + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} \ No newline at end of file diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/obj-c++.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/obj-c++.exp new file mode 100644 index 0000000000000000000000000000000000000000..fe941587841b0606e37581a6646d2868fe76e69b --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/obj-c++.exp @@ -0,0 +1,410 @@ +# Copyright (C) 2004-2022 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Many modifications by Jeffrey Wheat (cassidy@cygnus.com) +# With modifications by Mike Stump . + +# +# obj-c++ support library routines +# +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp + +# +# OBJCXX_UNDER_TEST is the compiler under test. +# + + +set gpp_compile_options "" + +# +# obj-c++_version -- extract and print the version number of the compiler +# + +proc obj-c++_version { } { + global OBJCXX_UNDER_TEST + + obj-c++_init + + # Ignore any arguments after the command. + set compiler [lindex $OBJCXX_UNDER_TEST 0] + + # Verify that the compiler exists. + if { [is_remote host] || [which $compiler] != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0]; + set output [lindex $tmp 1]; + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + if [is_remote host] { + clone_output "$compiler $version\n" + } else { + clone_output "[which $compiler] $version\n" + } + } else { + clone_output "Couldn't determine version of [which $compiler]\n" + } + } else { + # Compiler does not exist (this should have already been detected) + warning "$compiler does not exist" + } +} + +# +# obj-c++_include_flags -- provide new version of obj-c++_include_flags +# (originally from libgloss.exp) which knows about the gcc tree structure +# +proc obj-c++_include_flags { paths } { + global srcdir + global HAVE_LIBSTDCXX_V3 + global TESTING_IN_BUILD_TREE + + set flags "" + + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + return "${flags}" + } + + set gccpath ${paths} + + set odir [lookfor_file ${gccpath} libstdc++-v3] + if { ${odir} != "" } { + append flags [exec sh ${odir}/scripts/testsuite_flags --build-includes] + } + + return "$flags" +} + +# +# obj-c++_link_flags -- provide new version of obj-c++_link_flags +# (originally from libgloss.exp) which knows about the gcc tree structure. +# + +proc obj-c++_link_flags { paths } { + global rootme + global srcdir + global ld_library_path + global OBJCXX_UNDER_TEST + global shlib_ext + + set gccpath ${paths} + set libio_dir "" + set flags "" + set ld_library_path "." + set shlib_ext [get_shlib_extension] + verbose "shared lib extension: $shlib_ext" + + if { $gccpath != "" } { + if [file exists "${gccpath}/lib/libstdc++.a"] { + append ld_library_path ":${gccpath}/lib" + } + if [file exists "${gccpath}/libg++/libg++.a"] { + append flags " -L${gccpath}/libg++ " + append ld_library_path ":${gccpath}/libg++" + } + if [file exists "${gccpath}/libstdc++/libstdc++.a"] { + append flags " -L${gccpath}/libstdc++ " + append ld_library_path ":${gccpath}/libstdc++" + } + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] { + # Allow for %s spec substitutions + append flags " -B${gccpath}/libstdc++-v3/src/.libs " + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + # Look for libstdc++.${shlib_ext}. + if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] { + # Allow for %s spec substitutions + append flags " -B${gccpath}/libstdc++-v3/src/.libs " + append flags " -L${gccpath}/libstdc++-v3/src/.libs " + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + if [file exists "${gccpath}/libiberty/libiberty.a"] { + append flags " -L${gccpath}/libiberty " + } + if [file exists "${gccpath}/librx/librx.a"] { + append flags " -L${gccpath}/librx " + } + + set objcpath "[get_multilibs]" + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.a] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.a] + } + # Now check if we have a shared only build. + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.${shlib_ext}] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.${shlib_ext}] + } + } + + verbose "libobjc_dir: $libobjc_dir" + + if { $libobjc_dir != "" } { + set libobjc_dir [file dirname ${libobjc_dir}] + # Allow for %s spec substitutions + append flags " -B${libobjc_dir} " + append flags " -L${libobjc_dir} " + append ld_library_path ":${libobjc_dir}" + } + append ld_library_path \ + [gcc-set-multilib-library-path $OBJCXX_UNDER_TEST] + } else { + global tool_root_dir; + + set libgpp [lookfor_file ${tool_root_dir} libg++]; + if { $libgpp != "" } { + append flags "-L${libgpp} "; + append ld_library_path ":${libgpp}" + } + set libstdcpp [lookfor_file ${tool_root_dir} libstdc++]; + if { $libstdcpp != "" } { + append flags "-L${libstdcpp} "; + append ld_library_path ":${libstdcpp}" + } + set libiberty [lookfor_file ${tool_root_dir} libiberty]; + if { $libiberty != "" } { + append flags "-L${libiberty} "; + } + set librx [lookfor_file ${tool_root_dir} librx]; + if { $librx != "" } { + append flags "-L${librx} "; + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# obj-c++_init -- called at the start of each subdir of tests +# + +proc obj-c++_init { args } { + global subdir + global gpp_initialized + global base_dir + global tmpdir + global libdir + global gluefile wrap_flags; + global objdir srcdir + global ALWAYS_OBJCXXFLAGS + global TOOL_EXECUTABLE TOOL_OPTIONS + global OBJCXX_UNDER_TEST + global TESTING_IN_BUILD_TREE + global gcc_warning_prefix + global gcc_error_prefix + global TEST_ALWAYS_FLAGS + + if ![info exists OBJCXX_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set OBJCXX_UNDER_TEST $TOOL_EXECUTABLE; + } else { + if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { + set OBJCXX_UNDER_TEST [transform c++] + } else { + set OBJCXX_UNDER_TEST [findfile $base_dir/../../xg++ "$base_dir/../../xg++ -B$base_dir/../../" [findfile $base_dir/xg++ "$base_dir/xg++ -B$base_dir/" [transform c++]]] + } + } + } + + # Bleah, nasty. Bad taste. + if [ishost "*-dos-*" ] { + regsub "c\\+\\+" "$OBJCXX_UNDER_TEST" "gcc" OBJCXX_UNDER_TEST + } + + if ![is_remote host] { + if { [which $OBJCXX_UNDER_TEST] == 0 } then { + perror "OBJCXX_UNDER_TEST ($OBJCXX_UNDER_TEST) does not exist" + exit 1 + } + } + if ![info exists tmpdir] { + set tmpdir "/tmp" + } + + if [info exists gluefile] { + unset gluefile + } + + obj-c++_maybe_build_wrapper "${tmpdir}/obj-c++-testglue.o" "-fexceptions" + + set ALWAYS_OBJCXXFLAGS "" + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=$TEST_ALWAYS_FLAGS" + } + + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=[obj-c++_include_flags [get_multilibs ${TOOL_OPTIONS}] ]"; + lappend ALWAYS_OBJCXXFLAGS "ldflags=[obj-c++_link_flags [get_multilibs ${TOOL_OPTIONS}] ]"; + } else { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=[obj-c++_include_flags [get_multilibs] ]"; + lappend ALWAYS_OBJCXXFLAGS "ldflags=[obj-c++_link_flags [get_multilibs] ]"; + } + } + + if [info exists TOOL_OPTIONS] { + lappend ALWAYS_OBJCXXFLAGS "additional_flags=$TOOL_OPTIONS"; + } + + # Make sure that lines are not wrapped. That can confuse the + # error-message parsing machinery. + lappend ALWAYS_OBJCXXFLAGS "additional_flags=-fmessage-length=0" + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + if { [istarget *-*-darwin*] } { + lappend ALWAYS_OBJCXXFLAGS "ldflags=-multiply_defined suppress" + } + + verbose -log "ALWAYS_OBJCXXFLAGS set to $ALWAYS_OBJCXXFLAGS" + + verbose "obj-c++ is initialized" 3 +} + +# +# obj-c++_target_compile -- compile a source file +# + +proc obj-c++_target_compile { source dest type options } { + global tmpdir + global srcdir + global gpp_compile_options + global gluefile wrap_flags + global ALWAYS_OBJCXXFLAGS + global OBJCXX_UNDER_TEST + global shlib_ext + + set shlib_ext [get_shlib_extension] + verbose "input-options: $options" 4 + + # We have to figure out which runtime will be used on darwin because + # we need to add the include path for the gnu runtime if that is in + # use. + # First, set the default... + if { [istarget *-*-darwin*] } { + set nextruntime 1 + } else { + set nextruntime 0 + } + verbose "initial next runtime state : $nextruntime" 2 + # Next, see if we define the option in dg-options... + foreach opt $options { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + verbose "next runtime state after dg opts: $nextruntime" 2 + + set tgt [target_info name] + if [board_info $tgt exists multilib_flags] { + set lb [board_info $tgt multilib_flags] + verbose "board multilib_flags $lb" 2 + foreach opt $lb { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + } + verbose "next runtime state after any multilib opts: $nextruntime" 2 + + lappend options "libs=-lobjc" + + if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=${wrap_flags}" + } + + # If we have built libobjc along with the compiler, point the test harness + # at it (and associated headers). + + set objcpath "[get_multilibs]" + + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.a] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.a] + } + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.${shlib_ext}] + if { $libobjc_dir == ""} { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.${shlib_ext}] + } + } + + if { $libobjc_dir != "" } { + # If we are using the gnu runtime, add its includes. + if { $nextruntime == 0 } { + set objc_include_dir "${srcdir}/../../libobjc" + lappend options "additional_flags=-I${objc_include_dir}" + } + } + + lappend options "additional_flags=[libio_include_flags]" + lappend options "compiler=$OBJCXX_UNDER_TEST"; + lappend options "timeout=[timeout_value]" + + set options [concat $gpp_compile_options $options] + + set options [concat "$ALWAYS_OBJCXXFLAGS" $options]; + + set options [dg-additional-files-options $options $source] + + set result [target_compile $source $dest $type $options] + + return $result +} + +# +# ${tool}_option_help +# + +proc ${tool}_option_help { } { + send_user " --additional_options,OPTIONS\t\tUse OPTIONS to compile the testcase files. OPTIONS should be comma-separated.\n" +} + +# +# ${tool}_option_proc +# + +proc ${tool}_option_proc { option } { + if [regexp "^--additional_options," $option] { + global gpp_compile_options + regsub "--additional_options," $option "" option + foreach x [split $option ","] { + lappend gpp_compile_options "additional_flags=$x" + } + return 1; + } else { + return 0 + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..64a26309f988cafa3353b70f3f326a08fa5fcc03 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc-dg.exp @@ -0,0 +1,74 @@ +# Copyright (C) 1997-2022 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 +# . + +load_lib gcc-dg.exp + +# Define gcc callbacks for dg.exp. + +proc objc-dg-test { prog do_what extra_tool_flags } { + return [gcc-dg-test-1 objc_target_compile $prog $do_what $extra_tool_flags] +} + +proc objc-dg-prune { system text } { + return [gcc-dg-prune $system $text] +} + +# Utility routines. + +# Modified dg-runtest that can cycle through a list of optimization options +# as c-torture does. +proc objc-dg-runtest { testcases flags default-extra-flags } { + global runtests + + # Some callers set torture options themselves; don't override those. + set existing_torture_options [torture-options-exist] + if { $existing_torture_options == 0 } { + global DG_TORTURE_OPTIONS LTO_TORTURE_OPTIONS + torture-init + set-torture-options $DG_TORTURE_OPTIONS [list {}] $LTO_TORTURE_OPTIONS + } + dump-torture-options + + foreach test $testcases { + global torture_with_loops torture_without_loops + # If we're only testing specific files and this isn't one of + # them, skip it. + if ![runtest_file_p $runtests $test] { + continue + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + if [expr [search_for $test "for*("]+[search_for $test "while*("]] { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set nshort [file tail [file dirname $test]]/[file tail $test] + + foreach flags_t $option_list { + # combine flags so that dg-skip & xfail will see the extras. + set combined_flags "$flags $flags_t ${default-extra-flags}" + verbose "Testing $nshort, $combined_flags" 1 + dg-test $test $combined_flags "" + } + } + + if { $existing_torture_options == 0 } { + torture-finish + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc-torture.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc-torture.exp new file mode 100644 index 0000000000000000000000000000000000000000..a0c01189a1bec20196a4d3c6f3e2684ae45903e8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc-torture.exp @@ -0,0 +1,390 @@ +# Copyright (C) 1992-2022 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 +# . + +# This file was written by Rob Savoye. (rob@cygnus.com) + +load_lib file-format.exp +load_lib target-supports.exp + +# Make sure that the runtime list is re-evaluated for each multilib. +proc objc-set-runtime-options { dowhat args } { + global OBJC_RUNTIME_OPTIONS + set rtlist [list "-fgnu-runtime" ] + # At present (4.6), the only NeXT runtime target is Darwin. + # The previously used approach of testing trivial compiles is not reliable + # for determining the absence of the NeXT runtime, since a non-Darwin + # installation can have the objc headers present in the same locations + # that Darwin uses. If NeXT is ported to another target, then it should + # be listed here. + if [istarget *-*-darwin*] { + lappend rtlist "-fnext-runtime" + } + if [info exists OBJC_RUNTIME_OPTIONS] { + foreach other $OBJC_RUNTIME_OPTIONS { + # Don't do tests twice... + if { ( $other == "-fnext-runtime" || $other == "-fgnu-runtime" ) } { + continue + } + lappend rtlist $other + } + } + + set OBJC_RUNTIME_OPTIONS "" + + foreach type $rtlist { + global srcdir subdir target_triplet tmpdir + + set options "additional_flags=$type" + if [info exists args] { + lappend options $args + } + verbose "options $options" + if [info exists dowhat] { + switch $dowhat { + "compile" { + # We should check that the generated asm is sensible, so do + # the equivalent of -c. + set compile_type "object" + set output_file "trivial.o" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" "$output_file" "$compile_type" $options] + + remote_file build delete $output_file + # If we get any error, then we failed. + if ![string match "" $comp_output] then { + continue; + } + } + "execute" { + set test_obj "trivial.exe" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" $test_obj "executable" $options] + + # If we get any error, then we failed. + if ![string match "" $comp_output] then { + remote_file build delete $test_obj + continue; + } + set result [objc_load "$tmpdir/$test_obj" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $test_obj + if { $status != "pass" } { + verbose -log "trivial execute failed with $status $output" + continue; + } + } + default { + perror "$dowhat: not a valid objc-torture action" + return "" + } + } + } else { + set test_obj "trivial.exe" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" $test_obj executable $options] + + # If we get any error, then we failed. + remote_file build delete $test_obj + if ![string match "" $comp_output] then { + continue; + } + } + lappend OBJC_RUNTIME_OPTIONS $type + } + + verbose -log "Using the following runtimes: $OBJC_RUNTIME_OPTIONS" +} + +# The default option list can be overridden by +# TORTURE_OPTIONS="{ { list1 } ... { listN } }" + +if [info exists TORTURE_OPTIONS] { + set OBJC_TORTURE_OPTIONS $TORTURE_OPTIONS +} else { + # It is theoretically beneficial to group all of the O2/O3 options together, + # as in many cases the compiler will generate identical executables for + # all of them--and the objc-torture testsuite will skip testing identical + # executables multiple times. + # Also note that -finline-functions is explicitly included in one of the + # items below, even though -O3 is also specified, because some ports may + # choose to disable inlining functions by default, even when optimizing. + set OBJC_TORTURE_OPTIONS [list \ + " -O0 " \ + " -O1 " \ + " -O2 " \ + " -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions " \ + " -O3 -g " \ + " -Os " ] +} + +if [info exists ADDITIONAL_TORTURE_OPTIONS] { + set OBJC_TORTURE_OPTIONS \ + [concat $OBJC_TORTURE_OPTIONS $ADDITIONAL_TORTURE_OPTIONS] +} + +# +# objc-torture-compile -- runs the Tege OBJC-torture test +# +# SRC is the full pathname of the testcase. +# OPTION is the specific compiler flag we're testing (eg: -O2). +# +proc objc-torture-compile { src option } { + global output + global srcdir tmpdir + global host_triplet + + set output "$tmpdir/[file tail [file rootname $src]].o" + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + verbose "Testing $testcase, $option" 1 + + # Run the compiler and analyze the results. + set options "" + lappend options "additional_flags=-w $option" + + set comp_output [objc_target_compile "$src" "$output" object $options] + objc_check_compile $testcase $option $output $comp_output + remote_file build delete $output +} + +# +# objc-torture-execute -- utility to compile and execute a testcase +# +# SRC is the full pathname of the testcase. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc objc-torture-execute { src args } { + global tmpdir tool srcdir output compiler_conditional_xfail_data + + if { [llength $args] > 0 } { + set additional_flags [lindex $args 0] + } else { + set additional_flags "" + } + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + set executable $tmpdir/[file tail [file rootname $src].x] + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + set count 0 + set oldstatus "foo" + foreach option $option_list { + if { $count > 0 } { + if [info exists oldexec] { + remote_file build delete $oldexec + } + set oldexec $execname + } + set execname "${executable}${count}" + incr count + + # torture_{compile,execute}_xfail are set by the .x script + # (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_{compile,execute} can be set by the .x script + # (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + remote_file build delete $execname + verbose "Testing $testcase, $option" 1 + + set options "" + lappend options "additional_flags=-w $option" + if { $additional_flags != "" } { + lappend options "additional_flags=$additional_flags" + } + set comp_output [objc_target_compile "$src" "${execname}" executable $options] + + if ![objc_check_compile "$testcase compilation" $option $execname $comp_output] { + unresolved "$testcase execution, $option" + remote_file build delete $execname + continue + } + + # See if this source file uses "long long" types, if it does, and + # no_long_long is set, skip execution of the test. + if [target_info exists no_long_long] then { + if [expr [search_for $src "long long"]] then { + unsupported "$testcase execution, $option" + remote_file build delete $execname + continue + } + } + + if [info exists torture_execute_xfail] { + setup_xfail $torture_execute_xfail + } + + if [info exists torture_eval_before_execute] { + set ignore_me [eval $torture_eval_before_execute] + } + + + # Sometimes we end up creating identical executables for two + # consecutive sets of different of compiler options. + # + # In such cases we know the result of this test will be identical + # to the result of the last test. + # + # So in cases where the time to load and run/simulate the test + # is relatively high, compare the two binaries and avoid rerunning + # tests if the executables are identical. + # + # Do not do this for native testing since the cost to load/execute + # the test is fairly small and the comparison step actually slows + # the entire process down because it usually does not "hit". + set skip 0 + if { ![isnative] && [info exists oldexec] } { + if { [remote_file build cmp $oldexec $execname] == 0 } { + set skip 1 + set status $oldstatus + } + } + if { $skip == 0 } { + set result [objc_load "$execname" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + } + $status "$testcase execution, $option" + set oldstatus $status + # for each option + } + # tidy up + if [info exists execname] { + remote_file build delete $execname + } + if [info exists oldexec] { + remote_file build delete $oldexec + } +} + +# +# search_for -- looks for a string match in a file +# +proc search_for { file pattern } { + set fd [open $file r] + while { [gets $fd cur_line]>=0 } { + if [string match "*$pattern*" $cur_line] then { + close $fd + return 1 + } + } + close $fd + return 0 +} + +# +# objc-torture -- the objc-torture testcase source file processor +# +# This runs compilation only tests (no execute tests). +# SRC is the full pathname of the testcase, or just a file name in which case +# we prepend $srcdir/$subdir. +# +# If the testcase has an associated .x file, we source that to run the +# test instead. We use .x so that we don't lengthen the existing filename +# to more than 14 chars. +# +proc objc-torture { args } { + global srcdir subdir compiler_conditional_xfail_data + + set src [lindex $args 0] + if { [llength $args] > 1 } { + set options [lindex $args 1] + } else { + set options "" + } + + # Prepend $srdir/$subdir if missing. + if ![string match "*/*" $src] { + set src "$srcdir/$subdir/$src" + } + + # Check for alternate driver. + if [file exists [file rootname $src].x] { + verbose "Using alternate driver [file rootname [file tail $src]].x" 2 + set done_p 0 + catch "set done_p \[source [file rootname $src].x\]" + if { $done_p } { + return + } + } + + # Look for a loop within the source code - if we don't find one, + # don't pass -funroll[-all]-loops. + global torture_with_loops torture_without_loops + if [expr [search_for $src "for*("]+[search_for $src "while*("]] then { + set option_list $torture_with_loops + } else { + set option_list $torture_without_loops + } + + # loop through all the options + foreach option $option_list { + # torture_compile_xfail is set by the .x script (if present) + if [info exists torture_compile_xfail] { + setup_xfail $torture_compile_xfail + } + + # torture_execute_before_compile is set by the .x script (if present) + if [info exists torture_eval_before_compile] { + set ignore_me [eval $torture_eval_before_compile] + } + + objc-torture-compile $src "$option $options" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc.exp new file mode 100644 index 0000000000000000000000000000000000000000..7ac7134cc14538dd129e46ea222bebc4bf93dfca --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/objc.exp @@ -0,0 +1,356 @@ +# Copyright (C) 1992-2022 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 +# . + +# This file was written by Rob Savoye (rob@cygnus.com) +# Currently maintained by Doug Evans (dje@cygnus.com) + +# This file is loaded by the tool init file (eg: unix.exp). It provides +# default definitions for objc_start, etc. and other supporting cast members. + +# These globals are used by objc_start if no compiler arguments are provided. +# They are also used by the various testsuites to define the environment: +# where to find stdio.h, libc.a, etc. + +load_lib libgloss.exp +load_lib prune.exp +load_lib gcc-defs.exp +load_lib timeout.exp +load_lib target-libpath.exp +load_lib target-utils.exp + +# +# OBJC_UNDER_TEST is the compiler under test. +# + +# +# default_objc_version -- extract and print the version number of the compiler +# + +proc default_objc_version { } { + global OBJC_UNDER_TEST + + objc_init + + # Ignore any arguments after the command. + set compiler [lindex $OBJC_UNDER_TEST 0] + + if ![is_remote host] { + set compiler_name [which $compiler] + } else { + set compiler_name $compiler + } + + # Verify that the compiler exists. + if { $compiler_name != 0 } then { + set tmp [remote_exec host "$compiler -v"] + set status [lindex $tmp 0] + set output [lindex $tmp 1] + regexp " version \[^\n\r\]*" $output version + if { $status == 0 && [info exists version] } then { + clone_output "$compiler_name $version\n" + } else { + clone_output "Couldn't determine version of $compiler_name: $output\n" + } + } else { + # Compiler does not exist (this should have already been detected). + warning "$compiler does not exist" + } +} + +# +# Call objc_version. We do it this way so we can override it if needed. +# +proc objc_version { } { + default_objc_version +} + +# +# objc_init -- called at the start of each .exp script. +# +# There currently isn't much to do, but always using it allows us to +# make some enhancements without having to go back and rewrite the scripts. +# + +set objc_initialized 0 + +proc objc_init { args } { + global rootme + global tmpdir + global libdir + global gluefile wrap_flags + global objc_initialized + global OBJC_UNDER_TEST + global TOOL_EXECUTABLE + global objc_libgcc_s_path + global gcc_warning_prefix + global gcc_error_prefix + + # We set LC_ALL and LANG to C so that we get the same error messages as + # expected. + setenv LC_ALL C + setenv LANG C + + # Many hosts now default to a non-ASCII C locale, however, so + # they can set a charset encoding here if they need. + if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII + } + + if { $objc_initialized == 1 } { return; } + + if ![info exists OBJC_UNDER_TEST] then { + if [info exists TOOL_EXECUTABLE] { + set OBJC_UNDER_TEST $TOOL_EXECUTABLE + } else { + set OBJC_UNDER_TEST [find_gcc] + } + } + + if ![info exists tmpdir] then { + set tmpdir /tmp + } + + set gcc_warning_prefix "warning:" + set gcc_error_prefix "(fatal )?error:" + + objc_maybe_build_wrapper "${tmpdir}/objc-testglue.o" + + set objc_libgcc_s_path [gcc-set-multilib-library-path $OBJC_UNDER_TEST] +} + +proc objc_target_compile { source dest type options } { + global rootme + global tmpdir + global gluefile wrap_flags + global srcdir + global OBJC_UNDER_TEST + global TOOL_OPTIONS + global ld_library_path + global objc_libgcc_s_path + global shlib_ext + global TEST_ALWAYS_FLAGS + + set shlib_ext [get_shlib_extension] + set ld_library_path ".:${objc_libgcc_s_path}" + + # We have to figure out which runtime will be used on darwin because + # we need to add the include path for the gnu runtime if that is in + # use. + # First set the default... + if { [istarget *-*-darwin*] } { + set nextruntime 1 + } else { + set nextruntime 0 + } + verbose "initial next runtime state : $nextruntime" 2 + # Next, see if we define the option in dg-options... + foreach opt $options { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + verbose "next runtime state after dg opts: $nextruntime" 2 + + set tgt [target_info name] + if [board_info $tgt exists multilib_flags] { + set lb [board_info $tgt multilib_flags] + verbose "board multilib_flags $lb" 2 + foreach opt $lb { + if [regexp ".*-fnext-runtime.*" $opt] { + set nextruntime 1 + } + if [regexp ".*-fgnu-runtime.*" $opt] { + set nextruntime 0 + } + } + } + verbose "next runtime state after any multilib opts: $nextruntime" 2 + + lappend options "libs=-lobjc" + verbose "shared lib extension: $shlib_ext" 3 + + if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } { + lappend options "libs=${gluefile}" + lappend options "ldflags=$wrap_flags" + } + + # TEST_ALWAYS_FLAGS are flags that should be passed to every + # compilation. They are passed first to allow individual + # tests to override them. + if [info exists TEST_ALWAYS_FLAGS] { + set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options] + } + + # TOOL_OPTIONS must come first, so that it doesn't override testcase + # specific options. + if [info exists TOOL_OPTIONS] { + set options [concat "{additional_flags=$TOOL_OPTIONS}" $options] + } + + # If we have built libobjc along with the compiler, point the test harness + # at it (and associated headers). + + set objcpath "[get_multilibs]" + + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.a] + if { $libobjc_dir == "" } { + # On darwin there is, potentially, a gnu runtime too. + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.a] + } + # Perhaps we didn't build static libs. + if { $libobjc_dir == "" } { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.${shlib_ext}] + # On darwin there is, potentially, a gnu runtime too. + if { $libobjc_dir == "" } { + set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc-gnu.${shlib_ext}] + } + } + + if { $libobjc_dir != "" } { + # If we are using the gnu runtime, add its includes. + if { $nextruntime == 0 } { + set objc_include_dir "${srcdir}/../../libobjc" + lappend options "additional_flags=-I${objc_include_dir}" + verbose "adding gnu runtime include dir: $objc_include_dir " + } + set libobjc_dir [file dirname ${libobjc_dir}] + # Allow for %s spec substitutions.. + set objc_link_flags " -B${libobjc_dir} " + lappend options "additional_flags=${objc_link_flags}" + set objc_link_flags " -L${libobjc_dir} " + lappend options "additional_flags=${objc_link_flags}" + append ld_library_path ":${libobjc_dir}" + } + if { $type == "precompiled_header" } { + # If we generating a precompiled header, we have say this is an + # objective-C header. + set source [concat "-x objective-c-header" $source] + } + lappend options "compiler=$OBJC_UNDER_TEST" + lappend options "timeout=[timeout_value]" + + set_ld_library_path_env_vars + + set options [dg-additional-files-options $options $source] + + return [target_compile $source $dest $type $options] +} + +# +# objc_pass -- utility to record a testcase passed. +# + +proc objc_pass { testcase cflags } { + if { "$cflags" == "" } { + pass "$testcase" + } else { + pass "$testcase, $cflags" + } +} + +# +# objc_fail -- utility to record a testcase failed +# + +proc objc_fail { testcase cflags } { + if { "$cflags" == "" } { + fail "$testcase" + } else { + fail "$testcase, $cflags" + } +} + +# +# objc_finish -- called at the end of every .exp script that calls objc_init +# +# The purpose of this proc is to hide all quirks of the testing environment +# from the testsuites. It also exists to undo anything that objc_init did +# (that needs undoing). +# + +proc objc_finish { } { + # The testing harness apparently requires this. + global errorInfo + + if [info exists errorInfo] then { + unset errorInfo + } + + # Might as well reset these (keeps our caller from wondering whether + # s/he has to or not). + global prms_id bug_id + set prms_id 0 + set bug_id 0 +} + +proc objc_exit { } { + global gluefile + + if [info exists gluefile] { + file_on_build delete $gluefile + unset gluefile + } +} + +# If this is an older version of dejagnu (without runtest_file_p), +# provide one and assume the old syntax: foo1.exp bar1.c foo2.exp bar2.c. +# This can be deleted after next dejagnu release. + +if { [info procs runtest_file_p] == "" } then { + proc runtest_file_p { runtests testcase } { + if { $runtests != "" && [regexp "\[.\]\[cC\]" $runtests] } then { + if { [lsearch $runtests [file tail $testcase]] >= 0 } then { + return 1 + } else { + return 0 + } + } + return 1 + } +} + +# Provide a definition of this if missing (delete after next dejagnu release). + +if { [info procs prune_warnings] == "" } then { + proc prune_warnings { text } { + return $text + } +} + +# Prune messages from objc that aren't useful. + +proc prune_objc_output { text } { + #send_user "Before:$text\n" + regsub -all "(^|\n)\[^\n\]*: In (function|method) \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: At top level:\[^\n\]*" $text "" text + + # It would be nice to avoid passing anything to objc that would cause it to + # issue these messages (since ignoring them seems like a hack on our part), + # but that's too difficult in the general case. For example, sometimes + # you need to use -B to point objc at crt0.o, but there are some targets + # that don't have crt0.o. + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text + + #send_user "After:$text\n" + + return $text +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/options.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/options.exp new file mode 100644 index 0000000000000000000000000000000000000000..33c3cfb4d1764be29b62ea3675df81e3c4ef2dad --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/options.exp @@ -0,0 +1,121 @@ +# Copyright (C) 2009-2022 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 +# . + +# We set LC_ALL and LANG to C so that we get the same error messages as expected. +setenv LC_ALL C +setenv LANG C + +# Many hosts now default to a non-ASCII C locale, however, so +# they can set a charset encoding here if they need. +if { [ishost "*-*-cygwin*"] } { + setenv LC_ALL C.ASCII + setenv LANG C.ASCII +} + +# Run the LANGUAGE compiler with GCC_OPTIONS and inspect the compiler +# output excluding EXCLUDE lines to make sure that they match the +# newline-separated patterns in COMPILER_PATTERNS but not the patterns in +# COMPILER_NON_PATTERNS. In case of failure, xfail if XFAIL is nonempty. + +proc check_for_options_with_filter { language gcc_options exclude \ + compiler_patterns \ + compiler_non_patterns \ + expected_failure } { + set test "compiler driver $gcc_options option(s):" + set gcc_options "\{additional_flags=$gcc_options\}" + + switch "$language" { + "c" { + set compiler cc1 + set suffix c + } + "c++" { + set compiler cc1plus + set suffix cc + } + default { error "unknown language" } + } + + set filebase test-[pid] + set srcfname $filebase.$suffix + set fd [open $srcfname w] + puts $fd "int main (void) { return 0; }" + close $fd + remote_download host $srcfname + + set gcc_output [gcc_target_compile $srcfname $filebase.x executable $gcc_options] + remote_file build delete $srcfname $filebase.x $filebase.gcno + + if {[regexp -- "compiler not installed on this system" $gcc_output]} { + unsupported "$test: $language compiler not available" + return + } + + if { $exclude != "" } { + set lines [split $gcc_output "\n"] + set gcc_output "" + foreach line $lines { + if {[regexp -line -- "$exclude" $line]} { + continue + } + if { $gcc_output == "" } { + set gcc_output "$line" + } else { + set gcc_output "$gcc_output\n$line" + } + } + } + + # Verify that COMPILER_PATTERNS appear in gcc output. + foreach pattern [split $compiler_patterns "\n"] { + if {$pattern != ""} { + if {[regexp -line -- "$pattern" $gcc_output]} { + pass "$test $pattern" + } else { + if {$expected_failure != ""} { + xfail "$test \"$pattern\" present in output" + } else { + fail "$test \"$pattern\" present in output" + } + } + } + } + + # Verify that COMPILER_NON_PATTERNS do not appear in gcc output. + foreach pattern [split $compiler_non_patterns "\n"] { + if {$pattern != ""} { + if {![regexp -line -- "$pattern" $gcc_output result]} { + pass "$test $pattern" + } else { + if {$expected_failure != ""} { + xfail "$test \"$pattern\" absent from output" + } else { + # Print the unexpected line that caused the failure + # to make it easier to find in the multiline output. + fail "$test \"$pattern\" absent from output: \"$result\"" + } + } + } + } +} + +# As check_for_options_with_filter, but without the EXCLUDE parameter. + +proc check_for_options { language gcc_options compiler_patterns \ + compiler_non_patterns expected_failure } { + check_for_options_with_filter $language $gcc_options "" $compiler_patterns \ + $compiler_non_patterns $expected_failure +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/plugin-support.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/plugin-support.exp new file mode 100644 index 0000000000000000000000000000000000000000..749aa4dc08d40196ffce7d5ba3d6ae09cbc6227a --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/plugin-support.exp @@ -0,0 +1,132 @@ +# Copyright (C) 2009-2022 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 +# . +# + +# This file contains the support procedures for testing the plugin mechanism. + +load_lib dg.exp +load_lib gcc.exp + +# +# plugin-get-options -- process test directives +# +# SRC is the full pathname of the plugin source file. +# +proc plugin-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "plugin.exp does not support $cmd" + } + } + + # Return flags to use for compiling the plugin source file + return ${dg-extra-tool-flags} +} + +# +# plugin-test-execute -- build the plugin first and then compile the +# test files with the plugin. +# +# PLUGIN_SRC is the full pathname of the plugin source file. +# PLUGIN_TESTS is a list of input test source files. +# +proc plugin-test-execute { plugin_src plugin_tests } { + global srcdir objdir + global verbose + global GMPINC + global PLUGINCC + global PLUGINCFLAGS + + set basename [file tail $plugin_src] + set base [file rootname $basename] + set plugin_lib $base.so + + set testcase [dg-trim-dirname $srcdir $plugin_src] + verbose "Test the plugin $testcase" 1 + + # Build the plugin itself + set extra_flags [plugin-get-options $plugin_src] + + # Note that the plugin test support currently only works when the GCC + # build tree is available. (We make sure that is the case in plugin.exp.) + # Once we have figured out how/where to package/install GCC header files + # for general plugin support, we should modify the following include paths + # accordingly. + set gcc_srcdir "$srcdir/../.." + set gcc_objdir "$objdir/../../.." + set includes "-I. -I${srcdir} -I${gcc_srcdir}/gcc -I${gcc_objdir}/gcc \ + -I${gcc_srcdir}/include -I${gcc_srcdir}/libcpp/include \ + $GMPINC -I${gcc_objdir}/intl" + + if { [ ishost *-*-darwin* ] } { + # -mdynamic-no-pic is incompatible with -fPIC. + set plug_cflags "" + foreach op $PLUGINCFLAGS { + if { [string compare "-mdynamic-no-pic" $op] } { + set plug_cflags [concat $plug_cflags " $op"] + } + } + set optstr "$includes" + foreach op $extra_flags { + if { [string compare "-mdynamic-no-pic" $op] } { + set optstr [concat $optstr " $op"] + } + } + set optstr [concat $optstr "-DIN_GCC -fPIC -shared -fno-rtti -undefined dynamic_lookup"] + } else { + set plug_cflags $PLUGINCFLAGS + set optstr "$includes $extra_flags -DIN_GCC -fPIC -shared -fno-rtti" + } + + # Temporarily switch to the environment for the plugin compiler. + restore_ld_library_path_env_vars + set status [remote_exec build "$PLUGINCC $plug_cflags $plugin_src $optstr -o $plugin_lib"] + set status [lindex $status 0] + set_ld_library_path_env_vars + + if { $status != 0 } then { + fail "$testcase compilation" + # Strictly, this is wrong: the tests compiled with the plugin should + # become unresolved instead. + return + } else { + pass "$testcase compilation" + } + + # Compile the input source files with the plugin + global default_flags + set plugin_enabling_flags "-fplugin=./$plugin_lib" + dg-runtest $plugin_tests $plugin_enabling_flags $default_flags + + # Clean up + remote_file build delete $plugin_lib +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/profopt.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/profopt.exp new file mode 100644 index 0000000000000000000000000000000000000000..ac7712a5b4260e55eaa53762ff79e37efff2bb48 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/profopt.exp @@ -0,0 +1,607 @@ +# Copyright (C) 2001-2022 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 +# . +# +# This script was submitted by Janis Johnson . + +# Test the functionality and optionally, performance improvement, of +# programs compiled with profile-directed optimizations. Compile and +# run a test with profile options, compile it with options using the +# profile feedback, and then run the test again. Optionally compile +# and run a third time without the profile-directed optimization and +# compare timing results of the program with normal optimization and +# with the profile-directed optimization. Each test is run using +# multiple sets of optimization and/or code generation options in +# addition to the profiling and feedback options. + +# If perf_ext is defined and the performance value for the +# profile-directed test run is nonzero then the performance check will +# be done. + +load_lib dg.exp +load_lib gcc-dg.exp + +global PROFOPT_OPTIONS perf_delta + +# The including .exp file must define these. +global tool profile_option feedback_option prof_ext profile_wrapper +if ![info exists tool] { + error "Tools is not specified." +} +if ![info exists prof_ext] { + error "No profile data file extensions specified." +} + +# The maximum perforance degradation can be defined in the including file. +if ![info exists perf_delta] { + set perf_delta 4 +} + +# The default option list can be overridden by +# PROFOPT_OPTIONS="{ { list1 } ... { list2 } }" + +if ![info exists PROFOPT_OPTIONS] { + set PROFOPT_OPTIONS [list \ + { -g } \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O3 } \ + { -O3 -g } \ + { -Os } ] +} + +# +# profopt-cleanup -- remove profiling or performance results files. +# +# TESTCASE is the name of the test +# EXT is the extensions of files to remove +# +proc profopt-cleanup { testcase extlist } { + set basename [file tail $testcase] + set base [file rootname $basename] + foreach ext $extlist { + set files [glob -nocomplain $base.$ext] + if { $files != "" } { + eval "remote_file build delete $files" + } + } +} + +# +# profopt-target-cleanup -- remove profiling result files. +# +# DIR is the name of the directory +# TESTCASE is the name of the test +# EXT is the extensions of files to remove +# +proc profopt-target-cleanup { dir testcase ext } { + global additional_sources_used + set basename [file tail $testcase] + set base [file rootname $basename] + set file "$dir/$base.$ext" + eval "remote_file target delete $file" + + if [info exists additional_sources_used] { + foreach srcfile $additional_sources_used { + set basename [file tail $srcfile] + set base [file rootname $basename] + set file "$dir/$base.$ext" + eval "remote_file target delete $file" + } + } +} + +# +# profopt-perf-value -- get performance value for a test +# +# TESTCASE is the name of the test +# PERF_EXT is the extension of the performance result file +# OPTSTR is the string of compiler options +# +proc profopt-perf-value { testcase perf_ext optstr } { + set basename [file tail $testcase] + set base [file rootname $basename] + set files [glob -nocomplain $base.$perf_ext] + # The file doesn't exist; let the caller decide if that's a problem. + if { $files == "" } { + return -2 + } + remote_upload host $base.$perf_ext $base.$perf_ext + set fd [open $base.$perf_ext r] + gets $fd line + set val -2 + if [regexp "TIME" $line] { + if [regexp "TIME -1" $line] { + fail "$testcase perf check: no consistent time available, $optstr" + set val -1 + } elseif ![regexp "(\[0-9\]+)" "$line" val] { + set val -2 + } + } + # Report problems with an existing file. + if { $val == -2 } { + fail "$testcase perf check: file $base.$perf_ext has wrong format, $optstr" + } + close $fd + profopt-cleanup $testcase $perf_ext + return $val +} + +# +# dg-final-generate -- process code to run after the profile-generate step +# +# ARGS is the line number of the directive followed by the commands. +# +proc dg-final-generate { args } { + global generate_final_code + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + append generate_final_code "[lindex $args 1]\n" +} + +# +# dg-final-use -- process code to run after the profile-use step +# +# ARGS is the line number of the directive followed by the commands. +# +proc dg-final-use { args } { + global use_final_code + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + append use_final_code "[lindex $args 1]\n" +} + +# +# dg-final-use-not-autofdo -- process code to run after the profile-use step +# but only if not running autofdo +# ARGS is the line number of the directive followed by the commands. +# +proc dg-final-use-not-autofdo { args } { + global use_final_code + global run_autofdo + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + + if { $run_autofdo == 1 } { + return + } + append use_final_code "[lindex $args 1]\n" +} + +# +# dg-final-use-autofdo -- process code to run after the profile-use step +# but only if running autofdo +# ARGS is the line number of the directive followed by the commands. +# + +proc dg-final-use-autofdo { args } { + global use_final_code + global run_autofdo + + if { [llength $args] > 2 } { + error "[lindex $args 0]: too many arguments" + return + } + + if { $run_autofdo != 1 } { + return + } + append use_final_code "[lindex $args 1]\n" +} + +# +# profopt-final-code -- run final code +# +# WHICH is "generate" or "use". +# FINAL_CODE is the TCL code to run. +# TESTCASE is the name of the test, for error messages. +# +proc profopt-final-code { which final_code name } { + # This is copied from dg-test in dg.exp of DejaGnu. + regsub -all "\\\\(\[{}\])" $final_code "\\1" final_code + proc profopt-final-proc { args } $final_code + if [catch "profopt-final-proc $name" errmsg] { + perror "$name: error executing dg-final-${which}: $errmsg" + unresolved "$name: Error executing dg-final-${which}: $errmsg" + } +} + +# +# profopt-get-options -- process test directives +# +# SRC is the full pathname of the testcase. +# +proc profopt-get-options { src } { + # dg-options sets a variable called dg-extra-tool-flags. + set dg-extra-tool-flags "" + + # dg-require-* sets dg-do-what. + upvar dg-do-what dg-do-what + + # current_compiler_flags reads tool_flags from the same stack frame + # as dg-extra-tool-flags + set tool_flags "" + + set tmp [dg-get-options $src] + foreach op $tmp { + set cmd [lindex $op 0] + if { ![string compare "dg-options" $cmd] \ + || ![string compare "dg-additional-options" $cmd] \ + || ![string compare "dg-add-options" $cmd] \ + || ![string compare "dg-skip-if" $cmd] \ + || ![string compare "dg-final-generate" $cmd] \ + || ![string compare "dg-final-use" $cmd] \ + || ![string compare "dg-final-use-not-autofdo" $cmd] \ + || ![string compare "dg-final-use-autofdo" $cmd] \ + || ![string compare "dg-additional-sources" $cmd] \ + || [string match "dg-require-*" $cmd] } { + set status [catch "$op" errmsg] + if { $status != 0 } { + perror "$src: $errmsg for \"$op\"\n" + unresolved "$src: $errmsg for \"$op\"" + return + } + } else { + # Ignore unrecognized dg- commands, but warn about them. + warning "profopt.exp does not support $cmd" + } + } + + # Return flags to use for compiling the primary source file and for + # linking. + return ${dg-extra-tool-flags} +} + +# auto-profopt-execute -- Compile for auto profiling and then feedback, +# then normal. SRC is the full path name of the testcase. +proc auto-profopt-execute { src } { + global profile_wrapper + global profile_option + global feedback_option + global run_autofdo + global srcdir + + if { ! [check_profiling_available "-fauto-profile"] } { + regsub "(?q)$srcdir/" $src "" testcase + unsupported "$testcase -fauto-profile" + return + } + set profile_wrapper [profopt-perf-wrapper] + set profile_option "-gdwarf-4 -DFOR_AUTOFDO_TESTING" + set feedback_option "-fauto-profile -DFOR_AUTOFDO_TESTING -fearly-inlining" + set run_autofdo 1 + profopt-execute $src + unset profile_wrapper + unset profile_option + unset feedback_option + unset run_autofdo +} + +# +# c-prof-execute -- compile for profiling and then feedback, then normal +# +# SRC is the full pathname of the testcase. +# +proc profopt-execute { src } { + global srcdir tmpdir + global PROFOPT_OPTIONS + global tool profile_option feedback_option prof_ext perf_ext perf_delta + global profile_wrapper run_autofdo ld_library_path + global generate_final_code use_final_code + global verbose + global testname_with_flags + + if ![info exists profile_option] { + error "No profile option specified for first compile." + } + if ![info exists feedback_option] { + error "No feedback option specified for second compile." + } + if ![info exists profile_wrapper] { + set profile_wrapper "" + } + if ![info exists run_autofdo] { + set run_autofdo "" + } + + # Use the default option list or one defined for a set of tests. + if ![info exists PROFOPT_OPTIONS] { + error "PROFOPT_OPTIONS is not defined" + } + set prof_option_list $PROFOPT_OPTIONS + + regsub "(?q)$srcdir/" $src "" testcase + # If we couldn't rip $srcdir out of `src' then just do the best we can. + # The point is to reduce the unnecessary noise in the logs. Don't strip + # out too much because different testcases with the same name can confuse + # `test-tool'. + if [string match "/*" $testcase] { + set testcase "[file tail [file dirname $src]]/[file tail $src]" + } + + # Several procedures access the name of the test with torture flags, + # normally defined in dg-test. Profile optimization tests don't + # use dg-test, so define it here to make it accessible via + # testname-for-summary. + set testname_with_flags $testcase + + set executable $tmpdir/[file tail [file rootname $src].x] + set basename [file tail $testcase] + set base [file rootname $basename] + + set count 0 + foreach option $prof_option_list { + # We pass -dumpbase-ext ${execext}[123] to the compile&link + # commands so as to avoid the combination of the executable + # with the source name in the aux outputs. + set execext ".x${count}" + set execname1 "${executable}${count}1" + set execname2 "${executable}${count}2" + set execname3 "${executable}${count}3" + incr count + + remote_file build delete $execname1 + remote_file build delete $execname2 + remote_file build delete $execname3 + verbose "Testing $testcase, $option" 1 + + # Remove old performance data files. + if [info exists perf_ext] { + profopt-cleanup $testcase $perf_ext + } + + # Process test directives. + + set generate_final_code "" + set use_final_code "" + set dg-do-what [list "run" "" P] + set extra_flags [profopt-get-options $src] + if { [lindex ${dg-do-what} 1 ] == "N" } { + unsupported "$testcase" + unset testname_with_flags + verbose "$src not supported on this target, skipping it" 3 + return + } + + # schedule removal of dump files et al + # Do this before the call below destroys additional_sources.. + append use_final_code [schedule-cleanups "$option $extra_flags"] + set extra_options [dg-additional-files-options "" "$src"] + + # Remove old profiling data files. Make sure additional_sources_used is + # valid, by running it after dg-additional-files-options. + foreach ext $prof_ext { + profopt-target-cleanup $tmpdir $base $ext + profopt-target-cleanup $tmpdir $base "perf.data" + } + + # Tree profiling requires TLS runtime support, which may need + # additional flags. + if { [string first "-fprofile-generate" $profile_option] >= 0 } { + set extra_flags [add_options_for_tls $extra_flags] + } + + # Compile for profiling. + + set options "$extra_options" + lappend options "additional_flags=$option $extra_flags $profile_option -dumpbase-ext ${execext}1" + set optstr "$option $profile_option" + set comp_output [${tool}_target_compile "$src" "$execname1" executable $options] + if ![${tool}_check_compile "$testcase compilation" $optstr $execname1 $comp_output] { + unresolved "$testcase execution, $optstr" + unresolved "$testcase compilation, $option $feedback_option" + unresolved "$testcase execution, $option $feedback_option" + continue + } + + # Run the profiled test. + if { $run_autofdo == 1 } { + if { ![info exists ld_library_path]} { + set ld_library_path "" + } + set orig_ld_library_path "[getenv LD_LIBRARY_PATH]" + setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" + verbose -log "Running $profile_wrapper -o $tmpdir/$base.perf.data $execname1" + set id [remote_spawn "" "$profile_wrapper -o $tmpdir/$base.perf.data $execname1" "readonly"] + setenv LD_LIBRARY_PATH $orig_ld_library_path + if { $id < 0 } { + warning "Failed to run profiler" + set status "fail" + } else { + set result [remote_wait "" 300] + set status [lindex $result 0] + verbose "perf result $result" + if { $status == 0 } { + set status "pass" + } else { + set status "fail" + } + } + } else { + set result [${tool}_load $execname1 "" ""] + set status [lindex $result 0] + } + + set missing_file 0 + set bprefix "" + # Make sure the profile data was generated, and fail if not. + if { $status == "pass" } { + # convert profile + if { $run_autofdo == 1 } { + set bprefix "afdo." + set cmd "create_gcov --binary $execname1 --profile=$tmpdir/$base.perf.data -gcov_version=2 --gcov=$tmpdir/$bprefix$base.$ext" + verbose "Running $cmd" + set id [remote_spawn "" $cmd] + if { $id < 0 } { + unsupported "$testcase -fauto-profile: cannot run create_gcov" + unset testname_with_flags + set status "fail" + return + } + set status [remote_wait "" 300] + set status "pass" + } + + foreach ext $prof_ext { + remote_upload target $tmpdir/$bprefix$base.$ext + set files [glob -nocomplain $bprefix$base.$ext] + if { $files == "" } { + set status "fail" + set missing_file 1 + fail "$testcase execution: file $bprefix$base.$ext does not exist, $option $profile_option" + } + } + } + if { $missing_file == 0 } { + $status "$testcase execution, $optstr" + } + + # If there is dg-final code to execute for the generate step, do it + # even if it failed; it might clean up temporary files. + if ![string match $generate_final_code ""] { + profopt-final-code "generate" $generate_final_code $testcase + } + + remote_file build delete $execname1 + + # Quit for this round if it failed + if { $status != "pass" } { + unresolved "$testcase compilation, $option $feedback_option" + unresolved "$testcase execution, $option $feedback_option" + continue + } + + # Compile with feedback-directed optimizations. + + set options "$extra_options" + lappend options "additional_flags=$option $extra_flags $feedback_option -dumpbase-ext ${execext}2" + set optstr "$option $feedback_option" + if { [string first "-fauto-profile" $options] >= 0} { + set options [regsub -- "-fauto-profile" $options "-fauto-profile=$tmpdir/$bprefix$base.$ext"] + } + + set comp_output [${tool}_target_compile "$src" "$execname2" "executable" $options] + + # Prune warnings we know are unwanted. + set comp_output [prune_warnings $comp_output] + + if ![${tool}_check_compile "$testcase compilation" $optstr $execname2 $comp_output] { + unresolved "$testcase execution, $optstr" + continue + } + + # Run the profile-directed optimized test. + + set result [${tool}_load "$execname2" "" ""] + set status [lindex $result 0] + $status "$testcase execution, $optstr" + + # If there is dg-final code to execute for the use step, do it. + if ![string match $use_final_code ""] { + profopt-final-code "use" $use_final_code $testcase + } + + # Remove the profiling data files. + foreach ext $prof_ext { + profopt-target-cleanup $tmpdir "$bprefix$base" $ext + profopt-target-cleanup $tmpdir $base "perf.data" + profopt-target-cleanup $tmpdir $base "gcda.imports" + } + + if { $status != "pass" } { + continue + } + + # If the test is not expected to produce performance data then + # we're done now. + if ![info exists perf_ext] { + remote_file build delete $execname2 + continue + } + + # Get the performance data from the test built with + # profile-directed optimization. If the file doesn't exist or if + # the value is zero, skip the performance comparison. + set val2 [profopt-perf-value $testcase $perf_ext $optstr] + if { $val2 <= 0 } { + remote_file build delete $execname2 + continue + } + + # Compile with normal optimizations. + + set options "$extra_options" + lappend options "additional_flags=$option -dumpbase-ext ${execext}3" + set optstr "$option" + set comp_output [${tool}_target_compile "$src" "$execname3" "executable" $options] + if ![${tool}_check_compile "$testcase compilation" $optstr $execname3 $comp_output] { + unresolved "$testcase execution, $optstr" + unresolved "$testcase perf check, $optstr" + continue + } + + # Run the test with normal optimizations. + + set result [${tool}_load "$execname3" "" ""] + set status [lindex $result 0] + $status "$testcase execution, $optstr" + if { $status != "pass" } { + unresolved "$testcase perf check, $optstr" + continue + } + + # Get the performance data from the test built with normal + # optimization. + set val1 [profopt-perf-value $testcase $perf_ext $optstr] + if { $val1 < 0 } { + if { $val1 == -2 } { + # The data file existed with the profile-directed + # optimization so this one should, too. + fail "$testcase perf check: file $base.$perf_ext does not exist, $optstr" + } + continue + } + + # Compare results of the two runs and fail if the time with the + # profile-directed optimization is significantly more than the time + # without it. + set status "pass" + if { $val2 > $val1 } { + # Check for a performance degration outside of allowable limits. + if { [expr $val2 - $val1] > [expr [expr $val1 * $perf_delta] / 100] } { + set status "fail" + } + } + if { $status == "fail" } { + fail "$testcase perf check: orig: $val1 new: $val2, $optstr" + } else { + $status "$testcase perf check, $optstr" + verbose "$testcase orig: $val1 new: $val2, $optstr" 2 + remote_file build delete $execname2 + remote_file build delete $execname3 + } + } + unset testname_with_flags +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/prune.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/prune.exp new file mode 100644 index 0000000000000000000000000000000000000000..04c6a1dd7a1ea6a9dff056340d01fabc75763dad --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/prune.exp @@ -0,0 +1,170 @@ +# Copyright (C) 1997-2022 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 +# . + +# Prune messages from gcc that aren't useful. + +load_lib multiline.exp + +# Add options to TEST_ALWAYS_FLAGS so that diagnostics have the expected output +# format. Note: You should not normally need to add more options here. If you +# have made a change to the default diagnostic output format and are wanting to +# undo that in the testsuite here, then please update the handling of +# -fdiagnostics-plain-output in opts-common.c instead. + +if ![info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "" +} +set TEST_ALWAYS_FLAGS "-fdiagnostics-plain-output $TEST_ALWAYS_FLAGS" + +proc prune_gcc_output { text } { + global srcdir + + #send_user "Before:$text\n" + + # Handle any freeform regexps. + set text [handle-dg-regexps $text] + + # Remove Windows .exe suffix + regsub -all "(as|cc1|cc1plus|collect2|f951|ld|lto-wrapper)\.exe?:" $text {\1:} text + + regsub -all "(^|\n)(\[^\n\]*: \[iI\]|I)n ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|substitution|program|subroutine|block-data)\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: (recursively )?required \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: in .constexpr. expansion \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: in requirements \[^\n\]*" $text "" text + regsub -all "(^|\n) inlined from \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: error: ld returned \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: re(compiling|linking)\[^\n\]*" $text "" text + regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text + regsub -all "(^|\n)\[0-9\]\[0-9\]* errors\." $text "" text + + # Diagnostic inclusion stack + regsub -all "(^|\n)(In file)?\[ \]+included from \[^\n\]*" $text "" text + regsub -all "(^|\n)\[ \]+from \[^\n\]*" $text "" text + regsub -all "(^|\n)(In|of) module( \[^\n \]*,)? imported at \[^\n\]*" $text "" text + + global prune_notes + if { $prune_notes } { + # Ignore informational notes. + regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text + } + + # Ignore harmless -fpic warnings. + regsub -all "(^|\n)\[^\n\]*: warning: -f(pic|PIC) ignored for target\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: warning: -f(pic|PIC)( and -fpic are| is)? not supported\[^\n\]*" $text "" text + + # Ignore errata warning from IA64 assembler. + regsub -all "(^|\n)\[^\n\]*: Additional NOP may be necessary to workaround Itanium processor A/B step errata" $text "" text + regsub -all "(^|\n)\[^\n*\]*: Assembler messages:\[^\n\]*" $text "" text + + # Ignore harmless VTA note. + regsub -all "(^|\n)\[^\n\]*: note: variable tracking size limit exceeded with -fvar-tracking-assignments, retrying without\[^\n\]*" $text "" text + + # It would be nice to avoid passing anything to gcc that would cause it to + # issue these messages (since ignoring them seems like a hack on our part), + # but that's too difficult in the general case. For example, sometimes + # you need to use -B to point gcc at crt0.o, but there are some targets + # that don't have crt0.o. + regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text + regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text + + # Ideally the tests would indicate that executable stacks were needed + # to the linker. But the option for that varies and may not even exist + # on some targets. So we're stuck pruning the warning. + regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*requires executable stack\[^\n\]*\n?)+" $text "\\1" text + + # Ignore harmless warnings from Xcode 3.2.x. + regsub -all "(^|\n)\[^\n\]*ld: warning: can't add line info to anonymous symbol\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*warning: DWARFDebugInfoEntry::AppendDependants\[^\n\]*AT_\[^\n\]*FORM_ref4\[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*warning:\[^\n\]*TAG_variable: AT_location\[^\n\]*didn't have valid function low pc\[^\n\]*" $text "" text + + # Ignore harmless warnings from Xcode 4.0. + regsub -all "(^|\n)\[^\n\]*ld: warning: could not create compact unwind for\[^\n\]*" $text "" text + + # Ignore dsymutil warning (tool bug is actually linker) + regsub -all "(^|\n)\[^\n\]*could not find object file symbol for symbol\[^\n\]*" $text "" text + + # Ignore stabs obsoletion warnings + regsub -all "(^|\n)\[^\n\]*\[Ww\]arning: STABS debugging information is obsolete and not supported anymore\[^\n\]*" $text "" text + + # Ignore missing lto jobserver for tests that do more than 1 LTRANS unit + regsub -all "(^|\n)\[^\n\]*lto\[^\n\]*: warning: using serial compilation of \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*lto\[^\n\]*: note: see the \[^\n\]*'-flto' option documentation\[^\n\]* for more information" $text "" text + + # Many tests that use visibility will still pass on platforms that don't support it. + regsub -all "(^|\n)\[^\n\]*lto1: warning: visibility attribute not supported in this configuration; ignored\[^\n\]*" $text "" text + + # If dg-enable-nn-line-numbers was provided, then obscure source-margin + # line numbers by converting them to "NN" form. + set text [maybe-handle-nn-line-numbers $text] + + # Call into multiline.exp to handle any multiline output directives. + set text [handle-multiline-outputs $text] + + #send_user "After:$text\n" + + return $text +} + +# escape metacharacters in literal string, so it can be used in regex + +proc escape_regex_chars { line } { + return [string map {"^" "\\^" + "$" "\\$" + "(" "\\(" + ")" "\\)" + "[" "\\[" + "]" "\\]" + "{" "\\{" + "}" "\\}" + "." "\\." + "\\" "\\\\" + "?" "\\?" + "+" "\\+" + "*" "\\*" + "|" "\\|"} $line] +} + +proc prune_file_path { text } { + global srcdir + + set safedir [escape_regex_chars $srcdir] + regsub -all "$safedir\/" $text "" text + + # Truncate absolute file path into relative path. + set topdir "[file dirname [file dirname [file dirname $safedir]]]" + regsub -all "$topdir\/" $text "" text + + return $text +} + +# Prune internal compiler error messages, including the "Please submit..." +# footnote. + +proc prune_ices { text } { + regsub -all "(^|\n)\[^\n\]*: internal compiler error:.*\nSee \[^\n\]*" $text "" text + regsub -all "(^|\n|')*Internal compiler error:.*\nSee \[^\n\]*" $text "" text + return $text +} + +# Provide a definition of this if missing (delete after next dejagnu release). + +if { [info procs prune_warnings] == "" } then { + proc prune_warnings { text } { + return $text + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanasm.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanasm.exp new file mode 100644 index 0000000000000000000000000000000000000000..a80630bb2a819812ce1fe05184535011a12f1288 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanasm.exp @@ -0,0 +1,946 @@ +# Copyright (C) 2000-2022 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 +# . + +# Various utilities for scanning assembler output, used by gcc-dg.exp and +# g++-dg.exp. + +# Utility for scanning compiler result, invoked via dg-final. + +# Transform newline and similar characters into their escaped form. +proc make_pattern_printable { pattern } { + return [string map {\t \\t \n \\n \r \\r \\ \\\\} $pattern] +} + +# Scan the OUTPUT_FILE for a pattern. If it is present and POSITIVE +# is non-zero, or it is not present and POSITIVE is zero, the test +# passes. The ORIG_ARGS is the list of arguments provided by dg-final +# to scan-assembler. The first element in ORIG_ARGS is the regular +# expression to look for in the file. The second element, if present, +# is a DejaGNU target selector. + +proc dg-scan { name positive testcase output_file orig_args } { + if { [llength $orig_args] < 1 } { + error "$name: too few arguments" + return + } + if { [llength $orig_args] > 2 } { + error "$name: too many arguments" + return + } + if { [llength $orig_args] >= 2 } { + switch [dg-process-target [lindex $orig_args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set pattern [lindex $orig_args 0] + set printable_pattern [make_pattern_printable $pattern] + + set files [dg_glob_remote $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase $name $printable_pattern" + return + } + set fd [open $output_file r] + set text [read $fd] + close $fd + + set match [regexp -- $pattern $text] + if { $match == $positive } { + pass "$testcase $name $printable_pattern" + } else { + fail "$testcase $name $printable_pattern" + } +} + +proc dg_glob_remote { file_pattern } { + if { [is_remote host] } { + remote_upload host $file_pattern + } + return [glob -nocomplain $file_pattern] +} + +# Look for a pattern in the .s file produced by the compiler. See +# dg-scan for details. + +proc scan-assembler { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + dg-scan "scan-assembler" 1 $testcase $output_file $args +} + +force_conventional_output_for scan-assembler + +# Check that a pattern is not present in the .s file produced by the +# compiler. See dg-scan for details. + +proc scan-assembler-not { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + + dg-scan "scan-assembler-not" 0 $testcase $output_file $args +} + +force_conventional_output_for scan-assembler-not + +# Return the scan for the assembly for hidden visibility. + +proc hidden-scan-for { symbol } { + + set objformat [gcc_target_object_format] + + switch $objformat { + coff { return "$symbol\[,\d\]*hidden" } + elf { return "hidden\[ \t_\]*$symbol" } + mach-o { return "private_extern\[ \t_\]*_?$symbol" } + default { return "" } + } + +} + + +# Check that a symbol is defined as a hidden symbol in the .s file +# produced by the compiler. + +proc scan-hidden { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + + if { [llength $args] > 0 } { + set symbol [lindex $args 0] + + set hidden_scan [hidden-scan-for $symbol] + + set args [lreplace $args 0 0 "$hidden_scan"] + } + + dg-scan "scan-hidden" 1 $testcase $output_file $args +} + +# Check that a symbol is not defined as a hidden symbol in the .s file +# produced by the compiler. + +proc scan-not-hidden { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + + if { [llength $args] > 0 } { + set symbol [lindex $args 0] + set hidden_scan [hidden-scan-for $symbol] + + set args [lreplace $args 0 0 "$hidden_scan"] + } + + dg-scan "scan-not-hidden" 0 $testcase $output_file $args +} + +# Check that symbols are emitted in the desired section. +# Like scan-symbol-section, but using the assembly output generated by +# the compiler. +# +# Example: +# +# // All numbered functions (func1, func2, etc.) must be in the .text section or +# // in a .text sub-section (like .text._func1). +# { dg-final { scan-assembler-symbol-section {^_func[1-5]$} {^\.text($|\.)} } } + +proc scan-assembler-symbol-section { args } { + set testcase [testname-for-summary] + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].s" + dg-scan-symbol-section \ + "scan-assembler-symbol-section" $testcase $output_file $args +} + +# Check that symbols are emitted in the desired section. +# +# Symbols and sections are interpreted as regexp patterns. +# +# If no matching symbol is found, scan-symbol-section reports a FAILure. +# +# Usage: +# +# { dg-final { scan-symbol-section FILENAME SYMBOL SECTION } } +# +# Examples: +# +# // The my_var C symbol must be in the .data section (or in a .data._my_var section +# // if -ffunction-sections is in use). +# { dg-final { scan-symbol-section "my-test.s" {^_my_var$} {^\.data(\._my_var)?$} } } +# +# // All numbered functions (func1, func2, etc.) must be in the .text section +# // (and not in any other section like .text._func1). +# { dg-final { scan-symbol-section "my-test.s" {^_func[1-5]$} {^\.text$} } } +# +# Caveats: +# +# * Only ELF and Mach-O targets are supported. Other +# targets, like PE/COFF, might appear to work. +# * For Mach-O targets, the section name matched by scan-symbol-section has one +# of two forms: +# * The Mach-O segment name followed by a comma (',') followed by the Mach-O +# section name. For example, "__TEXT,__text". (There is no whitespace +# between the Mach-O segment name and the Mach-O section name.) +# * ".const", ".data", or ".text". For example, the .text assembler directive +# causes the section name to be ".text" (not "__TEXT,__text"). (However, a +# directive such as .section __TEXT,__text will cause the section name to be +# "__TEXT,__text".) +# * Because scan-symbol-section parses assembly code, scan-symbol-section is +# unaware of section rewriting performed by the linker. For example, the +# sections .text._f1 and .text._f2 would normally be merged by binutils' +# linker into one section called .text, but scan-symbol-section reports the +# sections as .text._f1 and .text._f2 (and not .text). +# * The symbol pattern matches any assembly label, including local labels which +# begin with `.L`. + +proc scan-symbol-section { args } { + set testcase [testname-for-summary] + set output_file [lindex $args 0] + dg-scan-symbol-section \ + "scan-symbol-section" $testcase $output_file $args +} + +# Check that symbols are emitted in the desired section. The ORIG_ARGS is +# the list of arguments provided by dg-final to scan-symbol-section or +# scan-assembler-symbol-section. The first element in ORIG_ARGS is the +# regular expression to look for in the file. The second element, if +# present, is a DejaGNU target selector. +# +# Avoid calling this function directly. In tests, use scan-symbol-section, +# scan-assembler-symbol-section, or scan-lto-assembler-symbol-section instead. + +proc dg-scan-symbol-section { name testcase output_file orig_args } { + if { [llength $orig_args] < 2 } { + error "$name: too few arguments" + return + } + if { [llength $orig_args] > 4 } { + error "$name: too many arguments" + return + } + switch $name { + "scan-symbol-section" { set arg_incr 1 } + default { set arg_incr 0 } + } + if { [llength $orig_args] >= 3 } { + switch [dg-process-target [lindex $orig_args [expr 2 + $arg_incr]]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set symbol_pattern [lindex $orig_args [expr 0 + $arg_incr]] + set expected_section_pattern [lindex $orig_args [expr 1 + $arg_incr]] + + set printable_symbol_pattern [make_pattern_printable $symbol_pattern] + set printable_expected_section_pattern [make_pattern_printable $expected_section_pattern] + + set files [dg_glob_remote $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase $name symbol $printable_symbol_pattern has section $printable_expected_section_pattern" + return + } + + parse_section_of_symbols $output_file section_by_symbol + + set found_symbol 0 + foreach symbol_name [lsort [array names section_by_symbol]] { + if { [regexp -- $symbol_pattern $symbol_name] } { + set section $section_by_symbol($symbol_name) + if { [istarget powerpc*-*-*] && $section == ".opd" } { + set section $section_by_symbol(.L.$symbol_name) + } + set description "$testcase $name symbol $printable_symbol_pattern (found $symbol_name) has section $printable_expected_section_pattern" + if { $section == "" } { + fail "$description (no section detected)" + } else { + set description "$description (found $section)" + if { [regexp -- $expected_section_pattern $section] } { + pass $description + } else { + fail $description + } + } + set found_symbol 1 + } + } + if { ! $found_symbol } { + fail "$testcase $name symbol $printable_symbol_pattern (symbol not found) has section $printable_expected_section_pattern" + } +} + +# Extract a symbol and section names from pre-processed assembly source code. +# +# This function adds entries in the RESULT array where the key is the symbol's +# name (including any leading underscores) and the value is the section's name +# (including any leading periods). +# +# For example, given the following assembly source code in file.s: +# +# .text +# .function _my_function +# _my_function: +# nop +# .data +# _my_data: +# .long 42 +# +# Executing 'parse_section_of_symbols "file.s" symbols' would have the same +# effect as the following code: +# +# set $result(_my_function) .text +# set $result(_my_data) .data + +proc parse_section_of_symbols { filename result } { + upvar $result up_result + + set section_pattern {^\s*(?:(?:\.section|\.csect)\s+(.*)|(\.const|\.data|\.text)\s*)$} + set label_pattern {^(\S+):$} + set previous_pattern {^\s*\.previous\s*$} + + set fd [open $filename r] + set current_section "" + set prev_section "" + while { [gets $fd line] >= 0 } { + if { [regexp -- $label_pattern $line dummy symbol_name] } { + set up_result($symbol_name) $current_section + } elseif { [regexp -- $section_pattern $line dummy section_directive_arguments full_section_directive] } { + set prev_section $current_section + if { $full_section_directive eq "" } { + # Example: .section .text,"ax",progbits + # Example: .section ".text",#alloc,#execinstr,#progbits + # Example: .section __TEXT,__text + set arguments [split $section_directive_arguments ","] + set current_section [string trim [lindex $arguments 0]] + set current_section [string trim $current_section {"}] + set arg_1 [string trim [lindex $arguments 1]] + if { [regexp {^_} $arg_1] } { + # The second argument looks like a Mach-O section name. + set current_section "$current_section,$arg_1" + } + } else { + # Example: .text + set current_section "$full_section_directive" + } + } elseif { [regexp -- $previous_pattern $line dummy] } { + set sect $prev_section + set prev_section $current_section + set current_section $sect + } + } + close $fd +} + +# Look for a pattern in OUTPUT_FILE. See dg-scan for details. + +proc scan-file { output_file args } { + set testcase [testname-for-summary] + dg-scan "scan-file" 1 $testcase $output_file $args +} + +# Check that a pattern is not present in the OUTPUT_FILE. See dg-scan +# for details. + +proc scan-file-not { output_file args } { + set testcase [testname-for-summary] + dg-scan "scan-file-not" 0 $testcase $output_file $args +} + +# Look for a pattern in the .su file produced by the compiler. See +# dg-scan for details. + +proc scan-stack-usage { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].su" + + dg-scan "scan-stack-usage" 1 $testcase $output_file $args +} + +# Check that a pattern is not present in the .su file produced by the +# compiler. See dg-scan for details. + +proc scan-stack-usage-not { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].su" + + dg-scan "scan-stack-usage-not" 0 $testcase $output_file $args +} + +# Return the filename of the Ada spec corresponding to the argument. + +proc get_ada_spec_filename { testcase } { + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set tailname [file tail $filename] + set extension [string trimleft [file extension $tailname] {.}] + regsub -all {\-} [file rootname $tailname] {_} rootname + + return [string tolower "${rootname}_${extension}.ads"] +} + +# Look for a pattern in the .ads file produced by the compiler. See +# dg-scan for details. + +proc scan-ada-spec { args } { + set testcase [testname-for-summary] + set output_file "[get_ada_spec_filename $testcase]" + + dg-scan "scan-ada-spec" 1 $testcase $output_file $args +} + +# Check that a pattern is not present in the .ads file produced by the +# compiler. See dg-scan for details. + +proc scan-ada-spec-not { args } { + set testcase [testname-for-summary] + set output_file "[get_ada_spec_filename $testcase]" + + dg-scan "scan-ada-spec-not" 0 $testcase $output_file $args +} + +# Call pass if pattern is present given number of times, otherwise fail. +proc scan-assembler-times { args } { + if { [llength $args] < 2 } { + error "scan-assembler-times: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-assembler-times: too many arguments" + return + } + if { [llength $args] >= 3 } { + switch [dg-process-target [lindex $args 2]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set pattern [lindex $args 0] + set times [lindex $args 1] + set pp_pattern [make_pattern_printable $pattern] + + # This must match the rule in gcc-dg.exp. + set output_file "[file rootname [file tail $filename]].s" + + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase scan-assembler-times $pp_pattern $times" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + set result_count [llength [regexp -inline -all -- $pattern $text]] + if {$result_count == $times} { + pass "$testcase scan-assembler-times $pp_pattern $times" + } else { + verbose -log "$testcase: $pp_pattern found $result_count times" + fail "$testcase scan-assembler-times $pp_pattern $times" + } +} + +force_conventional_output_for scan-assembler-times + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +proc scan-assembler-dem { args } { + global cxxfilt + global base_dir + + if { [llength $args] < 1 } { + error "scan-assembler-dem: too few arguments" + return + } + if { [llength $args] > 2 } { + error "scan-assembler-dem: too many arguments" + return + } + if { [llength $args] >= 2 } { + switch [dg-process-target [lindex $args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set pattern [lindex $args 0] + set pp_pattern [make_pattern_printable $pattern] + set output_file "[file rootname [file tail $filename]].s" + + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase scan-assembler-dem $pp_pattern" + return + } + + set output [remote_exec host "$cxxfilt" "" "$output_file"] + set text [lindex $output 1] + + if [regexp -- $pattern $text] { + pass "$testcase scan-assembler-dem $pp_pattern" + } else { + fail "$testcase scan-assembler-dem $pp_pattern" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +proc scan-assembler-dem-not { args } { + global cxxfilt + global base_dir + + if { [llength $args] < 1 } { + error "scan-assembler-dem-not: too few arguments" + return + } + if { [llength $args] > 2 } { + error "scan-assembler-dem-not: too many arguments" + return + } + if { [llength $args] >= 2 } { + switch [dg-process-target [lindex $args 1]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set pattern [lindex $args 0] + set pp_pattern [make_pattern_printable $pattern] + set output_file "[file rootname [file tail $filename]].s" + + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase scan-assembler-dem-not $pp_pattern" + return + } + + set output [remote_exec host "$cxxfilt" "" "$output_file"] + set text [lindex $output 1] + + if ![regexp -- $pattern $text] { + pass "$testcase scan-assembler-dem-not $pp_pattern" + } else { + fail "$testcase scan-assembler-dem-not $pp_pattern" + } +} + +# Call pass if object size is ok, otherwise fail. +# example: /* { dg-final { object-size text <= 54 } } */ +proc object-size { args } { + global size + global base_dir + + if { [llength $args] < 3 } { + error "object-size: too few arguments" + return + } + if { [llength $args] > 4 } { + error "object-size: too many arguments" + return + } + if { [llength $args] >= 4 } { + switch [dg-process-target [lindex $args 3]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find size like we find g++ in g++.exp. + if ![info exists size] { + set size [findfile $base_dir/../../../binutils/size \ + $base_dir/../../../binutils/size \ + [findfile $base_dir/../../size $base_dir/../../size \ + [findfile $base_dir/size $base_dir/size \ + [transform size]]]] + verbose -log "size is $size" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set what [lindex $args 0] + set where [lsearch { text data bss total } $what] + if { $where == -1 } { + error "object-size: illegal argument: $what" + return + } + set cmp [lindex $args 1] + if { [lsearch { < > <= >= == != } $cmp] == -1 } { + error "object-size: illegal argument: $cmp" + return + } + set with [lindex $args 2] + if ![string is integer $with ] { + error "object-size: illegal argument: $with" + return + } + + set output_file "[file rootname [file tail $filename]].o" + if ![file_on_host exists $output_file] { + verbose -log "$testcase: $output_file does not exist" + unresolved "$testcase object-size $what $cmp $with" + return + } + set output [remote_exec host "$size" "$output_file"] + set status [lindex $output 0] + if { $status != 0 } { + verbose -log "$testcase object-size: $size failed" + unresolved "$testcase object-size $what $cmp $with" + return + } + + set text [lindex $output 1] + set lines [split $text "\n"] + + set l0match {^\s*text\s+data\s+bss\s+dec\s+hex\s+filename\s*$} + set l1match {^\s*\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+} + + if { [istarget *-*-darwin*] } { + set l0match {^\s*__TEXT\s+__DATA\s+__OBJC\s+others\s+dec\s+hex\s*$} + set l1match {^\s*\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+} + } + + set line0 [lindex $lines 0] + if ![regexp $l0match $line0] { + verbose -log "$testcase object-size: $size did not produce expected first line: $line0" + unresolved "$testcase object-size $what $cmp $with" + return + } + + set line1 [lindex $lines 1] + if ![regexp $l1match $line1] { + verbose -log "$testcase object-size: $size did not produce expected second line: $line1" + unresolved "$testcase object-size $what $cmp $with" + return + } + + set actual [lindex $line1 $where] + verbose -log "$what size is $actual" + + if [expr $actual $cmp $with] { + pass "$testcase object-size $what $cmp $with" + } else { + fail "$testcase object-size $what $cmp $with" + } +} + +# Utility for testing that a function is defined on the current line. +# Call pass if so, otherwise fail. Invoked directly; the file must +# have been compiled with -g -dA. +# +# Argument 0 is the current line, passed implicitly by dejagnu +# Argument 1 is the function to check +# Argument 2 handles expected failures and the like +# Argument 3 is "." to match the current line, or an integer to match +# an explicit line. +proc dg-function-on-line { args } { + # Upvar from dg-final: + upvar dg-final-code final-code + + set line [lindex $args 0] + set symbol [lindex $args 1] + set failures [lindex $args 2] + + if { [llength $args] >= 4 } { + switch [lindex $args 3] { + "." { } + "default" { set line [lindex $args 3] } + } + } + + if { [istarget hppa*-*-linux*] } { + set pattern [format {%s:\n\t.PROC\n\t.CALLINFO.*\n\t.ENTRY\n.L.*:\n(\t.file[^\t]*)*\t[^:]+:%d(:[0-9]+)?\n} \ + $symbol $line] + } elseif { [istarget hppa*-*-*] } { + set pattern [format {\t;[^:]+:%d(:[0-9]+)?\n(\t[^\t]+\n)+%s:\n\t.PROC} \ + $line $symbol] + } elseif { [istarget mips*-*-*] } { + set pattern [format {\t\.loc [0-9]+ %d [0-9]+( [^\n]*)?\n(\t.cfi_startproc[^\t]*\n)*\t\.set\t(no)?mips16\n\t(\.set\t(no)?micromips\n\t)?\.ent\t%s\n\t\.type\t%s, @function\n%s:\n} \ + $line $symbol $symbol $symbol] + } elseif { [istarget microblaze*-*-*] } { + set pattern [format {:%d(:[0-9]+)?\n\$.*:\n\t\.ent\t%s\n\t\.type\t%s, @function\n%s:\n} \ + $line $symbol $symbol $symbol] + } else { + set pattern [format {%s:[^\t]*(\t.(fnstart|frame|mask|file)[^\t]*)*\t[^:]+:%d(:[0-9]+)?\n} \ + $symbol $line] + } + + # The lack of spaces around $pattern is important, since they'd + # become part of the regex scan-assembler tries to match. + set cmd "scan-assembler {$pattern}" + if { [llength $args] >= 3 } { + set cmd "$cmd {$failures}" + } + + append final-code "$cmd\n" +} + +# Look for a pattern in the .exe.ltrans0.s file produced by the +# compiler. See dg-scan for details. + +proc scan-lto-assembler { args } { + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set output_file "[file rootname [file tail $filename]].ltrans0.ltrans.s" + verbose "output_file: $output_file" + dg-scan "scan-lto-assembler" 1 $testcase $output_file $args +} + +# Read assembly file FILENAME and store a mapping from function names +# to function bodies in array RESULT. FILENAME has already been uploaded +# locally where necessary and is known to exist. + +proc parse_function_bodies { filename result } { + upvar $result up_result + + # Regexp for the start of a function definition (name in \1). + set label {^([a-zA-Z_]\S+):$} + + # Regexp for the end of a function definition. + set terminator {^\s*\.size} + + # Regexp for lines that aren't interesting. + set fluff {^\s*(?:\.|//|@)} + + set fd [open $filename r] + set in_function 0 + while { [gets $fd line] >= 0 } { + if { [regexp $label $line dummy function_name] } { + set in_function 1 + set function_body "" + } elseif { $in_function } { + if { [regexp $terminator $line] } { + set up_result($function_name) $function_body + set in_function 0 + } elseif { ![regexp $fluff $line] } { + append function_body $line "\n" + } + } + } + close $fd +} + +# FUNCTIONS is an array that maps function names to function bodies. +# Return true if it contains a definition of function NAME and if +# that definition matches BODY_REGEXP. + +proc check_function_body { functions name body_regexp } { + upvar $functions up_functions + + if { ![info exists up_functions($name)] } { + return 0 + } + return [regexp "^$body_regexp\$" $up_functions($name)] +} + +# Check the implementations of functions against expected output. Used as: +# +# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR]] } } +# +# See sourcebuild.texi for details. + +proc check-function-bodies { args } { + if { [llength $args] < 2 } { + error "too few arguments to check-function-bodies" + } + if { [llength $args] > 4 } { + error "too many arguments to check-function-bodies" + } + + if { [llength $args] >= 3 } { + set required_flags [lindex $args 2] + + upvar 2 dg-extra-tool-flags extra_tool_flags + set flags $extra_tool_flags + + global torture_current_flags + if { [info exists torture_current_flags] } { + append flags " " $torture_current_flags + } + foreach required_flag $required_flags { + switch -- $required_flag { + target - + xfail { + error "misplaced $required_flag in check-function-bodies" + } + } + } + foreach required_flag $required_flags { + if { ![regexp " $required_flag " $flags] } { + return + } + } + } + + set xfail_all 0 + if { [llength $args] >= 4 } { + switch [dg-process-target [lindex $args 3]] { + "S" { } + "N" { return } + "F" { set xfail_all 1 } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + + global srcdir + set input_filename "$srcdir/$filename" + set output_filename "[file rootname [file tail $filename]].s" + + set prefix [lindex $args 0] + set prefix_len [string length $prefix] + set terminator [lindex $args 1] + if { [string equal $terminator ""] } { + set terminator "*/" + } + set terminator_len [string length $terminator] + + set have_bodies 0 + if { [is_remote host] } { + remote_upload host "$filename" + } + if { [file exists $output_filename] } { + parse_function_bodies $output_filename functions + set have_bodies 1 + } else { + verbose -log "$testcase: output file does not exist" + } + + set count 0 + set function_regexp "" + set label {^(\S+):$} + + set lineno 1 + set fd [open $input_filename r] + set in_function 0 + while { [gets $fd line] >= 0 } { + if { [string equal -length $prefix_len $line $prefix] } { + set line [string trim [string range $line $prefix_len end]] + if { !$in_function } { + if { [regexp "^(.*?\\S)\\s+{(.*)}\$" $line dummy \ + line selector] } { + set selector [dg-process-target $selector] + } else { + set selector "P" + } + if { ![regexp $label $line dummy function_name] } { + close $fd + error "check-function-bodies: line $lineno does not have a function label" + } + set in_function 1 + set function_regexp "" + } elseif { [string equal $line "("] } { + append function_regexp "(?:" + } elseif { [string equal $line "|"] } { + append function_regexp "|" + } elseif { [string equal $line ")"] } { + append function_regexp ")" + } elseif { [string equal $line "..."] } { + append function_regexp ".*" + } else { + append function_regexp "\t" $line "\n" + } + } elseif { [string equal -length $terminator_len $line $terminator] } { + if { ![string equal $selector "N"] } { + if { $xfail_all || [string equal $selector "F"] } { + setup_xfail "*-*-*" + } + set testname "$testcase check-function-bodies $function_name" + if { !$have_bodies } { + unresolved $testname + } elseif { [check_function_body functions $function_name \ + $function_regexp] } { + pass $testname + } else { + fail $testname + } + } + set in_function 0 + incr count + } + incr lineno + } + close $fd + if { $in_function } { + error "check-function-bodies: missing \"$terminator\"" + } + if { $count == 0 } { + error "check-function-bodies: no matches found" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scandump.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scandump.exp new file mode 100644 index 0000000000000000000000000000000000000000..85217cc96a5be78f214fce1f482e39e366b1aa71 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scandump.exp @@ -0,0 +1,326 @@ +# Copyright (C) 2000-2022 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 +# . + +# Various utilities for scanning dump output, used by gcc-dg.exp and +# g++-dg.exp. +# +# This is largely borrowed from scanasm.exp. + +# Extract the constant part of the dump file suffix from the regexp. +# Argument 0 is the regular expression. +proc dump-suffix { arg } { + set idx [expr [string first "." $arg] + 1] + return [string range $arg $idx end] +} + +# Construct the dumpbase. +# Argument 0 is the src file +# Argument 1 is the dump base suffix +proc dump-base { args } { + set src [lindex $args 0] + set dumpbase_suf [lindex $args 1] + # The dump basename may vary depending on the output name, on + # whether there are multiple sources. We use -dumpbase "" in + # gcc-defs to base compilation dumps only on the source basename. + set dumpbase $src + if { [string length $dumpbase_suf] != 0 } { + regsub {[.][^.]*$} $src $dumpbase_suf dumpbase + } + return $dumpbase +} + +# Expand dump file name pattern to exactly one file. +# Return a single dump file name or an empty string +# if the pattern matches no file or more than one file. +# +# Argument 0 is the testcase name +# Argument 1 is the dump file glob pattern +proc glob-dump-file { args } { + + set pattern [lindex $args 1] + set dump_file "[glob -nocomplain $pattern]" + set num_files [llength $dump_file] + + if { $num_files != 1 } { + set testcase [lindex $args 0] + if { $num_files == 0 } { + verbose -log "$testcase: dump file does not exist" + } + + if { $num_files > 1 } { + verbose -log "$testcase: multiple dump files found" + } + + return + } + + return $dump_file +} + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump { args } { + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + + set printable_pattern [make_pattern_printable [lindex $args 1]] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + + set pattern "$dumpbase.[lindex $args 2]" + set output_file "[glob-dump-file $testcase $pattern]" + if { $output_file == "" } { + unresolved "$testname" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + if [regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is number of times the regexp must be found +# Argument 3 is the suffix for the dump file +# Argument 4 is the suffix of the dump base +# Argument 5 handles expected failures and the like +proc scan-dump-times { args } { + + if { [llength $args] >= 6 } { + switch [dg-process-target [lindex $args 5]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set times [lindex $args 2] + set suf [dump-suffix [lindex $args 3]] + set printable_pattern [make_pattern_printable [lindex $args 1]] + set testname "$testcase scan-[lindex $args 0]-dump-times $suf \"$printable_pattern\" [lindex $args 2]" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 4]] + + set pattern "$dumpbase.[lindex $args 3]" + set output_file "[glob-dump-file $testcase $pattern]" + if { $output_file == "" } { + unresolved "$testname" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + set result_count [llength [regexp -inline -all -- [lindex $args 1] $text]] + if {$result_count == $times} { + pass "$testname" + } else { + verbose -log "$testcase: pattern found $result_count times" + fail "$testname" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump-not { args } { + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set printable_pattern [make_pattern_printable [lindex $args 1]] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump-not $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + + set pattern "$dumpbase.[lindex $args 2]" + set output_file "[glob-dump-file $testcase $pattern]" + if { $output_file == "" } { + unresolved "$testname" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + + if ![regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump-dem { args } { + global cxxfilt + global base_dir + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set printable_pattern [make_pattern_printable [lindex $args 1]] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump-dem $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + + set pattern "$dumpbase.[lindex $args 2]" + set output_file "[glob-dump-file $testcase $pattern]" + if { $output_file == "" } { + unresolved "$testname" + return + } + + set fd [open "| $cxxfilt < $output_file" r] + set text [read $fd] + close $fd + + if [regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the type of dump we are searching (rtl, tree, ipa) +# Argument 1 is the regexp to match. +# Argument 2 is the suffix for the dump file +# Argument 3 is the suffix of the dump base +# Argument 4 handles expected failures and the like +proc scan-dump-dem-not { args } { + global cxxfilt + global base_dir + + if { [llength $args] >= 5 } { + switch [dg-process-target [lindex $args 4]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + # Find c++filt like we find g++ in g++.exp. + if ![info exists cxxfilt] { + set cxxfilt [findfile $base_dir/../../../binutils/cxxfilt \ + $base_dir/../../../binutils/cxxfilt \ + [findfile $base_dir/../../c++filt $base_dir/../../c++filt \ + [findfile $base_dir/c++filt $base_dir/c++filt \ + [transform c++filt]]]] + verbose -log "c++filt is $cxxfilt" + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set printable_pattern [make_pattern_printable [lindex $args 1]] + set suf [dump-suffix [lindex $args 2]] + set testname "$testcase scan-[lindex $args 0]-dump-dem-not $suf \"$printable_pattern\"" + set src [file tail $filename] + set dumpbase [dump-base $src [lindex $args 3]] + + set pattern "$dumpbase.[lindex $args 2]" + set output_file "[glob-dump-file $testcase $pattern]" + if { $output_file == "" } { + unresolved "$testname" + return + } + + set fd [open "| $cxxfilt < $output_file" r] + set text [read $fd] + close $fd + + if ![regexp -- [lindex $args 1] $text] { + pass "$testname" + } else { + fail "$testname" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanipa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanipa.exp new file mode 100644 index 0000000000000000000000000000000000000000..09bb0720d2e1fbb96df20999a957eef6ff8d29db --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanipa.exp @@ -0,0 +1,146 @@ +# Copyright (C) 2000-2022 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 +# . + +# Various utilities for scanning ipa dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped ipa pass +# Argument 3 handles expected failures and the like +proc scan-ipa-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-ipa-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-ipa-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scan-dump-times "ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" "" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-ipa-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-ipa-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ipa-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem-not "ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" "" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanlang.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanlang.exp new file mode 100644 index 0000000000000000000000000000000000000000..f090cee9ac18f723e4498e60ea37bada5b931fa0 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanlang.exp @@ -0,0 +1,96 @@ +# Copyright (C) 2000-2022 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 +# . + +# Various utilities for scanning tree dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped lang pass +# Argument 2 handles expected failures and the like +proc scan-lang-dump { args } { + + if { [llength $args] < 2 } { + error "scan-lang-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-lang-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "lang" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "lang" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 1]" "" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped tree pass +# Argument 3 handles expected failures and the like +proc scan-lang-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-lang-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-lang-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "lang" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scan-dump-times "lang" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 2]" "" + } +} + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped lang pass +# Argument 2 handles expected failures and the like +proc scan-lang-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-lang-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-lang-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "lang" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-not "lang" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]l.[lindex $args 1]" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanltranstree.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanltranstree.exp new file mode 100644 index 0000000000000000000000000000000000000000..9e783088814bafb3d468995ee93fe8f2bfe09278 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanltranstree.exp @@ -0,0 +1,148 @@ +# Copyright (C) 2000-2022 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 +# . + +# Various utilities for scanning ltrans tree dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" \ + [lindex $args 2] + } else { + scan-dump "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped tree pass +# Argument 3 handles expected failures and the like +proc scan-ltrans-tree-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-ltrans-tree-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-ltrans-tree-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "ltrans-tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" \ + ".ltrans0.ltrans" [lindex $args 3] + } else { + scan-dump-times "ltrans-tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" ".ltrans0.ltrans" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" \ + [lindex $args 2] + } else { + scan-dump-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" \ + [lindex $args 2] + } else { + scan-dump-dem "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-ltrans-tree-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-ltrans-tree-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-ltrans-tree-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \ + ".ltrans0.ltrans" [lindex $args 2] + } else { + scan-dump-dem-not "ltrans-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \ + ".ltrans0.ltrans" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffload.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffload.exp new file mode 100644 index 0000000000000000000000000000000000000000..c9c5f03ab0ee19709fd67c317a701e902e8e4e49 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffload.exp @@ -0,0 +1,61 @@ +# Copyright (C) 2020-2022 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 +# . + +# Utility for scanning offloading dump output, used by libgomp.exp. + +# Format an offload dump suffix given the offload target name in +# OFFTGT and any suffix, probably empty, in SUFFIX. +proc scoff-format { offtgt suffix } { + return ".x$offtgt.mkoffload$suffix" +} + +# Adjust an offload dump TESTNAME for offload TARGET. +proc scoff-testname { target testname } { + return "$target-$testname" +} + +# Adjust the arglist ARGS, so that argument IDX gets scoff-formatted, +# and argument 0 (the test name) gets scoff-testnamed. +proc scoff-adjust { args idx target } { + lset args $idx "[scoff-format $target [lindex $args $idx]]" + lset args 0 "[scoff-testname $target [lindex $args 0]]" + return $args +} + +# Wrapper for scan procs. +# Argument 0 is the index of the argument to replace when calling +# argument 1 with the remaining arguments. Use end-1 or end or so. +proc scoff { args } { + set idx [lindex $args 0] + set prc [lindex $args 1] + set args [lreplace $args 0 1] + + global offload_target + if [info exists offload_target] { + set target $offload_target + if { "$target" != "disable" } { + eval $prc [scoff-adjust $args $idx $target] + } + } else { + global offload_targets + foreach target [split $offload_targets ","] { + # HSA offloading is doing things differently, doesn't use 'mkoffload'. + if { "$target" == "hsa" } continue + + eval $prc [scoff-adjust $args $idx $target] + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffloadrtl.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffloadrtl.exp new file mode 100644 index 0000000000000000000000000000000000000000..36b0f1597608c8e8c0ce903a30182231303f6242 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffloadrtl.exp @@ -0,0 +1,148 @@ +# Copyright (C) 2018-2022 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 +# . + +# Various utilities for scanning offloading rtl dump output, used by +# libgomp.exp. + +load_lib scandump.exp +load_lib scanoffload.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped rtl pass +# Argument 3 handles expected failures and the like +proc scan-offload-rtl-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-offload-rtl-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-offload-rtl-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scoff end-1 scan-dump-times "offload-rtl" [lindex $args 0] \ + [lindex $args 1] "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scoff end scan-dump-times "offload-rtl" [lindex $args 0] \ + [lindex $args 1] "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 2]" "" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump-dem "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump-dem "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-offload-rtl-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-rtl-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-rtl-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump-dem-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump-dem-not "offload-rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]r.[lindex $args 1]" "" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffloadtree.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffloadtree.exp new file mode 100644 index 0000000000000000000000000000000000000000..7e77727d5d35ee56f3ce79a16677ddb06fb5f750 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanoffloadtree.exp @@ -0,0 +1,148 @@ +# Copyright (C) 2018-2022 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 +# . + +# Various utilities for scanning offloading tree dump output, used by +# libgomp.exp. + +load_lib scandump.exp +load_lib scanoffload.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped tree pass +# Argument 3 handles expected failures and the like +proc scan-offload-tree-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-offload-tree-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-offload-tree-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scoff end-1 scan-dump-times "offload-tree" [lindex $args 0] \ + [lindex $args 1] "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scoff end scan-dump-times "offload-tree" [lindex $args 0] \ + [lindex $args 1] "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 2]" "" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump-dem "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump-dem "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-offload-tree-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-offload-tree-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-offload-tree-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scoff end-1 scan-dump-dem-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scoff end scan-dump-dem-not "offload-tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9]t.[lindex $args 1]" "" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanrtl.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanrtl.exp new file mode 100644 index 0000000000000000000000000000000000000000..6790cdc32a4f896e8bd6068ddc8b431c753fdbe0 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanrtl.exp @@ -0,0 +1,156 @@ +# Copyright (C) 2006-2022 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 +# . + +# Various utilities for scanning rtl dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped rtl pass +# Argument 3 handles expected failures and the like +proc scan-rtl-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-rtl-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-rtl-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "rtl" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scan-dump-times "rtl" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 2]" "" + } +} + +force_conventional_output_for scan-rtl-dump-times + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump-not + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump-dem + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped rtl pass +# Argument 2 handles expected failures and the like +proc scan-rtl-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-rtl-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-rtl-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" \ + "" [lindex $args 2] + } else { + scan-dump-dem-not "rtl" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]r.[lindex $args 1]" "" + } +} + +force_conventional_output_for scan-rtl-dump-dem-not diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scantree.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scantree.exp new file mode 100644 index 0000000000000000000000000000000000000000..d52c99ab49741f330189d179a1614f53a88d957f --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scantree.exp @@ -0,0 +1,146 @@ +# Copyright (C) 2000-2022 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 +# . + +# Various utilities for scanning tree dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" [lindex $args 2] + } else { + scan-dump "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped tree pass +# Argument 3 handles expected failures and the like +proc scan-tree-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-tree-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-tree-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" "" \ + [lindex $args 3] + } else { + scan-dump-times "tree" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" "" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" \ + [lindex $args 2] + } else { + scan-dump-dem "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped tree pass +# Argument 2 handles expected failures and the like +proc scan-tree-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-tree-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-tree-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \ + "" [lindex $args 2] + } else { + scan-dump-dem-not "tree" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" "" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanwpaipa.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanwpaipa.exp new file mode 100644 index 0000000000000000000000000000000000000000..a2d8c6a1dfc0f7068924f106e0f51941e9b282e8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/scanwpaipa.exp @@ -0,0 +1,170 @@ +# Copyright (C) 2018-2022 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 +# . + +# Various utilities for scanning ipa dump output, used by gcc-dg.exp and +# g++-dg.exp. + +load_lib scandump.exp + +# Utility for scanning compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \ + [lindex $args 2] + } else { + scan-dump "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" + } +} + +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-pgo-wpa-ipa-dump { args } { + + if { [llength $args] < 2 } { + error "scan-pgo-wpa-ipa-dump: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-pgo-wpa-ipa-dump: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump "pgo-wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \ + [lindex $args 2] + } else { + scan-dump "pgo-wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" + } +} + +# Call pass if pattern is present given number of times, otherwise fail. +# Argument 0 is the regexp to match +# Argument 1 is number of times the regexp must be found +# Argument 2 is the name of the dumped ipa pass +# Argument 3 handles expected failures and the like +proc scan-wpa-ipa-dump-times { args } { + + if { [llength $args] < 3 } { + error "scan-wpa-ipa-dump-times: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-wpa-ipa-dump-times: too many arguments" + return + } + if { [llength $args] >= 4 } { + scan-dump-times "wpa-ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".wpa" \ + [lindex $args 3] + } else { + scan-dump-times "wpa-ipa" [lindex $args 0] [lindex $args 1] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".wpa" + } +} + +# Call pass if pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump-not { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \ + [lindex $args 2] + } else { + scan-dump-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" + } +} + +# Utility for scanning demangled compiler result, invoked via dg-final. +# Call pass if pattern is present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump-dem { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump-dem: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump-dem: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \ + [lindex $args 2] + } else { + scan-dump-dem "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" + } +} + +# Call pass if demangled pattern is not present, otherwise fail. +# +# Argument 0 is the regexp to match +# Argument 1 is the name of the dumped ipa pass +# Argument 2 handles expected failures and the like +proc scan-wpa-ipa-dump-dem-not { args } { + + if { [llength $args] < 2 } { + error "scan-wpa-ipa-dump-dem-not: too few arguments" + return + } + if { [llength $args] > 3 } { + error "scan-wpa-ipa-dump-dem-not: too many arguments" + return + } + if { [llength $args] >= 3 } { + scan-dump-dem-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \ + [lindex $args 2] + } else { + scan-dump-dem-not "wpa-ipa" [lindex $args 0] \ + "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-libpath.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-libpath.exp new file mode 100644 index 0000000000000000000000000000000000000000..d09cd515d20adf591e51f2be8f184ea8c3c46df8 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-libpath.exp @@ -0,0 +1,289 @@ +# Copyright (C) 2004-2022 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 +# . + +# This file was contributed by John David Anglin (dave.anglin@nrc-cnrc.gc.ca) + +set orig_environment_saved 0 +set orig_ld_library_path_saved 0 +set orig_ld_run_path_saved 0 +set orig_shlib_path_saved 0 +set orig_ld_library_path_32_saved 0 +set orig_ld_library_path_64_saved 0 +set orig_dyld_library_path_saved 0 +set orig_path_saved 0 +set orig_gcc_exec_prefix_saved 0 +set orig_gcc_exec_prefix_checked 0 + + +####################################### +# proc set_gcc_exec_prefix_env_var { } +####################################### + +proc set_gcc_exec_prefix_env_var { } { + global TEST_GCC_EXEC_PREFIX + global env + + # Set GCC_EXEC_PREFIX for the compiler under test to pick up files not in + # the build tree from a specified location (normally the install tree). + if [info exists TEST_GCC_EXEC_PREFIX] { + setenv GCC_EXEC_PREFIX "$TEST_GCC_EXEC_PREFIX" + } +} + +####################################### +# proc set_ld_library_path_env_vars { } +####################################### + +proc set_ld_library_path_env_vars { } { + global ld_library_path + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_gcc_exec_prefix_saved + global orig_gcc_exec_prefix_checked + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + global orig_gcc_exec_prefix + global env + + # Save the original GCC_EXEC_PREFIX. + if { $orig_gcc_exec_prefix_checked == 0 } { + if [info exists env(GCC_EXEC_PREFIX)] { + set orig_gcc_exec_prefix "$env(GCC_EXEC_PREFIX)" + set orig_gcc_exec_prefix_saved 1 + } + set orig_gcc_exec_prefix_checked 1 + } + + set_gcc_exec_prefix_env_var + + # Setting the ld library path causes trouble when testing cross-compilers. + if { [is_remote target] } { + return + } + + if { $orig_environment_saved == 0 } { + set orig_environment_saved 1 + + # Save the original environment. + if [info exists env(LD_LIBRARY_PATH)] { + set orig_ld_library_path "$env(LD_LIBRARY_PATH)" + set orig_ld_library_path_saved 1 + } + if [info exists env(LD_RUN_PATH)] { + set orig_ld_run_path "$env(LD_RUN_PATH)" + set orig_ld_run_path_saved 1 + } + if [info exists env(SHLIB_PATH)] { + set orig_shlib_path "$env(SHLIB_PATH)" + set orig_shlib_path_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_32)] { + set orig_ld_library_path_32 "$env(LD_LIBRARY_PATH_32)" + set orig_ld_library_path_32_saved 1 + } + if [info exists env(LD_LIBRARY_PATH_64)] { + set orig_ld_library_path_64 "$env(LD_LIBRARY_PATH_64)" + set orig_ld_library_path_64_saved 1 + } + if [info exists env(DYLD_LIBRARY_PATH)] { + set orig_dyld_library_path "$env(DYLD_LIBRARY_PATH)" + set orig_dyld_library_path_saved 1 + } + if [info exists env(PATH)] { + set orig_path "$env(PATH)" + set orig_path_saved 1 + } + } + + # We need to set ld library path in the environment. Currently, + # unix.exp doesn't set the environment correctly for all systems. + # It only sets SHLIB_PATH and LD_LIBRARY_PATH when it executes a + # program. We also need the environment set for compilations, etc. + # + # On Darwin, we have to set variables akin to LD_LIBRARY_PATH, but called + # DYLD_LIBRARY_PATH. The same applies to Solaris 32 bit + # (LD_LIBRARY_PATH_32), Solaris 64 bit (LD_LIBRARY_PATH_64), and HP-UX + # (SHLIB_PATH). In some cases, the variables are independent of + # LD_LIBRARY_PATH, and in other cases LD_LIBRARY_PATH is used if the + # variable is not defined. + # + # Doing this is somewhat of a hack as ld_library_path gets repeated in + # SHLIB_PATH and LD_LIBRARY_PATH when unix_load sets these variables. + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH "$ld_library_path" + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$ld_library_path:$orig_ld_run_path" + } else { + setenv LD_RUN_PATH "$ld_library_path" + } + # The default shared library dynamic path search for 64-bit + # HP-UX executables searches LD_LIBRARY_PATH before SHLIB_PATH. + # LD_LIBRARY_PATH isn't used for 32-bit executables. Thus, we + # set LD_LIBRARY_PATH and SHLIB_PATH as if they were independent. + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$ld_library_path:$orig_shlib_path" + } else { + setenv SHLIB_PATH "$ld_library_path" + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path_32" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_32 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_32 "$ld_library_path" + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path_64" + } elseif { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH_64 "$ld_library_path:$orig_ld_library_path" + } else { + setenv LD_LIBRARY_PATH_64 "$ld_library_path" + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$ld_library_path:$orig_dyld_library_path" + } else { + setenv DYLD_LIBRARY_PATH "$ld_library_path" + } + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + if { $orig_path_saved } { + setenv PATH "$ld_library_path:$orig_path" + } else { + setenv PATH "$ld_library_path" + } + } + + verbose -log "LD_LIBRARY_PATH=[getenv LD_LIBRARY_PATH]" + verbose -log "LD_RUN_PATH=[getenv LD_RUN_PATH]" + verbose -log "SHLIB_PATH=[getenv SHLIB_PATH]" + verbose -log "LD_LIBRARY_PATH_32=[getenv LD_LIBRARY_PATH_32]" + verbose -log "LD_LIBRARY_PATH_64=[getenv LD_LIBRARY_PATH_64]" + verbose -log "DYLD_LIBRARY_PATH=[getenv DYLD_LIBRARY_PATH]" +} + +####################################### +# proc restore_gcc_exec_prefix_env_var { } +####################################### + +proc restore_gcc_exec_prefix_env_var { } { + global orig_gcc_exec_prefix_saved + global orig_gcc_exec_prefix + global env + + if { $orig_gcc_exec_prefix_saved } { + setenv GCC_EXEC_PREFIX "$orig_gcc_exec_prefix" + } elseif [info exists env(GCC_EXEC_PREFIX)] { + unsetenv GCC_EXEC_PREFIX + } +} + +####################################### +# proc restore_ld_library_path_env_vars { } +####################################### + +proc restore_ld_library_path_env_vars { } { + global orig_environment_saved + global orig_ld_library_path_saved + global orig_ld_run_path_saved + global orig_shlib_path_saved + global orig_ld_library_path_32_saved + global orig_ld_library_path_64_saved + global orig_dyld_library_path_saved + global orig_path_saved + global orig_ld_library_path + global orig_ld_run_path + global orig_shlib_path + global orig_ld_library_path_32 + global orig_ld_library_path_64 + global orig_dyld_library_path + global orig_path + global env + + restore_gcc_exec_prefix_env_var + + if { $orig_environment_saved == 0 } { + return + } + + if { $orig_ld_library_path_saved } { + setenv LD_LIBRARY_PATH "$orig_ld_library_path" + } elseif [info exists env(LD_LIBRARY_PATH)] { + unsetenv LD_LIBRARY_PATH + } + if { $orig_ld_run_path_saved } { + setenv LD_RUN_PATH "$orig_ld_run_path" + } elseif [info exists env(LD_RUN_PATH)] { + unsetenv LD_RUN_PATH + } + if { $orig_shlib_path_saved } { + setenv SHLIB_PATH "$orig_shlib_path" + } elseif [info exists env(SHLIB_PATH)] { + unsetenv SHLIB_PATH + } + if { $orig_ld_library_path_32_saved } { + setenv LD_LIBRARY_PATH_32 "$orig_ld_library_path_32" + } elseif [info exists env(LD_LIBRARY_PATH_32)] { + unsetenv LD_LIBRARY_PATH_32 + } + if { $orig_ld_library_path_64_saved } { + setenv LD_LIBRARY_PATH_64 "$orig_ld_library_path_64" + } elseif [info exists env(LD_LIBRARY_PATH_64)] { + unsetenv LD_LIBRARY_PATH_64 + } + if { $orig_dyld_library_path_saved } { + setenv DYLD_LIBRARY_PATH "$orig_dyld_library_path" + } elseif [info exists env(DYLD_LIBRARY_PATH)] { + unsetenv DYLD_LIBRARY_PATH + } + if { $orig_path_saved } { + setenv PATH "$orig_path" + } elseif [info exists env(PATH)] { + unsetenv PATH + } +} + +####################################### +# proc get_shlib_extension { } +####################################### + +proc get_shlib_extension { } { + global shlib_ext + + if { [istarget *-*-darwin*] } { + set shlib_ext "dylib" + } elseif { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + set shlib_ext "dll" + } elseif { [istarget hppa*-*-hpux*] } { + set shlib_ext "sl" + } else { + set shlib_ext "so" + } + return $shlib_ext +} + diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-supports-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-supports-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..aa2164bc78981477eb18577cc7268add58f10369 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-supports-dg.exp @@ -0,0 +1,685 @@ +# Copyright (C) 1997-2022 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 +# . + +# DejaGnu's dg-test defines extra flags that are used to compile a test. +# Access them for directives that need to examine all options that are +# used for a test, including checks for non-cached effective targets. +# We don't know how far up the call chain it is but we know we'll hit +# it eventually, and that we're at least 3 calls down. + +proc current_compiler_flags { } { + set frames 2 + while { ![info exists flags1] } { + set frames [expr $frames + 1] + upvar $frames dg-extra-tool-flags flags1 + } + upvar $frames tool_flags flags2 + return "$flags1 $flags2" +} + +# DejaGnu's dg-test defines a test name that includes torture options +# which is used in most pass/fail messages. Grab a copy of it. + +proc testname-for-summary { } { + global testname_with_flags + + # A variable called "name" is too generic, so identify dg-test by + # the existence of dg-extra-tool-flags. + if ![info exists testname_with_flags] { + set frames 2 + while { ![info exists flags] } { + set frames [expr $frames + 1] + upvar $frames dg-extra-tool-flags flags + } + + # We've got the stack level for dg-test; get the variable we want. + upvar $frames name name + set testname_with_flags $name + + # If there are flags, add an extra space to improve readability of + # the test summary. + if { [llength $testname_with_flags] > 1 } { + set testname_with_flags "$testname_with_flags " + } + } + return "$testname_with_flags" +} + +# If this target does not support weak symbols, skip this test. + +proc dg-require-weak { args } { + set weak_available [ check_weak_available ] + if { $weak_available == -1 } { + upvar name name + unresolved "$name" + } + if { $weak_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support overriding weak symbols, skip this +# test. + +proc dg-require-weak-override { args } { + set weak_override_available [ check_weak_override_available ] + if { $weak_override_available == -1 } { + upvar name name + unresolved "$name" + } + if { $weak_override_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "visibility" attribute, skip this +# test. + +proc dg-require-visibility { args } { + set visibility_available [ check_visibility_available [lindex $args 1 ] ] + if { $visibility_available == -1 } { + upvar name name + unresolved "$name" + } + if { $visibility_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "alias" attribute, skip this +# test. + +proc dg-require-alias { args } { + set alias_available [ check_alias_available ] + if { $alias_available == -1 } { + upvar name name + unresolved "$name" + } + if { $alias_available < 2 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "ifunc" attribute, skip this +# test. + +proc dg-require-ifunc { args } { + if { ![ check_ifunc_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target's linker does not support the --gc-sections flag, +# skip this test. + +proc dg-require-gc-sections { args } { + if { ![ check_gc_sections_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support profiling, skip this test. + +proc dg-require-profiling { args } { + if { ![ check_profiling_available [lindex $args 1] ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support DLL attributes skip this test. + +proc dg-require-dll { args } { + # As a special case, the mcore-*-elf supports these attributes. + # All Symbian OS targets also support these attributes. + if { [istarget mcore-*-elf] + || [istarget *-*-symbianelf] } { + return + } + # PE/COFF targets support dllimport/dllexport. + if { [gcc_target_object_format] == "pe" } { + return + } + + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] +} + +# If this host does not support an ASCII locale, skip this test. + +proc dg-require-ascii-locale { args } { + if { ![ check_ascii_locale_available] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +proc dg-require-iconv { args } { + if { ![ check_iconv_available ${args} ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this host does not have "dot", skip this test. + +proc dg-require-dot { args } { + verbose "dg-require-dot" 2 + if { ![ check_dot_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not have sufficient stack size, skip this test. + +proc dg-require-stack-size { args } { + if { ![is-effective-target stack_size] } { + return + } + + set stack_size [dg-effective-target-value stack_size] + set required [expr [lindex $args 1]] + if { $stack_size < $required } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support named sections skip this test. + +proc dg-require-named-sections { args } { + if { ![ check_named_sections_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If the target does not match the required effective target, skip this test. +# Only apply this if the optional selector matches. + +proc dg-require-effective-target { args } { + set args [lreplace $args 0 0] + # Verify the number of arguments. The last is optional. + if { [llength $args] < 1 || [llength $args] > 2 } { + error "syntax error, need a single effective-target keyword with optional selector" + } + + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + # Evaluate selector if present. + if { [llength $args] == 2 } { + switch [dg-process-target-1 [lindex $args 1]] { + "S" { } + "N" { return } + } + } + + if { ![is-effective-target [lindex $args 0]] } { + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not have fork, skip this test. + +proc dg-require-fork { args } { + if { ![check_fork_available] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not have mkfifo, skip this test. + +proc dg-require-mkfifo { args } { + if { ![check_mkfifo_available] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not use __cxa_atexit, skip this test. + +proc dg-require-cxa-atexit { args } { + if { ![ check_cxa_atexit_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If the host is remote rather than the same as the build system, skip +# this test. Some tests are incompatible with DejaGnu's handling of +# remote hosts, which involves copying the source file to the host and +# compiling it with a relative path and "-o a.out". + +proc dg-require-host-local { args } { + if [ is_remote host ] { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +proc dg-require-linker-plugin { args } { + set linker_plugin_available [ check_linker_plugin_available ] + if { $linker_plugin_available == 0 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# If this target does not support the "stack-check" option, skip this +# test. + +proc dg-require-stack-check { args } { + set stack_check_available [ check_stack_check_available [lindex $args 1 ] ] + if { $stack_check_available == -1 } { + upvar name name + unresolved "$name" + } + if { $stack_check_available != 1 } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} + +# Add any target-specific flags needed for accessing the given list +# of features. This must come after all dg-options. + +proc dg-add-options { args } { + upvar dg-extra-tool-flags extra-tool-flags + + foreach arg [lrange $args 1 end] { + if { [info procs add_options_for_$arg] != "" } { + set extra-tool-flags \ + [eval [list add_options_for_$arg ${extra-tool-flags}]] + } else { + error "Unrecognized option type: $arg" + } + } +} + +# Compare flags for a test directive against flags that will be used to +# compile the test: multilib flags, flags for torture options, and either +# the default flags for this group of tests or flags specified with a +# previous dg-options directive. + +proc check-flags { args } { + global compiler_flags + global TOOL_OPTIONS + global TEST_ALWAYS_FLAGS + + # The args are within another list; pull them out. + set args [lindex $args 0] + + # Start the list with a dummy tool name so the list will match "*" + # if there are no flags. + set compiler_flags " toolname " + append compiler_flags [current_compiler_flags] + # If running a subset of the test suite, $TOOL_OPTIONS may not exist. + catch {append compiler_flags " $TOOL_OPTIONS "} + # If running a subset of the test suite, $TEST_ALWAYS_FLAGS may not exist. + catch {append compiler_flags " $TEST_ALWAYS_FLAGS "} + set dest [target_info name] + if [board_info $dest exists cflags] { + append compiler_flags "[board_info $dest cflags] " + } + if [board_info $dest exists multilib_flags] { + append compiler_flags "[board_info $dest multilib_flags] " + } + + # The next two arguments are optional. If they were not specified, + # use the defaults. + if { [llength $args] == 2 } { + lappend $args [list "*"] + } + if { [llength $args] == 3 } { + lappend $args [list ""] + } + + # If the option strings are the defaults, or the same as the + # defaults, there is no need to call check_conditional_xfail to + # compare them to the actual options. + if { [string compare [lindex $args 2] "*"] == 0 + && [string compare [lindex $args 3] "" ] == 0 } { + set result 1 + } else { + # The target list might be an effective-target keyword, so replace + # the original list with "*-*-*", since we already know it matches. + set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]] + } + + # Any value in this variable was left over from an earlier test. + set compiler_flags "" + + return $result +} + +# Skip the test (report it as UNSUPPORTED) if the target list and +# included flags are matched and the excluded flags are not matched. +# +# The first argument is the line number of the dg-skip-if directive +# within the test file. Remaining arguments are as for xfail lists: +# message { targets } { include } { exclude } +# +# This tests against multilib flags plus either the default flags for this +# group of tests or flags specified with a previous dg-options command. + +proc dg-skip-if { args } { + # Verify the number of arguments. The last two are optional. + set args [lreplace $args 0 0] + if { [llength $args] < 2 || [llength $args] > 4 } { + error "dg-skip-if 2: need 2, 3, or 4 arguments" + } + + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + if [check-flags $args] { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } + } +} + +# Like check_conditional_xfail, but callable from a dg test. + +proc dg-xfail-if { args } { + # Verify the number of arguments. The last three are optional. + set args [lreplace $args 0 0] + if { [llength $args] < 2 || [llength $args] > 4 } { + error "dg-xfail-if: need 2, 3, or 4 arguments" + } + + # Don't change anything if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + global compiler_conditional_xfail_data + + # The target list might be an effective-target keyword. Replace + # the original list with "*-*-*", since we already know it matches. + set args [lreplace $args 1 1 "*-*-*"] + + # Supply default values for unspecified optional arguments. + if { [llength $args] == 2 } { + lappend $args [list "*"] + } + if { [llength $args] == 3 } { + lappend $args [list ""] + } + + set compiler_conditional_xfail_data $args + } +} + +# Like dg-xfail-if but for the execute step. + +proc dg-xfail-run-if { args } { + # Verify the number of arguments. The last two are optional. + set args [lreplace $args 0 0] + if { [llength $args] < 2 || [llength $args] > 4 } { + error "dg-xfail-run-if: need 2, 3, or 4 arguments" + } + + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + if [check-flags $args] { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "S" "F"] + } + } +} + +# Record whether the program is expected to return a nonzero status. + +set shouldfail 0 + +proc dg-shouldfail { args } { + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + global shouldfail + + set args [lreplace $args 0 0] + if { [llength $args] > 1 } { + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + # The target matches, now check the flags. + if [check-flags $args] { + set shouldfail 1 + } + } + } else { + set shouldfail 1 + } +} + +# Record whether the compiler is expected (at the moment) to ICE. +# Used for tests that test bugs that have not been fixed yet. + +set expect_ice 0 + +proc dg-ice { args } { + # Don't bother if we're already skipping the test. + upvar dg-do-what dg-do-what + if { [lindex ${dg-do-what} 1] == "N" } { + return + } + + global expect_ice + + set args [lreplace $args 0 0] + if { [llength $args] > 1 } { + set selector [list target [lindex $args 1]] + if { [dg-process-target-1 $selector] == "S" } { + # The target matches, now check the flags. + if [check-flags $args] { + set expect_ice 1 + } + } + } else { + set expect_ice 1 + } +} + +# Intercept the call to the DejaGnu version of dg-process-target to +# support use of an effective-target keyword in place of a list of +# target triplets to xfail or skip a test. +# +# The argument to dg-process-target is the keyword "target" or "xfail" +# followed by a selector: +# target-triplet-1 ... +# effective-target-keyword +# selector-expression +# +# For a target list the result is "S" if the target is selected, "N" otherwise. +# For an xfail list the result is "F" if the target is affected, "P" otherwise. + +# In contexts that allow either "target" or "xfail" the argument can be +# target selector1 xfail selector2 +# which returns "N" if selector1 is not selected, otherwise the result of +# "xfail selector2". +# +# A selector expression appears within curly braces and uses a single logical +# operator: !, &&, or ||. An operand is another selector expression, an +# effective-target keyword, or a list of target triplets within quotes or +# curly braces. + +if { [info procs saved-dg-process-target] == [list] } { + rename dg-process-target saved-dg-process-target + + # Evaluate an operand within a selector expression. + proc selector_opd { op } { + set selector "target" + lappend selector $op + set answer [ expr { [dg-process-target $selector] == "S" } ] + verbose "selector_opd: `$op' $answer" 2 + return $answer + } + + # Evaluate a target triplet list within a selector expression. + # Unlike other operands, this needs to be expanded from a list to + # the same string as "target". + proc selector_list { op } { + set selector "target [join $op]" + set answer [ expr { [dg-process-target $selector] == "S" } ] + verbose "selector_list: `$op' $answer" 2 + return $answer + } + + # Evaluate a selector expression. + proc selector_expression { exp } { + if { [llength $exp] >= 2 + && [string match "any-opts" [lindex $exp 0]] } { + set args [list "" { *-*-* } [lrange $exp 1 end] ""] + set answer [check_conditional_xfail $args] + } elseif { [llength $exp] >= 2 + && [string match "no-opts" [lindex $exp 0]] } { + set args [list "" { *-*-* } "*" [lrange $exp 1 end]] + set answer [check_conditional_xfail $args] + } elseif { [llength $exp] == 2 } { + if [string match "!" [lindex $exp 0]] { + set op1 [lindex $exp 1] + set answer [expr { ! [selector_opd $op1] }] + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + } elseif { [llength $exp] == 3 } { + set op1 [lindex $exp 0] + set opr [lindex $exp 1] + set op2 [lindex $exp 2] + if [string match "&&" $opr] { + set answer [expr { [selector_opd $op1] && [selector_opd $op2] }] + } elseif [string match "||" $opr] { + set answer [expr { [selector_opd $op1] || [selector_opd $op2] }] + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + } else { + # Assume it's a list of target triplets. + set answer [selector_list $exp] + } + + verbose "selector_expression: `$exp' $answer" 2 + return $answer + } + + # Evaluate "target selector" or "xfail selector". + + proc dg-process-target-1 { args } { + verbose "dg-process-target-1: `$args'" 2 + + # Extract the 'what' keyword from the argument list. + set selector [string trim [lindex $args 0]] + if [regexp "^xfail " $selector] { + set what "xfail" + } elseif [regexp "^target " $selector] { + set what "target" + } else { + error "syntax error in target selector \"$selector\"" + } + + # Extract the rest of the list, which might be a keyword. + regsub "^${what}" $selector "" rest + set rest [string trim $rest] + + if [is-effective-target-keyword $rest] { + # The selector is an effective target keyword. + if [is-effective-target $rest] { + return [expr { $what == "xfail" ? "F" : "S" }] + } else { + return [expr { $what == "xfail" ? "P" : "N" }] + } + } + + if [string match "{*}" $rest] { + if [selector_expression [lindex $rest 0]] { + return [expr { $what == "xfail" ? "F" : "S" }] + } else { + return [expr { $what == "xfail" ? "P" : "N" }] + } + } + + # The selector is not an effective-target keyword, so process + # the list of target triplets. + return [saved-dg-process-target $selector] + } + + # Intercept calls to the DejaGnu function. In addition to + # processing "target selector" or "xfail selector", handle + # "target selector1 xfail selector2". + + proc dg-process-target { args } { + verbose "replacement dg-process-target: `$args'" 2 + + set selector [string trim [lindex $args 0]] + + # If the argument list contains both 'target' and 'xfail', + # process 'target' and, if that succeeds, process 'xfail'. + if [regexp "^target .* xfail .*" $selector] { + set xfail_index [string first "xfail" $selector] + set xfail_selector [string range $selector $xfail_index end] + set target_selector [string range $selector 0 [expr $xfail_index-1]] + set target_selector [string trim $target_selector] + if { [dg-process-target-1 $target_selector] == "N" } { + return "N" + } + return [dg-process-target-1 $xfail_selector] + + } + return [dg-process-target-1 $selector] + } +} + +# If this target does not support the "symver" attribute, skip this +# test. + +proc dg-require-symver { args } { + if { ![ check_symver_available ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-supports.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-supports.exp new file mode 100644 index 0000000000000000000000000000000000000000..bd89d4f52294313633afdd14e2523be9d7ff882d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-supports.exp @@ -0,0 +1,11926 @@ +# Copyright (C) 1999-2022 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 +# . + +# Please email any bugs, comments, and/or additions to this file to: +# gcc-patches@gcc.gnu.org + +# This file defines procs for determining features supported by the target. + +# Try to compile the code given by CONTENTS into an output file of +# type TYPE, where TYPE is as for target_compile. Return a list +# whose first element contains the compiler messages and whose +# second element is the name of the output file. +# +# BASENAME is a prefix to use for source and output files. +# If ARGS is not empty, its first element is a string that +# should be added to the command line. +# +# Assume by default that CONTENTS is C code. +# Otherwise, code should contain: +# "/* Assembly" for assembly code, +# "// C++" for c++, +# "// D" for D, +# "! Fortran" for Fortran code, +# "/* ObjC", for ObjC +# "// ObjC++" for ObjC++ +# and "// Go" for Go +# If the tool is ObjC/ObjC++ then we overide the extension to .m/.mm to +# allow for ObjC/ObjC++ specific flags. + +proc check_compile {basename type contents args} { + global tool + verbose "check_compile tool: $tool for $basename" + + # Save additional_sources to avoid compiling testsuite's sources + # against check_compile's source. + global additional_sources + if [info exists additional_sources] { + set tmp_additional_sources "$additional_sources" + set additional_sources "" + } + + if { [llength $args] > 0 } { + set options [list "additional_flags=[lindex $args 0]"] + } else { + set options "" + } + switch -glob -- $contents { + "*/* Assembly*" { set src ${basename}[pid].S } + "*! Fortran*" { set src ${basename}[pid].f90 } + "*// C++*" { set src ${basename}[pid].cc } + "*// D*" { set src ${basename}[pid].d } + "*// ObjC++*" { set src ${basename}[pid].mm } + "*/* ObjC*" { set src ${basename}[pid].m } + "*// Go*" { set src ${basename}[pid].go } + default { + switch -- $tool { + "objc" { set src ${basename}[pid].m } + "obj-c++" { set src ${basename}[pid].mm } + default { set src ${basename}[pid].c } + } + } + } + + set compile_type $type + switch -glob $type { + assembly { set output ${basename}[pid].s } + object { set output ${basename}[pid].o } + executable { set output ${basename}[pid].exe } + "rtl-*" { + set output ${basename}[pid].s + lappend options "additional_flags=-fdump-$type" + set compile_type assembly + } + } + set f [open $src "w"] + puts $f $contents + close $f + global compiler_flags + set save_compiler_flags $compiler_flags + set lines [${tool}_target_compile $src $output $compile_type "$options"] + set compiler_flags $save_compiler_flags + file delete $src + + set scan_output $output + # Don't try folding this into the switch above; calling "glob" before the + # file is created won't work. + if [regexp "rtl-(.*)" $type dummy rtl_type] { + set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]" + file delete $output + } + + # Restore additional_sources. + if [info exists additional_sources] { + set additional_sources "$tmp_additional_sources" + } + + return [list $lines $scan_output] +} + +proc current_target_name { } { + global target_info + if [info exists target_info(target,name)] { + set answer $target_info(target,name) + } else { + set answer "" + } + return $answer +} + +# Implement an effective-target check for property PROP by invoking +# the Tcl command ARGS and seeing if it returns true. + +proc check_cached_effective_target { prop args } { + global et_cache + + set target [current_target_name] + if {![info exists et_cache($prop,$target)]} { + verbose "check_cached_effective_target $prop: checking $target" 2 + if {[string is true -strict $args] || [string is false -strict $args]} { + error {check_cached_effective_target condition already evaluated; did you pass [...] instead of the expected {...}?} + } else { + set code [catch {uplevel eval $args} result] + if {$code != 0 && $code != 2} { + return -code $code $result + } + set et_cache($prop,$target) $result + } + } + set value $et_cache($prop,$target) + verbose "check_cached_effective_target $prop: returning $value for $target" 2 + return $value +} + +# Implements a version of check_cached_effective_target that also takes et_index +# into account when creating the key for the cache. +proc check_cached_effective_target_indexed { prop args } { + global et_index + set key "$et_index $prop" + verbose "check_cached_effective_target_index $prop: returning $key" 2 + + return [check_cached_effective_target $key [list uplevel eval $args]] +} + +# Clear effective-target cache. This is useful after testing +# effective-target features and overriding TEST_ALWAYS_FLAGS and/or +# ALWAYS_CXXFLAGS. +# If one changes ALWAYS_CXXFLAGS or TEST_ALWAYS_FLAGS then they should +# do a clear_effective_target_cache at the end as the target cache can +# make decisions based upon the flags, and those decisions need to be +# redone when the flags change. An example of this is the +# asan_init/asan_finish pair. + +proc clear_effective_target_cache { } { + global et_cache + array unset et_cache +} + +# Like check_compile, but delete the output file and return true if the +# compiler printed no messages. +proc check_no_compiler_messages_nocache {args} { + set result [eval check_compile $args] + set lines [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $output + return [string match "" $lines] +} + +# Like check_no_compiler_messages_nocache, but cache the result. +# PROP is the property we're checking, and doubles as a prefix for +# temporary filenames. +proc check_no_compiler_messages {prop args} { + return [check_cached_effective_target $prop { + eval [list check_no_compiler_messages_nocache $prop] $args + }] +} + +# Like check_compile, but return true if the compiler printed no +# messages and if the contents of the output file satisfy PATTERN. +# If PATTERN has the form "!REGEXP", the contents satisfy it if they +# don't match regular expression REGEXP, otherwise they satisfy it +# if they do match regular expression PATTERN. (PATTERN can start +# with something like "[!]" if the regular expression needs to match +# "!" as the first character.) +# +# Delete the output file before returning. The other arguments are +# as for check_compile. +proc check_no_messages_and_pattern_nocache {basename pattern args} { + global tool + + set result [eval [list check_compile $basename] $args] + set lines [lindex $result 0] + set output [lindex $result 1] + + set ok 0 + if { [string match "" $lines] } { + set chan [open "$output"] + set invert [regexp {^!(.*)} $pattern dummy pattern] + set ok [expr { [regexp $pattern [read $chan]] != $invert }] + close $chan + } + + remote_file build delete $output + return $ok +} + +# Like check_no_messages_and_pattern_nocache, but cache the result. +# PROP is the property we're checking, and doubles as a prefix for +# temporary filenames. +proc check_no_messages_and_pattern {prop pattern args} { + return [check_cached_effective_target $prop { + eval [list check_no_messages_and_pattern_nocache $prop $pattern] $args + }] +} + +# Try to compile and run an executable from code CONTENTS. Return true +# if the compiler reports no messages and if execution "passes" in the +# usual DejaGNU sense. The arguments are as for check_compile, with +# TYPE implicitly being "executable". +proc check_runtime_nocache {basename contents args} { + global tool + + set result [eval [list check_compile $basename executable $contents] $args] + set lines [lindex $result 0] + set output [lindex $result 1] + + set ok 0 + if { [string match "" $lines] } { + # No error messages, everything is OK. + set result [remote_load target "./$output" "" ""] + set status [lindex $result 0] + verbose "check_runtime_nocache $basename: status is <$status>" 2 + if { $status == "pass" } { + set ok 1 + } + } + remote_file build delete $output + return $ok +} + +# Like check_runtime_nocache, but cache the result. PROP is the +# property we're checking, and doubles as a prefix for temporary +# filenames. +proc check_runtime {prop args} { + global tool + + return [check_cached_effective_target $prop { + eval [list check_runtime_nocache $prop] $args + }] +} + +# Return 1 if GCC was configured with $pattern. +proc check_configured_with { pattern } { + global tool + + set options [list "additional_flags=-v"] + set gcc_output [${tool}_target_compile "" "" "none" $options] + if { [ regexp "Configured with: \[^\n\]*$pattern" $gcc_output ] } { + verbose "Matched: $pattern" 2 + return 1 + } + + verbose "Failed to match: $pattern" 2 + return 0 +} + +############################### +# proc check_weak_available { } +############################### + +# weak symbols are only supported in some configs/object formats +# this proc returns 1 if they're supported, 0 if they're not, or -1 if unsure + +proc check_weak_available { } { + global target_cpu + + # All mips targets should support it + + if { [ string first "mips" $target_cpu ] >= 0 } { + return 1 + } + + # All AIX targets should support it + + if { [istarget *-*-aix*] } { + return 1 + } + + # All solaris2 targets should support it + + if { [istarget *-*-solaris2*] } { + return 1 + } + + # Windows targets Cygwin and MingW32 support it + + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + return 1 + } + + # HP-UX 10.X doesn't support it + + if { [istarget hppa*-*-hpux10*] } { + return 0 + } + + # nvptx (nearly) supports it + + if { [istarget nvptx-*-*] } { + return 1 + } + + # pdp11 doesn't support it + + if { [istarget pdp11*-*-*] } { + return 0 + } + + # VxWorks hardly supports it (vx7 RTPs only) + + if { [istarget *-*-vxworks*] } { + return 0 + } + + # ELF and ECOFF support it. a.out does with gas/gld but may also with + # other linkers, so we should try it + + set objformat [gcc_target_object_format] + + switch $objformat { + elf { return 1 } + ecoff { return 1 } + a.out { return 1 } + mach-o { return 1 } + som { return 1 } + unknown { return -1 } + default { return 0 } + } +} + +# return 1 if weak undefined symbols are supported. + +proc check_effective_target_weak_undefined { } { + if { [istarget hppa*-*-hpux*] } { + return 0 + } + return [check_runtime weak_undefined { + extern void foo () __attribute__((weak)); + int main (void) { if (foo) return 1; return 0; } + } ""] +} + +############################### +# proc check_weak_override_available { } +############################### + +# Like check_weak_available, but return 0 if weak symbol definitions +# cannot be overridden. + +proc check_weak_override_available { } { + if { [istarget *-*-mingw*] } { + return 0 + } + return [check_weak_available] +} + +# The "noinit" attribute is only supported by some targets. +# This proc returns 1 if it's supported, 0 if it's not. + +proc check_effective_target_noinit { } { + if { [istarget arm*-*-eabi] + || [istarget msp430-*-*] } { + return 1 + } + + return 0 +} + +# The "persistent" attribute is only supported by some targets. +# This proc returns 1 if it's supported, 0 if it's not. + +proc check_effective_target_persistent { } { + if { [istarget arm*-*-eabi] + || [istarget msp430-*-*] } { + return 1 + } + + return 0 +} + +############################### +# proc check_visibility_available { what_kind } +############################### + +# The visibility attribute is only support in some object formats +# This proc returns 1 if it is supported, 0 if not. +# The argument is the kind of visibility, default/protected/hidden/internal. + +proc check_visibility_available { what_kind } { + if [string match "" $what_kind] { set what_kind "hidden" } + + return [check_no_compiler_messages visibility_available_$what_kind object " + void f() __attribute__((visibility(\"$what_kind\"))); + void f() {} + "] +} + +############################### +# proc check_alias_available { } +############################### + +# Determine if the target toolchain supports the alias attribute. + +# Returns 2 if the target supports aliases. Returns 1 if the target +# only supports weak aliased. Returns 0 if the target does not +# support aliases at all. Returns -1 if support for aliases could not +# be determined. + +proc check_alias_available { } { + global tool + + return [check_cached_effective_target alias_available { + set src alias[pid].c + set obj alias[pid].o + verbose "check_alias_available compiling testfile $src" 2 + set f [open $src "w"] + # Compile a small test program. The definition of "g" is + # necessary to keep the Solaris assembler from complaining + # about the program. + puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n" + puts $f "void g() {} void f() __attribute__((alias(\"g\")));" + close $f + set lines [${tool}_target_compile $src $obj object ""] + file delete $src + remote_file build delete $obj + + if [string match "" $lines] then { + # No error messages, everything is OK. + return 2 + } else { + if [regexp "alias definitions not supported" $lines] { + verbose "check_alias_available target does not support aliases" 2 + + set objformat [gcc_target_object_format] + + if { $objformat == "elf" } { + verbose "check_alias_available but target uses ELF format, so it ought to" 2 + return -1 + } else { + return 0 + } + } else { + if [regexp "only weak aliases are supported" $lines] { + verbose "check_alias_available target supports only weak aliases" 2 + return 1 + } else { + return -1 + } + } + } + }] +} + +# Returns 1 if the target toolchain supports strong aliases, 0 otherwise. + +proc check_effective_target_alias { } { + if { [check_alias_available] < 2 } { + return 0 + } else { + return 1 + } +} + +# Returns 1 if the target toolchain supports ifunc, 0 otherwise. + +proc check_ifunc_available { } { + return [check_no_compiler_messages ifunc_available object { + #ifdef __cplusplus + extern "C" { + #endif + extern void f_ (); + typedef void F (void); + F* g (void) { return &f_; } + void f () __attribute__ ((ifunc ("g"))); + #ifdef __cplusplus + } + #endif + }] +} + +# Returns true if --gc-sections is supported on the target. + +proc check_gc_sections_available { } { + global tool + + return [check_cached_effective_target gc_sections_available { + # Some targets don't support gc-sections despite whatever's + # advertised by ld's options. + if { [istarget alpha*-*-*] + || [istarget ia64-*-*] } { + return 0 + } + + # elf2flt uses -q (--emit-relocs), which is incompatible with + # --gc-sections. + if { [board_info target exists ldflags] + && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } { + return 0 + } + + # VxWorks kernel modules are relocatable objects linked with -r, + # while RTP executables are linked with -q (--emit-relocs). + # Both of these options are incompatible with --gc-sections. + if { [istarget *-*-vxworks*] } { + return 0 + } + + # Check if the ld used by gcc supports --gc-sections. + set options [list "additional_flags=-print-prog-name=ld"] + set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0] + set ld_output [remote_exec host "$gcc_ld" "--help"] + if { [ string first "--gc-sections" $ld_output ] >= 0 } { + return 1 + } else { + return 0 + } + }] +} + +# Returns 1 if "dot" is supported on the host. + +proc check_dot_available { } { + verbose "check_dot_available" 2 + + set status [remote_exec host "dot" "-V"] + verbose " status: $status" 2 + if { [lindex $status 0] != 0 } { + return 0 + } + return 1 +} + +# Return 1 if according to target_info struct and explicit target list +# target is supposed to support trampolines. + +proc check_effective_target_trampolines { } { + if [target_info exists gcc,no_trampolines] { + return 0 + } + if { [istarget avr-*-*] + || [istarget msp430-*-*] + || [istarget nvptx-*-*] + || [istarget hppa2.0w-hp-hpux11.23] + || [istarget hppa64-hp-hpux11.23] + || [istarget pru-*-*] + || [istarget bpf-*-*] } { + return 0; + } + return 1 +} + +# Return 1 if target has limited stack size. + +proc check_effective_target_stack_size { } { + if [target_info exists gcc,stack_size] { + return 1 + } + return 0 +} + +# Return the value attribute of an effective target, otherwise return 0. + +proc dg-effective-target-value { effective_target } { + if { "$effective_target" == "stack_size" } { + if [check_effective_target_stack_size] { + return [target_info gcc,stack_size] + } + } + + return 0 +} + +# Return 1 if signal.h is supported. + +proc check_effective_target_signal { } { + if [target_info exists gcc,signal_suppress] { + return 0 + } + return 1 +} + +# Return 1 if according to target_info struct and explicit target list +# target disables -fdelete-null-pointer-checks. Targets should return 0 +# if they simply default to -fno-delete-null-pointer-checks but obey +# -fdelete-null-pointer-checks when passed explicitly (and tests that +# depend on this option should do that). + +proc check_effective_target_keeps_null_pointer_checks { } { + if [target_info exists keeps_null_pointer_checks] { + return 1 + } + if { [istarget msp430-*-*] || [istarget cr16-*-*] } { + return 1; + } + return 0 +} + +# Return the autofdo profile wrapper + +# Linux by default allows 516KB of perf event buffers +# in /proc/sys/kernel/perf_event_mlock_kb +# Each individual perf tries to grab it +# This causes problems with parallel test suite runs. Instead +# limit us to 8 pages (32K), which should be good enough +# for the small test programs. With the default settings +# this allows parallelism of 16 and higher of parallel gcc-auto-profile +proc profopt-perf-wrapper { } { + global srcdir + return "$srcdir/../config/i386/gcc-auto-profile -m8 " +} + +# Return true if profiling is supported on the target. + +proc check_profiling_available { test_what } { + verbose "Profiling argument is <$test_what>" 1 + + # These conditions depend on the argument so examine them before + # looking at the cache variable. + + # Tree profiling requires TLS runtime support. + if { $test_what == "-fprofile-generate" } { + if { ![check_effective_target_tls_runtime] } { + return 0 + } + } + + if { $test_what == "-fauto-profile" } { + if { !([istarget i?86-*-linux*] || [istarget x86_64-*-linux*]) } { + verbose "autofdo only supported on linux" + return 0 + } + # not cross compiling? + if { ![isnative] } { + verbose "autofdo not supported for non native builds" + return 0 + } + set event [profopt-perf-wrapper] + if {$event == "" } { + verbose "autofdo not supported" + return 0 + } + global srcdir + set status [remote_exec host "$srcdir/../config/i386/gcc-auto-profile" "-m8 true -v >/dev/null"] + if { [lindex $status 0] != 0 } { + verbose "autofdo not supported because perf does not work" + return 0 + } + + # no good way to check this in advance -- check later instead. + #set status [remote_exec host "create_gcov" "2>/dev/null"] + #if { [lindex $status 0] != 255 } { + # verbose "autofdo not supported due to missing create_gcov" + # return 0 + #} + } + + # Support for -p on solaris2 relies on mcrt1.o which comes with the + # vendor compiler. We cannot reliably predict the directory where the + # vendor compiler (and thus mcrt1.o) is installed so we can't + # necessarily find mcrt1.o even if we have it. + if { [istarget *-*-solaris2*] && $test_what == "-p" } { + return 0 + } + + # We don't yet support profiling for MIPS16. + if { [istarget mips*-*-*] + && ![check_effective_target_nomips16] + && ($test_what == "-p" || $test_what == "-pg") } { + return 0 + } + + # MinGW does not support -p. + if { [istarget *-*-mingw*] && $test_what == "-p" } { + return 0 + } + + # cygwin does not support -p. + if { [istarget *-*-cygwin*] && $test_what == "-p" } { + return 0 + } + + # uClibc does not have gcrt1.o. + if { [check_effective_target_uclibc] + && ($test_what == "-p" || $test_what == "-pg") } { + return 0 + } + + # Now examine the cache variable. + set profiling_working \ + [check_cached_effective_target profiling_available { + # Some targets don't have any implementation of __bb_init_func or are + # missing other needed machinery. + if {[istarget aarch64*-*-elf] + || [istarget am3*-*-linux*] + || [istarget amdgcn-*-*] + || [istarget arm*-*-eabi*] + || [istarget arm*-*-elf] + || [istarget arm*-*-symbianelf*] + || [istarget avr-*-*] + || [istarget bfin-*-*] + || [istarget cris-*-*] + || [istarget csky-*-elf*] + || [istarget fido-*-elf] + || [istarget h8300-*-*] + || [istarget lm32-*-*] + || [istarget m32c-*-elf] + || [istarget m68k-*-elf] + || [istarget m68k-*-uclinux*] + || [istarget mips*-*-elf*] + || [istarget mmix-*-*] + || [istarget mn10300-*-elf*] + || [istarget moxie-*-elf*] + || [istarget msp430-*-*] + || [istarget nds32*-*-elf] + || [istarget nios2-*-elf] + || [istarget nvptx-*-*] + || [istarget powerpc-*-eabi*] + || [istarget powerpc-*-elf] + || [istarget pru-*-*] + || [istarget rx-*-*] + || [istarget tic6x-*-elf] + || [istarget visium-*-*] + || [istarget xstormy16-*] + || [istarget xtensa*-*-elf] + || [istarget *-*-rtems*] + || [istarget *-*-vxworks*] } { + return 0 + } else { + return 1 + } + }] + + # -pg link test result can't be cached since it may change between + # runs. + if { $profiling_working == 1 + && ![check_no_compiler_messages_nocache profiling executable { + int main() { return 0; } } "-pg"] } { + set profiling_working 0 + } + + return $profiling_working +} + +# Check to see if a target is "freestanding". This is as per the definition +# in Section 4 of C99 standard. Effectively, it is a target which supports no +# extra headers or libraries other than what is considered essential. +proc check_effective_target_freestanding { } { + if { [istarget nvptx-*-*] } { + return 1 + } + return 0 +} + +# Check to see that file I/O functions are available. +proc check_effective_target_fileio { } { + return [check_no_compiler_messages fileio_available executable { +#include +int main() { + char *n = tmpnam (NULL); + FILE *f = fopen (n, "w"); + fclose (f); + remove (n); + return 0; +} } ""] +} + +# Return 1 if target has packed layout of structure members by +# default, 0 otherwise. Note that this is slightly different than +# whether the target has "natural alignment": both attributes may be +# false. + +proc check_effective_target_default_packed { } { + return [check_no_compiler_messages default_packed assembly { + struct x { char a; long b; } c; + int s[sizeof (c) == sizeof (char) + sizeof (long) ? 1 : -1]; + }] +} + +# Return 1 if target has PCC_BITFIELD_TYPE_MATTERS defined. See +# documentation, where the test also comes from. + +proc check_effective_target_pcc_bitfield_type_matters { } { + # PCC_BITFIELD_TYPE_MATTERS isn't just about unnamed or empty + # bitfields, but let's stick to the example code from the docs. + return [check_no_compiler_messages pcc_bitfield_type_matters assembly { + struct foo1 { char x; char :0; char y; }; + struct foo2 { char x; int :0; char y; }; + int s[sizeof (struct foo1) != sizeof (struct foo2) ? 1 : -1]; + }] +} + +# Add to FLAGS all the target-specific flags needed to use thread-local storage. + +proc add_options_for_tls { flags } { + # On Solaris 9, __tls_get_addr/___tls_get_addr only lives in + # libthread, so always pass -pthread for native TLS. Same for AIX. + # Need to duplicate native TLS check from + # check_effective_target_tls_native to avoid recursion. + if { ([istarget powerpc-ibm-aix*]) && + [check_no_messages_and_pattern tls_native "!emutls" assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] } { + return "-pthread [g++_link_flags [get_multilibs "-pthread"] ] $flags " + } + return $flags +} + +# Return 1 if indirect jumps are supported, 0 otherwise. + +proc check_effective_target_indirect_jumps {} { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if nonlocal goto is supported, 0 otherwise. + +proc check_effective_target_nonlocal_goto {} { + if { [istarget nvptx-*-*] || [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if global constructors are supported, 0 otherwise. + +proc check_effective_target_global_constructor {} { + if { [istarget nvptx-*-*] + || [istarget amdgcn-*-*] + || [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if taking label values is supported, 0 otherwise. + +proc check_effective_target_label_values {} { + if { [istarget nvptx-*-*] || [target_info exists gcc,no_label_values] } { + return 0 + } + + return 1 +} + +# Return 1 if builtin_return_address and builtin_frame_address are +# supported, 0 otherwise. + +proc check_effective_target_return_address {} { + if { [istarget nvptx-*-*] } { + return 0 + } + # No notion of return address in eBPF. + if { [istarget bpf-*-*] } { + return 0 + } + # It could be supported on amdgcn, but isn't yet. + if { [istarget amdgcn*-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if the assembler does not verify function types against +# calls, 0 otherwise. Such verification will typically show up problems +# with K&R C function declarations. + +proc check_effective_target_untyped_assembly {} { + if { [istarget nvptx-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if alloca is supported, 0 otherwise. + +proc check_effective_target_alloca {} { + if { [istarget nvptx-*-*] } { + return [check_no_compiler_messages alloca assembly { + void f (void*); + void g (int n) { f (__builtin_alloca (n)); } + }] + } + return 1 +} + +# Return 1 if thread local storage (TLS) is supported, 0 otherwise. + +proc check_effective_target_tls {} { + return [check_no_compiler_messages tls assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] +} + +# Return 1 if *native* thread local storage (TLS) is supported, 0 otherwise. + +proc check_effective_target_tls_native {} { + # VxWorks uses emulated TLS machinery, but with non-standard helper + # functions, so we fail to automatically detect it. + if { [istarget *-*-vxworks*] } { + return 0 + } + + return [check_no_messages_and_pattern tls_native "!emutls" assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] +} + +# Return 1 if *emulated* thread local storage (TLS) is supported, 0 otherwise. + +proc check_effective_target_tls_emulated {} { + # VxWorks uses emulated TLS machinery, but with non-standard helper + # functions, so we fail to automatically detect it. + if { [istarget *-*-vxworks*] } { + return 1 + } + + return [check_no_messages_and_pattern tls_emulated "emutls" assembly { + __thread int i; + int f (void) { return i; } + void g (int j) { i = j; } + }] +} + +# Return 1 if TLS executables can run correctly, 0 otherwise. + +proc check_effective_target_tls_runtime {} { + return [check_runtime tls_runtime { + __thread int thr __attribute__((tls_model("global-dynamic"))) = 0; + int main (void) { return thr; } + } [add_options_for_tls ""]] +} + +# Return 1 if atomic compare-and-swap is supported on 'int' + +proc check_effective_target_cas_char {} { + return [check_no_compiler_messages cas_char assembly { + #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 + #error unsupported + #endif + } ""] +} + +proc check_effective_target_cas_int {} { + return [check_no_compiler_messages cas_int assembly { + #if __INT_MAX__ == 0x7fff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 + /* ok */ + #elif __INT_MAX__ == 0x7fffffff && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 + /* ok */ + #else + #error unsupported + #endif + } ""] +} + +# Return 1 if -ffunction-sections is supported, 0 otherwise. + +proc check_effective_target_function_sections {} { + # Darwin has its own scheme and silently accepts -ffunction-sections. + if { [istarget *-*-darwin*] } { + return 0 + } + + return [check_no_compiler_messages functionsections assembly { + void foo (void) { } + } "-ffunction-sections"] +} + +# Return 1 if instruction scheduling is available, 0 otherwise. + +proc check_effective_target_scheduling {} { + return [check_no_compiler_messages scheduling object { + void foo (void) { } + } "-fschedule-insns"] +} + +# Return 1 if trapping arithmetic is available, 0 otherwise. + +proc check_effective_target_trapping {} { + return [check_no_compiler_messages trapping object { + int add (int a, int b) { return a + b; } + } "-ftrapv"] +} + +# Return 1 if compilation with -fgraphite is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fgraphite {} { + return [check_no_compiler_messages fgraphite object { + void foo (void) { } + } "-O1 -fgraphite"] +} + +# Return 1 if compiled with --enable-offload-targets= +# This affects host compilation as ENABLE_OFFLOAD then evaluates to true. +proc check_effective_target_offloading_enabled {} { + return [check_configured_with "--enable-offload-targets"] +} + +# Return 1 if compilation with -fopenacc is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fopenacc {} { + # nvptx/amdgcn can be built with the device-side bits of openacc, but it + # does not make sense to test it as an openacc host. + if [istarget nvptx-*-*] { return 0 } + if [istarget amdgcn-*-*] { return 0 } + + return [check_no_compiler_messages fopenacc object { + void foo (void) { } + } "-fopenacc"] +} + +# Return 1 if compilation with -fopenmp is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fopenmp {} { + # nvptx/amdgcn can be built with the device-side bits of libgomp, but it + # does not make sense to test it as an openmp host. + if [istarget nvptx-*-*] { return 0 } + if [istarget amdgcn-*-*] { return 0 } + + return [check_no_compiler_messages fopenmp object { + void foo (void) { } + } "-fopenmp"] +} + +# Return 1 if compilation with -fgnu-tm is error-free for trivial +# code, 0 otherwise. + +proc check_effective_target_fgnu_tm {} { + return [check_no_compiler_messages fgnu_tm object { + void foo (void) { } + } "-fgnu-tm"] +} + +# Return 1 if the target supports mmap, 0 otherwise. + +proc check_effective_target_mmap {} { + return [check_function_available "mmap"] +} + +# Return 1 if the target supports sysconf, 0 otherwise. + +proc check_effective_target_sysconf {} { + return [check_function_available "sysconf"] +} + +# Return 1 if the target supports dlopen, 0 otherwise. +proc check_effective_target_dlopen {} { + return [check_no_compiler_messages dlopen executable { + #include + int main(void) { dlopen ("dummy.so", RTLD_NOW); } + } [add_options_for_dlopen ""]] +} + +proc add_options_for_dlopen { flags } { + return "$flags -ldl" +} + +# Return 1 if the target supports clone, 0 otherwise. +proc check_effective_target_clone {} { + return [check_function_available "clone"] +} + +# Return 1 if the target supports setrlimit, 0 otherwise. +proc check_effective_target_setrlimit {} { + # Darwin has non-posix compliant RLIMIT_AS + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_function_available "setrlimit"] +} + +# Return 1 if the target supports gettimeofday, 0 otherwise. +proc check_effective_target_gettimeofday {} { + return [check_function_available "gettimeofday"] +} + +# Return 1 if the target supports swapcontext, 0 otherwise. +proc check_effective_target_swapcontext {} { + return [check_no_compiler_messages swapcontext executable { + #include + int main (void) + { + ucontext_t orig_context,child_context; + if (swapcontext(&child_context, &orig_context) < 0) { } + } + }] +} + +# Return 1 if the target supports POSIX threads, 0 otherwise. +proc check_effective_target_pthread {} { + return [check_no_compiler_messages pthread object { + #include + void foo (void) { } + } "-pthread"] +} + +# Return 1 if compilation with -mpe-aligned-commons is error-free +# for trivial code, 0 otherwise. + +proc check_effective_target_pe_aligned_commons {} { + if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } { + return [check_no_compiler_messages pe_aligned_commons object { + int foo; + } "-mpe-aligned-commons"] + } + return 0 +} + +# Return 1 if the target supports -static +proc check_effective_target_static {} { + if { [istarget arm*-*-uclinuxfdpiceabi] } { + return 0; + } + return [check_no_compiler_messages static executable { + int main (void) { return 0; } + } "-static"] +} + +# Return 1 if the target supports -fstack-protector +proc check_effective_target_fstack_protector {} { + if { [istarget hppa*-*-*] } { + return 0; + } + return [check_runtime fstack_protector { + #include + int main (int argc, char *argv[]) { + char buf[64]; + return !strcpy (buf, strrchr (argv[0], '/')); + } + } "-fstack-protector"] +} + +# Return 1 if the target supports -fstack-check or -fstack-check=$stack_kind +proc check_stack_check_available { stack_kind } { + if [string match "" $stack_kind] then { + set stack_opt "-fstack-check" + } else { set stack_opt "-fstack-check=$stack_kind" } + + return [check_no_compiler_messages stack_check_$stack_kind executable { + int main (void) { return 0; } + } "$stack_opt"] +} + +# Return 1 if compilation with -freorder-blocks-and-partition is error-free +# for trivial code, 0 otherwise. As some targets (ARM for example) only +# warn when -fprofile-use is also supplied we test that combination too. + +proc check_effective_target_freorder {} { + if { [check_no_compiler_messages freorder object { + void foo (void) { } + } "-freorder-blocks-and-partition"] + && [check_no_compiler_messages fprofile_use_freorder object { + void foo (void) { } + } "-fprofile-use -freorder-blocks-and-partition -Wno-missing-profile"] } { + return 1 + } + return 0 +} + +# Return 1 if -fpic and -fPIC are supported, as in no warnings or errors +# emitted, 0 otherwise. Whether a shared library can actually be built is +# out of scope for this test. + +proc check_effective_target_fpic { } { + # Note that M68K has a multilib that supports -fpic but not + # -fPIC, so we need to check both. We test with a program that + # requires GOT references. + foreach arg {fpic fPIC} { + if [check_no_compiler_messages $arg object { + extern int foo (void); extern int bar; + int baz (void) { return foo () + bar; } + } "-$arg"] { + return 1 + } + } + return 0 +} + +# On AArch64, if -fpic is not supported, then we will fall back to -fPIC +# silently. So, we can't rely on above "check_effective_target_fpic" as it +# assumes compiler will give warning if -fpic not supported. Here we check +# whether binutils supports those new -fpic relocation modifiers, and assume +# -fpic is supported if there is binutils support. GCC configuration will +# enable -fpic for AArch64 in this case. +# +# "check_effective_target_aarch64_small_fpic" is dedicated for checking small +# memory model -fpic relocation types. + +proc check_effective_target_aarch64_small_fpic { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_small_fpic object { + void foo (void) { asm ("ldr x0, [x2, #:gotpage_lo15:globalsym]"); } + }] + } else { + return 0 + } +} + +# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize +# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported +# in binutils since 2015-03-04 as PR gas/17843. +# +# This test directive make sure binutils support all features needed by TLS LE +# under -mtls-size=32 on AArch64. + +proc check_effective_target_aarch64_tlsle32 { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_tlsle32 object { + void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); } + }] + } else { + return 0 + } +} + +# Return 1 if -shared is supported, as in no warnings or errors +# emitted, 0 otherwise. + +proc check_effective_target_shared { } { + # Note that M68K has a multilib that supports -fpic but not + # -fPIC, so we need to check both. We test with a program that + # requires GOT references. + return [check_no_compiler_messages shared executable { + extern int foo (void); extern int bar; + int baz (void) { return foo () + bar; } + } "-shared -fpic"] +} + +# Return 1 if -pie, -fpie and -fPIE are supported, 0 otherwise. + +proc check_effective_target_pie { } { + if { [istarget *-*-darwin\[912\]*] + || [istarget *-*-dragonfly*] + || [istarget *-*-freebsd*] + || [istarget *-*-linux*] + || [istarget arm*-*-uclinuxfdpiceabi] + || [istarget *-*-gnu*] + || [istarget *-*-amdhsa]} { + return 1; + } + if { [istarget *-*-solaris2.1\[1-9\]*] } { + # Full PIE support was added in Solaris 11.3, but gcc errors out + # if missing, so check for that. + return [check_no_compiler_messages pie executable { + int main (void) { return 0; } + } "-pie -fpie"] + } + return 0 +} + +# Return true if the target supports -mpaired-single (as used on MIPS). + +proc check_effective_target_mpaired_single { } { + return [check_no_compiler_messages mpaired_single object { + void foo (void) { } + } "-mpaired-single"] +} + +# Return true if the target has access to FPU instructions. + +proc check_effective_target_hard_float { } { + if { [istarget loongarch*-*-*] } { + return [check_no_compiler_messages hard_float assembly { + #if (defined __loongarch_soft_float) + #error __loongarch_soft_float + #endif + }] + } + + if { [istarget mips*-*-*] } { + return [check_no_compiler_messages hard_float assembly { + #if (defined __mips_soft_float || defined __mips16) + #error __mips_soft_float || __mips16 + #endif + }] + } + + # This proc is actually checking the availabilty of FPU + # support for doubles, so on the RX we must fail if the + # 64-bit double multilib has been selected. + if { [istarget rx-*-*] } { + return 0 + # return [check_no_compiler_messages hard_float assembly { + #if defined __RX_64_BIT_DOUBLES__ + #error __RX_64_BIT_DOUBLES__ + #endif + # }] + } + + # The generic test doesn't work for C-SKY because some cores have + # hard float for single precision only. + if { [istarget csky*-*-*] } { + return [check_no_compiler_messages hard_float assembly { + #if defined __csky_soft_float__ + #error __csky_soft_float__ + #endif + }] + } + + # The generic test equates hard_float with "no call for adding doubles". + return [check_no_messages_and_pattern hard_float "!\\(call" rtl-expand { + double a (double b, double c) { return b + c; } + }] +} + +# Return true if the target is a 64-bit MIPS target. + +proc check_effective_target_mips64 { } { + return [check_no_compiler_messages mips64 assembly { + #ifndef __mips64 + #error !__mips64 + #endif + }] +} + +# Return true if the target is a MIPS target that does not produce +# MIPS16 code. + +proc check_effective_target_nomips16 { } { + return [check_no_compiler_messages nomips16 object { + #ifndef __mips + #error !__mips + #else + /* A cheap way of testing for -mflip-mips16. */ + void foo (void) { asm ("addiu $20,$20,1"); } + void bar (void) { asm ("addiu $20,$20,1"); } + #endif + }] +} + +# Add the options needed for MIPS16 function attributes. At the moment, +# we don't support MIPS16 PIC. + +proc add_options_for_mips16_attribute { flags } { + return "$flags -mno-abicalls -fno-pic -DMIPS16=__attribute__((mips16))" +} + +# Return true if we can force a mode that allows MIPS16 code generation. +# We don't support MIPS16 PIC, and only support MIPS16 -mhard-float +# for o32 and o64. + +proc check_effective_target_mips16_attribute { } { + return [check_no_compiler_messages mips16_attribute assembly { + #ifdef PIC + #error PIC + #endif + #if defined __mips_hard_float \ + && (!defined _ABIO32 || _MIPS_SIM != _ABIO32) \ + && (!defined _ABIO64 || _MIPS_SIM != _ABIO64) + #error __mips_hard_float && (!_ABIO32 || !_ABIO64) + #endif + } [add_options_for_mips16_attribute ""]] +} + +# Return 1 if the target supports long double larger than double when +# using the new ABI, 0 otherwise. + +proc check_effective_target_mips_newabi_large_long_double { } { + return [check_no_compiler_messages mips_newabi_large_long_double object { + int dummy[sizeof(long double) > sizeof(double) ? 1 : -1]; + } "-mabi=64"] +} + +# Return true if the target is a MIPS target that has access +# to the LL and SC instructions. + +proc check_effective_target_mips_llsc { } { + if { ![istarget mips*-*-*] } { + return 0 + } + # Assume that these instructions are always implemented for + # non-elf* targets, via emulation if necessary. + if { ![istarget *-*-elf*] } { + return 1 + } + # Otherwise assume LL/SC support for everything but MIPS I. + return [check_no_compiler_messages mips_llsc assembly { + #if __mips == 1 + #error __mips == 1 + #endif + }] +} + +# Return true if the target is a MIPS target that uses in-place relocations. + +proc check_effective_target_mips_rel { } { + if { ![istarget mips*-*-*] } { + return 0 + } + return [check_no_compiler_messages mips_rel object { + #if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ + || (defined _ABI64 && _MIPS_SIM == _ABI64) + #error _ABIN32 && (_ABIN32 || _ABI64) + #endif + }] +} + +# Return true if the target is a MIPS target that uses the EABI. + +proc check_effective_target_mips_eabi { } { + if { ![istarget mips*-*-*] } { + return 0 + } + return [check_no_compiler_messages mips_eabi object { + #ifndef __mips_eabi + #error !__mips_eabi + #endif + }] +} + +# Return 1 if the current multilib does not generate PIC by default. + +proc check_effective_target_nonpic { } { + return [check_no_compiler_messages nonpic assembly { + #if __PIC__ + #error __PIC__ + #endif + }] +} + +# Return 1 if the current multilib generates PIE by default. + +proc check_effective_target_pie_enabled { } { + return [check_no_compiler_messages pie_enabled assembly { + #ifndef __PIE__ + #error unsupported + #endif + }] +} + +# Return 1 if the target generates -fstack-protector by default. + +proc check_effective_target_fstack_protector_enabled {} { + return [ check_no_compiler_messages fstack_protector_enabled assembly { + #if !defined(__SSP__) && !defined(__SSP_ALL__) && \ + !defined(__SSP_STRONG__) && !defined(__SSP_EXPICIT__) + #error unsupported + #endif + }] +} + +# Return 1 if the target does not use a status wrapper. + +proc check_effective_target_unwrapped { } { + if { [target_info needs_status_wrapper] != "" \ + && [target_info needs_status_wrapper] != "0" } { + return 0 + } + return 1 +} + +# Return true if iconv is supported on the target. In particular IBM1047. + +proc check_iconv_available { test_what } { + global libiconv + + # If the tool configuration file has not set libiconv, try "-liconv" + if { ![info exists libiconv] } { + set libiconv "-liconv" + } + set test_what [lindex $test_what 1] + return [check_runtime_nocache $test_what [subst { + #include + int main (void) + { + iconv_t cd; + + cd = iconv_open ("$test_what", "UTF-8"); + if (cd == (iconv_t) -1) + return 1; + return 0; + } + }] $libiconv] +} + +# Return true if the atomic library is supported on the target. +proc check_effective_target_libatomic_available { } { + return [check_no_compiler_messages libatomic_available executable { + int main (void) { return 0; } + } "-latomic"] +} + +# Return 1 if an ASCII locale is supported on this host, 0 otherwise. + +proc check_ascii_locale_available { } { + return 1 +} + +# Return true if named sections are supported on this target. + +proc check_named_sections_available { } { + return [check_no_compiler_messages named_sections assembly { + int __attribute__ ((section("whatever"))) foo; + }] +} + +# Return true if the "naked" function attribute is supported on this target. + +proc check_effective_target_naked_functions { } { + return [check_no_compiler_messages naked_functions assembly { + void f() __attribute__((naked)); + }] +} + +# Return 1 if the target supports Fortran real kinds larger than real(8), +# 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_large_real { } { + return [check_no_compiler_messages fortran_large_real executable { + ! Fortran + integer,parameter :: k = selected_real_kind (precision (0.0_8) + 1) + real(kind=k) :: x + x = cos (x) + end + }] +} + +# Return 1 if the target supports Fortran real kind real(16), +# 0 otherwise. Contrary to check_effective_target_fortran_large_real +# this checks for Real(16) only; the other returned real(10) if +# both real(10) and real(16) are available. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_real_16 { } { + return [check_no_compiler_messages fortran_real_16 executable { + ! Fortran + real(kind=16) :: x + x = cos (x) + end + }] +} + +# Return 1 if the target supports Fortran real kind 10, +# 0 otherwise. Contrary to check_effective_target_fortran_large_real +# this checks for real(10) only. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_real_10 { } { + return [check_no_compiler_messages fortran_real_10 executable { + ! Fortran + real(kind=10) :: x + x = cos (x) + end + }] +} + +# Return 1 if the target supports Fortran real kind C_FLOAT128, +# 0 otherwise. This differs from check_effective_target_fortran_real_16 +# because _Float128 has the additional requirement that it be the +# 128-bit IEEE encoding; even if _Float128 is available in C, it may not +# have a corresponding Fortran kind on targets (PowerPC) that use some +# other encoding for long double/TFmode/real(16). +proc check_effective_target_fortran_real_c_float128 { } { + return [check_no_compiler_messages fortran_real_c_float128 executable { + ! Fortran + use iso_c_binding + real(kind=c_float128) :: x + x = cos (x) + end + }] +} + +# Return 1 if the target supports Fortran's IEEE modules, +# 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_ieee { flags } { + return [check_no_compiler_messages fortran_ieee executable { + ! Fortran + use, intrinsic :: ieee_features + end + } $flags ] +} + + +# Return 1 if the target supports SQRT for the largest floating-point +# type. (Some targets lack the libm support for this FP type.) +# On most targets, this check effectively checks either whether sqrtl is +# available or on __float128 systems whether libquadmath is installed, +# which provides sqrtq. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_largest_fp_has_sqrt { } { + return [check_no_compiler_messages fortran_largest_fp_has_sqrt executable { + ! Fortran + use iso_fortran_env, only: real_kinds + integer,parameter:: maxFP = real_kinds(ubound(real_kinds,dim=1)) + real(kind=maxFP), volatile :: x + x = 2.0_maxFP + x = sqrt (x) + end + }] +} + + +# Return 1 if the target supports Fortran integer kinds larger than +# integer(8), 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_large_int { } { + return [check_no_compiler_messages fortran_large_int executable { + ! Fortran + integer,parameter :: k = selected_int_kind (range (0_8) + 1) + integer(kind=k) :: i + end + }] +} + +# Return 1 if the target supports Fortran integer(16), 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_fortran_integer_16 { } { + return [check_no_compiler_messages fortran_integer_16 executable { + ! Fortran + integer(16) :: i + end + }] +} + +# Return 1 if we can statically link libgfortran, 0 otherwise. +# +# When the target name changes, replace the cached result. + +proc check_effective_target_static_libgfortran { } { + return [check_no_compiler_messages static_libgfortran executable { + ! Fortran + print *, 'test' + end + } "-static"] +} + +# Return 1 if we can use the -rdynamic option, 0 otherwise. + +proc check_effective_target_rdynamic { } { + return [check_no_compiler_messages rdynamic executable { + int main() { return 0; } + } "-rdynamic"] +} + +proc check_linker_plugin_available { } { + return [check_no_compiler_messages_nocache linker_plugin executable { + int main() { return 0; } + } "-flto -fuse-linker-plugin"] +} + +# Return 1 if the target is RV32, 0 otherwise. Cache the result. + +proc check_effective_target_rv32 { } { + # Check that we are compiling for RV32 by checking the xlen size. + return [check_no_compiler_messages riscv_rv32 assembly { + #if !defined(__riscv_xlen) + #error "__riscv_xlen not defined!" + #else + #if __riscv_xlen != 32 + #error "Not RV32" + #endif + #endif + }] +} + +# Return 1 if the target is RV64, 0 otherwise. Cache the result. + +proc check_effective_target_rv64 { } { + # Check that we are compiling for RV64 by checking the xlen size. + return [check_no_compiler_messages riscv_rv64 assembly { + #if !defined(__riscv_xlen) + #error "__riscv_xlen not defined!" + #else + #if __riscv_xlen != 64 + #error "Not RV64" + #endif + #endif + }] +} + +# Return 1 if the target OS supports running SSE executables, 0 +# otherwise. Cache the result. + +proc check_sse_os_support_available { } { + return [check_cached_effective_target sse_os_support_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + expr 1 + } + }] +} + +# Return 1 if the target OS supports running AVX executables, 0 +# otherwise. Cache the result. + +proc check_avx_os_support_available { } { + return [check_cached_effective_target avx_os_support_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + # Check that OS has AVX and SSE saving enabled. + check_runtime_nocache avx_os_support_available { + int main () + { + unsigned int eax, edx; + + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + return (eax & 0x06) != 0x06; + } + } "" + } + }] +} + +# Return 1 if the target OS supports running AVX executables, 0 +# otherwise. Cache the result. + +proc check_avx512_os_support_available { } { + return [check_cached_effective_target avx512_os_support_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + # Check that OS has AVX512, AVX and SSE saving enabled. + check_runtime_nocache avx512_os_support_available { + int main () + { + unsigned int eax, edx; + + asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); + return (eax & 0xe6) != 0xe6; + } + } "" + } + }] +} + +# Return 1 if the target supports executing SSE instructions, 0 +# otherwise. Cache the result. + +proc check_sse_hw_available { } { + return [check_cached_effective_target sse_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache sse_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return !(edx & bit_SSE); + } + } "" + } + }] +} + +# Return 1 if the target supports executing SSE2 instructions, 0 +# otherwise. Cache the result. + +proc check_sse2_hw_available { } { + return [check_cached_effective_target sse2_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache sse2_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return !(edx & bit_SSE2); + } + } "" + } + }] +} + +# Return 1 if the target supports executing SSE4 instructions, 0 +# otherwise. Cache the result. + +proc check_sse4_hw_available { } { + return [check_cached_effective_target sse4_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache sse4_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return !(ecx & bit_SSE4_2); + } + } "" + } + }] +} + +# Return 1 if the target supports executing AVX instructions, 0 +# otherwise. Cache the result. + +proc check_avx_hw_available { } { + return [check_cached_effective_target avx_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + expr 0 + } else { + check_runtime_nocache avx_hw_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 1; + + return ((ecx & (bit_AVX | bit_OSXSAVE)) + != (bit_AVX | bit_OSXSAVE)); + } + } "" + } + }] +} + +# Return 1 if the target supports executing AVX2 instructions, 0 +# otherwise. Cache the result. + +proc check_avx2_hw_available { } { + return [check_cached_effective_target avx2_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } { + expr 0 + } else { + check_runtime_nocache avx2_hw_available { + #include + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid_max (0, NULL) < 7) + return 1; + + __cpuid (1, eax, ebx, ecx, edx); + + if (!(ecx & bit_OSXSAVE)) + return 1; + + __cpuid_count (7, 0, eax, ebx, ecx, edx); + + return !(ebx & bit_AVX2); + } + } "" + } + }] +} + +# Return 1 if the target supports executing AVX512 foundation instructions, 0 +# otherwise. Cache the result. + +proc check_avx512f_hw_available { } { + return [check_cached_effective_target avx512f_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget x86_64-*-*] || [istarget i?86-*-*]) } { + expr 0 + } else { + check_runtime_nocache avx512f_hw_available { + #include + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + + if (__get_cpuid_max (0, NULL) < 7) + return 1; + + __cpuid (1, eax, ebx, ecx, edx); + + if (!(ecx & bit_OSXSAVE)) + return 1; + + __cpuid_count (7, 0, eax, ebx, ecx, edx); + + return !(ebx & bit_AVX512F); + } + } "" + } + }] +} + +# Return 1 if the target supports running SSE executables, 0 otherwise. + +proc check_effective_target_sse_runtime { } { + if { [check_effective_target_sse] + && [check_sse_hw_available] + && [check_sse_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running SSE2 executables, 0 otherwise. + +proc check_effective_target_sse2_runtime { } { + if { [check_effective_target_sse2] + && [check_sse2_hw_available] + && [check_sse_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running SSE4 executables, 0 otherwise. + +proc check_effective_target_sse4_runtime { } { + if { [check_effective_target_sse4] + && [check_sse4_hw_available] + && [check_sse_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running AVX executables, 0 otherwise. + +proc check_effective_target_avx_runtime { } { + if { [check_effective_target_avx] + && [check_avx_hw_available] + && [check_avx_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running AVX2 executables, 0 otherwise. + +proc check_effective_target_avx2_runtime { } { + if { [check_effective_target_avx2] + && [check_avx2_hw_available] + && [check_avx_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running AVX512f executables, 0 otherwise. + +proc check_effective_target_avx512f_runtime { } { + if { [check_effective_target_avx512f] + && [check_avx512f_hw_available] + && [check_avx512_os_support_available] } { + return 1 + } + return 0 +} + +# Return 1 if bmi2 instructions can be compiled. +proc check_effective_target_bmi2 { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages bmi2 object { + unsigned int + _bzhi_u32 (unsigned int __X, unsigned int __Y) + { + return __builtin_ia32_bzhi_si (__X, __Y); + } + } "-mbmi2" ] +} + +# Return 1 if the target supports executing MIPS Paired-Single instructions, +# 0 otherwise. Cache the result. + +proc check_mpaired_single_hw_available { } { + return [check_cached_effective_target mpaired_single_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget mips*-*-*]) } { + expr 0 + } else { + check_runtime_nocache mpaired_single_hw_available { + int main() + { + asm volatile ("pll.ps $f2,$f4,$f6"); + return 0; + } + } "" + } + }] +} + +# Return 1 if the target supports executing Loongson vector instructions, +# 0 otherwise. Cache the result. + +proc check_mips_loongson_mmi_hw_available { } { + return [check_cached_effective_target mips_loongson_mmi_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget mips*-*-*]) } { + expr 0 + } else { + check_runtime_nocache mips_loongson_mmi_hw_available { + #include + int main() + { + asm volatile ("paddw $f2,$f4,$f6"); + return 0; + } + } "-mloongson-mmi" + } + }] +} + +# Return 1 if the target supports executing MIPS MSA instructions, 0 +# otherwise. Cache the result. + +proc check_mips_msa_hw_available { } { + return [check_cached_effective_target mips_msa_hw_available { + # If this is not the right target then we can skip the test. + if { !([istarget mips*-*-*]) } { + expr 0 + } else { + check_runtime_nocache mips_msa_hw_available { + #if !defined(__mips_msa) + #error "MSA NOT AVAIL" + #else + #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)) + #error "MSA NOT AVAIL FOR ISA REV < 2" + #endif + #if !defined(__mips_hard_float) + #error "MSA HARD_FLOAT REQUIRED" + #endif + #if __mips_fpr != 64 + #error "MSA 64-bit FPR REQUIRED" + #endif + #include + + int main() + { + v8i16 v = __builtin_msa_ldi_h (0); + v[0] = 0; + return v[0]; + } + #endif + } "-mmsa" + } + }] +} + +# Return 1 if the target supports running MIPS Paired-Single +# executables, 0 otherwise. + +proc check_effective_target_mpaired_single_runtime { } { + if { [check_effective_target_mpaired_single] + && [check_mpaired_single_hw_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running Loongson executables, 0 otherwise. + +proc check_effective_target_mips_loongson_mmi_runtime { } { + if { [check_effective_target_mips_loongson_mmi] + && [check_mips_loongson_mmi_hw_available] } { + return 1 + } + return 0 +} + +# Return 1 if the target supports running MIPS MSA executables, 0 otherwise. + +proc check_effective_target_mips_msa_runtime { } { + if { [check_effective_target_mips_msa] + && [check_mips_msa_hw_available] } { + return 1 + } + return 0 +} + +# Return 1 if we are compiling for 64-bit PowerPC but we do not use direct +# move instructions for moves from GPR to FPR. + +proc check_effective_target_powerpc64_no_dm { } { + # The "mulld" checks if we are generating PowerPC64 code. The "lfd" + # checks if we do not use direct moves, but use the old-fashioned + # slower move-via-the-stack. + return [check_no_messages_and_pattern powerpc64_no_dm \ + {\mmulld\M.*\mlfd} assembly { + double f(long long x) { return x*x; } + } {-O2}] +} + +# Return 1 if the target supports the __builtin_cpu_supports built-in, +# including having a new enough library to support the test. Cache the result. +# Require at least a power7 to run on. + +proc check_ppc_cpu_supports_hw_available { } { + return [check_cached_effective_target ppc_cpu_supports_hw_available { + # Some simulators are known to not support VSX/power8 instructions. + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mvsx" + check_runtime_nocache ppc_cpu_supports_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("xxlor vs0,vs0,vs0"); + #else + asm volatile ("xxlor 0,0,0"); + #endif + if (!__builtin_cpu_supports ("vsx")) + return 1; + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing 750CL paired-single instructions, 0 +# otherwise. Cache the result. + +proc check_750cl_hw_available { } { + return [check_cached_effective_target 750cl_hw_available { + # If this is not the right target then we can skip the test. + if { ![istarget powerpc-*paired*] } { + expr 0 + } else { + check_runtime_nocache 750cl_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("ps_mul v0,v0,v0"); + #else + asm volatile ("ps_mul 0,0,0"); + #endif + return 0; + } + } "-mpaired" + } + }] +} + +# Return 1 if the target supports executing power8 vector instructions, 0 +# otherwise. Cache the result. + +proc check_p8vector_hw_available { } { + return [check_cached_effective_target p8vector_hw_available { + # Some simulators are known to not support VSX/power8 instructions. + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mpower8-vector" + check_runtime_nocache p8vector_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("xxlorc vs0,vs0,vs0"); + #else + asm volatile ("xxlorc 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing power9 vector instructions, 0 +# otherwise. Cache the result. + +proc check_p9vector_hw_available { } { + return [check_cached_effective_target p9vector_hw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin. + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mpower9-vector" + check_runtime_nocache p9vector_hw_available { + int main() + { + long e = -1; + vector double v = (vector double) { 0.0, 0.0 }; + asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v)); + return e; + } + } $options + } + }] +} + +# Return 1 if the PowerPC target generates PC-relative instructions +# automatically for targets that support PC-relative instructions. +proc check_effective_target_powerpc_pcrel { } { + return [check_no_messages_and_pattern powerpc_pcrel \ + {\mpla\M} assembly { + static unsigned short s; + unsigned short *p_foo (void) { return &s; } + } {-O2 -mcpu=power10}] +} + +# Return 1 if the PowerPC target generates prefixed instructions automatically +# for targets that support prefixed instructions. +proc check_effective_target_powerpc_prefixed_addr { } { + return [check_no_messages_and_pattern powerpc_prefixed_addr \ + {\mplwz\M} assembly { + unsigned int foo (unsigned int *p) { return p[0x12345]; } + } {-O2 -mcpu=power10}] +} + +# Return 1 if the target supports executing power9 modulo instructions, 0 +# otherwise. Cache the result. + +proc check_p9modulo_hw_available { } { + return [check_cached_effective_target p9modulo_hw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin. + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mmodulo" + check_runtime_nocache p9modulo_hw_available { + int main() + { + int i = 5, j = 3, r = -1; + asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j)); + return (r == 2); + } + } $options + } + }] +} + + +# Return 1 if the target supports executing power10 instructions, 0 otherwise. +# Cache the result. It is assumed that if a simulator does not support the +# power10 instructions, that it will generate an error and this test will fail. + +proc check_power10_hw_available { } { + return [check_cached_effective_target power10_hw_available { + check_runtime_nocache power10_hw_available { + int main() + { + /* Set e first and use +r to check if pli actually works. */ + long e = -1; + asm ("pli %0,%1" : "+r" (e) : "n" (0x12345)); + if (e == 0x12345) + return 0; + return 1; + } + } "-mcpu=power10" + }] +} + +# Return 1 if the target supports executing MMA instructions, 0 otherwise. +# Cache the result. It is assumed that if a simulator does not support the +# MMA instructions, that it will generate an error and this test will fail. + +proc check_ppc_mma_hw_available { } { + return [check_cached_effective_target ppc_mma_hw_available { + check_runtime_nocache ppc_mma_hw_available { + #include + typedef double v4sf_t __attribute__ ((vector_size (16))); + + int main() + { + __vector_quad acc0; + v4sf_t result[4]; + result[0][0] = 1.0; + __builtin_mma_xxsetaccz (&acc0); + __builtin_mma_disassemble_acc (result, &acc0); + if (result[0][0] != 0.0) + return 1; + return 0; + } + } "-mcpu=power10" + }] +} + +# Return 1 if the target supports executing __float128 on PowerPC via software +# emulation, 0 otherwise. Cache the result. + +proc check_ppc_float128_sw_available { } { + return [check_cached_effective_target ppc_float128_sw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin and VxWorks. + if { [istarget *-*-vxworks*] + || [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mfloat128 -mvsx" + check_runtime_nocache ppc_float128_sw_available { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() + { + __float128 z = x + y; + return (z != 3.0q); + } + } $options + } + }] +} + +# Return 1 if the target supports executing __float128 on PowerPC via power9 +# hardware instructions, 0 otherwise. Cache the result. + +proc check_ppc_float128_hw_available { } { + return [check_cached_effective_target ppc_float128_hw_available { + # Some simulators are known to not support VSX/power8/power9 + # instructions. For now, disable on Darwin. + if { [istarget *-*-vxworks*] + || [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mfloat128 -mvsx -mfloat128-hardware -mpower9-vector" + check_runtime_nocache ppc_float128_hw_available { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() + { + __float128 z = x + y; + __float128 w = -1.0q; + + __asm__ ("xsaddqp %0,%1,%2" : "+v" (w) : "v" (x), "v" (y)); + return ((z != 3.0q) || (z != w)); + } + } $options + } + }] +} + +# See if the __ieee128 keyword is understood. +proc check_effective_target_ppc_ieee128_ok { } { + return [check_cached_effective_target ppc_ieee128_ok { + # disable on AIX and VxWorks. + if { [istarget *-*-aix*] + || [istarget *-*-vxworks*]} { + expr 0 + } else { + set options "-mfloat128" + check_runtime_nocache ppc_ieee128_ok { + int main() + { + __ieee128 a; + return 0; + } + } $options + } + }] +} + +# Check if GCC and GLIBC supports explicitly specifying that the long double +# format uses the IBM 128-bit extended double format. Under little endian +# PowerPC Linux, you need GLIBC 2.32 or later to be able to use a different +# long double format for running a program than the system default. + +proc check_effective_target_long_double_ibm128 { } { + return [check_runtime_nocache long_double_ibm128 { + #include + #include + /* use volatile to prevent optimization. */ + volatile __ibm128 a = (__ibm128) 3.0; + volatile long double one = 1.0L; + volatile long double two = 2.0L; + volatile long double b; + char buffer[20]; + int main() + { + __ibm128 a2; + long double b2; + if (sizeof (long double) != 16) + return 1; + b = one + two; + /* eliminate removing volatile cast warning. */ + a2 = a; + b2 = b; + if (memcmp (&a2, &b2, 16) != 0) + return 1; + sprintf (buffer, "%lg", b); + return strcmp (buffer, "3") != 0; + } + } [add_options_for_long_double_ibm128 ""]] +} + +# Return the appropriate options to specify that long double uses the IBM +# 128-bit format on PowerPC. + +proc add_options_for_long_double_ibm128 { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mlong-double-128 -Wno-psabi -mabi=ibmlongdouble" + } + return "$flags" +} + +# Check if GCC and GLIBC supports explicitly specifying that the long double +# format uses the IEEE 128-bit format. Under little endian PowerPC Linux, you +# need GLIBC 2.32 or later to be able to use a different long double format for +# running a program than the system default. + +proc check_effective_target_long_double_ieee128 { } { + return [check_runtime_nocache long_double_ieee128 { + #include + #include + /* use volatile to prevent optimization. */ + volatile _Float128 a = 3.0f128; + volatile long double one = 1.0L; + volatile long double two = 2.0L; + volatile long double b; + char buffer[20]; + int main() + { + _Float128 a2; + long double b2; + if (sizeof (long double) != 16) + return 1; + b = one + two; + /* eliminate removing volatile cast warning. */ + a2 = a; + b2 = b; + if (memcmp (&a2, &b2, 16) != 0) + return 1; + sprintf (buffer, "%lg", b); + return strcmp (buffer, "3") != 0; + } + } [add_options_for_long_double_ieee128 ""]] +} + +# Return the appropriate options to specify that long double uses the IBM +# 128-bit format on PowerPC. +proc add_options_for_long_double_ieee128 { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mlong-double-128 -Wno-psabi -mabi=ieeelongdouble" + } + return "$flags" +} + +# Check if GCC and GLIBC supports explicitly specifying that the long double +# format uses the IEEE 64-bit. Under little endian PowerPC Linux, you need +# GLIBC 2.32 or later to be able to use a different long double format for +# running a program than the system default. + +proc check_effective_target_long_double_64bit { } { + return [check_runtime_nocache long_double_64bit { + #include + #include + /* use volatile to prevent optimization. */ + volatile double a = 3.0; + volatile long double one = 1.0L; + volatile long double two = 2.0L; + volatile long double b; + char buffer[20]; + int main() + { + double a2; + long double b2; + if (sizeof (long double) != 8) + return 1; + b = one + two; + /* eliminate removing volatile cast warning. */ + a2 = a; + b2 = b; + if (memcmp (&a2, &b2, 16) != 0) + return 1; + sprintf (buffer, "%lg", b); + return strcmp (buffer, "3") != 0; + } + } [add_options_for_ppc_long_double_override_64bit ""]] +} + +# Return the appropriate options to specify that long double uses the IEEE +# 64-bit format on PowerPC. + +proc add_options_for_long_double_64bit { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mlong-double-64" + } + return "$flags" +} + +# Return 1 if the target supports executing VSX instructions, 0 +# otherwise. Cache the result. + +proc check_vsx_hw_available { } { + return [check_cached_effective_target vsx_hw_available { + # Some simulators are known to not support VSX instructions. + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] + || [istarget powerpc*-*-eabispe] + || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mvsx" + check_runtime_nocache vsx_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("xxlor vs0,vs0,vs0"); + #else + asm volatile ("xxlor 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing AltiVec instructions, 0 +# otherwise. Cache the result. + +proc check_vmx_hw_available { } { + return [check_cached_effective_target vmx_hw_available { + # Some simulators are known to not support VMX instructions. + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] } { + expr 0 + } else { + # Most targets don't require special flags for this test case, but + # Darwin does. Just to be sure, make sure VSX is not enabled for + # the altivec tests. + if { [istarget *-*-darwin*] + || [istarget *-*-aix*] } { + set options "-maltivec -mno-vsx" + } else { + set options "-mno-vsx" + } + check_runtime_nocache vmx_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("vor v0,v0,v0"); + #else + asm volatile ("vor 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +proc check_ppc_recip_hw_available { } { + return [check_cached_effective_target ppc_recip_hw_available { + # Some simulators may not support FRE/FRES/FRSQRTE/FRSQRTES + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + set options "-mpowerpc-gfxopt -mpowerpc-gpopt -mpopcntb" + check_runtime_nocache ppc_recip_hw_available { + volatile double d_recip, d_rsqrt, d_four = 4.0; + volatile float f_recip, f_rsqrt, f_four = 4.0f; + int main() + { + asm volatile ("fres %0,%1" : "=f" (f_recip) : "f" (f_four)); + asm volatile ("fre %0,%1" : "=d" (d_recip) : "d" (d_four)); + asm volatile ("frsqrtes %0,%1" : "=f" (f_rsqrt) : "f" (f_four)); + asm volatile ("frsqrte %0,%1" : "=f" (d_rsqrt) : "d" (d_four)); + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing AltiVec and Cell PPU +# instructions, 0 otherwise. Cache the result. + +proc check_effective_target_cell_hw { } { + return [check_cached_effective_target cell_hw_available { + # Some simulators are known to not support VMX and PPU instructions. + if { [istarget powerpc-*-eabi*] } { + expr 0 + } else { + # Most targets don't require special flags for this test + # case, but Darwin and AIX do. + if { [istarget *-*-darwin*] + || [istarget *-*-aix*] } { + set options "-maltivec -mcpu=cell" + } else { + set options "-mcpu=cell" + } + check_runtime_nocache cell_hw_available { + int main() + { + #ifdef __MACH__ + asm volatile ("vor v0,v0,v0"); + asm volatile ("lvlx v0,r0,r0"); + #else + asm volatile ("vor 0,0,0"); + asm volatile ("lvlx 0,0,0"); + #endif + return 0; + } + } $options + } + }] +} + +# Return 1 if the target supports executing 64-bit instructions, 0 +# otherwise. Cache the result. + +proc check_effective_target_powerpc64 { } { + global powerpc64_available_saved + global tool + + if [info exists powerpc64_available_saved] { + verbose "check_effective_target_powerpc64 returning saved $powerpc64_available_saved" 2 + } else { + set powerpc64_available_saved 0 + + # Some simulators are known to not support powerpc64 instructions. + if { [istarget powerpc-*-eabi*] || [istarget powerpc-ibm-aix*] } { + verbose "check_effective_target_powerpc64 returning 0" 2 + return $powerpc64_available_saved + } + + # Set up, compile, and execute a test program containing a 64-bit + # instruction. Include the current process ID in the file + # names to prevent conflicts with invocations for multiple + # testsuites. + set src ppc[pid].c + set exe ppc[pid].x + + set f [open $src "w"] + puts $f "int main() {" + puts $f "#ifdef __MACH__" + puts $f " asm volatile (\"extsw r0,r0\");" + puts $f "#else" + puts $f " asm volatile (\"extsw 0,0\");" + puts $f "#endif" + puts $f " return 0; }" + close $f + + set opts "additional_flags=-mcpu=G5" + + verbose "check_effective_target_powerpc64 compiling testfile $src" 2 + set lines [${tool}_target_compile $src $exe executable "$opts"] + file delete $src + + if [string match "" $lines] then { + # No error message, compilation succeeded. + set result [${tool}_load "./$exe" "" ""] + set status [lindex $result 0] + remote_file build delete $exe + verbose "check_effective_target_powerpc64 testfile status is <$status>" 2 + + if { $status == "pass" } then { + set powerpc64_available_saved 1 + } + } else { + verbose "check_effective_target_powerpc64 testfile compilation failed" 2 + } + } + + return $powerpc64_available_saved +} + +# GCC 3.4.0 for powerpc64-*-linux* included an ABI fix for passing +# complex float arguments. This affects gfortran tests that call cabsf +# in libm built by an earlier compiler. Return 0 if libm uses the same +# argument passing as the compiler under test, 1 otherwise. + +proc check_effective_target_broken_cplxf_arg { } { + # Skip the work for targets known not to be affected. + if { ![istarget powerpc*-*-linux*] || ![is-effective-target lp64] } { + return 0 + } + + return [check_cached_effective_target broken_cplxf_arg { + check_runtime_nocache broken_cplxf_arg { + #include + extern void abort (void); + float fabsf (float); + float cabsf (_Complex float); + int main () + { + _Complex float cf; + float f; + cf = 3 + 4.0fi; + f = cabsf (cf); + if (fabsf (f - 5.0) > 0.0001) + /* Yes, it's broken. */ + return 0; + /* All fine, not broken. */ + return 1; + } + } "-lm" + }] +} + +# Return 1 is this is a TI C6X target supporting C67X instructions +proc check_effective_target_ti_c67x { } { + return [check_no_compiler_messages ti_c67x assembly { + #if !defined(_TMS320C6700) + #error !_TMS320C6700 + #endif + }] +} + +# Return 1 is this is a TI C6X target supporting C64X+ instructions +proc check_effective_target_ti_c64xp { } { + return [check_no_compiler_messages ti_c64xp assembly { + #if !defined(_TMS320C6400_PLUS) + #error !_TMS320C6400_PLUS + #endif + }] +} + +# Check if a -march=... option is given, as part of (earlier) options. +proc check_effective_target_march_option { } { + return [check-flags [list "" { *-*-* } { "-march=*" } { "" } ]] +} + +proc check_alpha_max_hw_available { } { + return [check_runtime alpha_max_hw_available { + int main() { return __builtin_alpha_amask(1<<8) != 0; } + }] +} + +# Returns true iff the FUNCTION is available on the target system. +# (This is essentially a Tcl implementation of Autoconf's +# AC_CHECK_FUNC.) + +proc check_function_available { function } { + return [check_no_compiler_messages ${function}_available \ + executable [subst { + #ifdef __cplusplus + extern "C" + #endif + char $function (); + int main () { $function (); } + }] "-fno-builtin" ] +} + +# Returns true iff "fork" is available on the target system. + +proc check_fork_available {} { + if { [istarget *-*-vxworks*] } { + # VxWorks doesn't have fork but our way to test can't + # tell as we're doing partial links for kernel modules. + return 0 + } + return [check_function_available "fork"] +} + +# Returns true iff "mkfifo" is available on the target system. + +proc check_mkfifo_available {} { + if { [istarget *-*-cygwin*] } { + # Cygwin has mkfifo, but support is incomplete. + return 0 + } + + return [check_function_available "mkfifo"] +} + +# Returns true iff "__cxa_atexit" is used on the target system. + +proc check_cxa_atexit_available { } { + return [check_cached_effective_target cxa_atexit_available { + if { [istarget hppa*-*-hpux10*] } { + # HP-UX 10 doesn't have __cxa_atexit but subsequent test passes. + expr 0 + } elseif { [istarget *-*-vxworks] } { + # vxworks doesn't have __cxa_atexit but subsequent test passes. + expr 0 + } else { + check_runtime_nocache cxa_atexit_available { + // C++ + #include + static unsigned int count; + struct X + { + X() { count = 1; } + ~X() + { + if (count != 3) + exit(1); + count = 4; + } + }; + void f() + { + static X x; + } + struct Y + { + Y() { f(); count = 2; } + ~Y() + { + if (count != 2) + exit(1); + count = 3; + } + }; + Y y; + int main() { return 0; } + } + } + }] +} + +proc check_effective_target_objc2 { } { + return [check_no_compiler_messages objc2 object { + #ifdef __OBJC2__ + int dummy[1]; + #else + #error !__OBJC2__ + #endif + }] +} + +proc check_effective_target_next_runtime { } { + return [check_no_compiler_messages objc2 object { + #ifdef __NEXT_RUNTIME__ + int dummy[1]; + #else + #error !__NEXT_RUNTIME__ + #endif + }] +} + +# Return 1 if we're generating code for big-endian memory order. + +proc check_effective_target_be { } { + return [check_no_compiler_messages be object { + int dummy[__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? 1 : -1]; + }] +} + +# Return 1 if we're generating code for little-endian memory order. + +proc check_effective_target_le { } { + return [check_no_compiler_messages le object { + int dummy[__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? 1 : -1]; + }] +} + +# Return 1 if we're generating 32-bit code using default options, 0 +# otherwise. + +proc check_effective_target_ilp32 { } { + return [check_no_compiler_messages ilp32 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 4 + && sizeof (long) == 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating ia32 code using default options, 0 +# otherwise. + +proc check_effective_target_ia32 { } { + return [check_no_compiler_messages ia32 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 4 + && sizeof (long) == 4 ? 1 : -1] = { __i386__ }; + }] +} + +# Return 1 if we're generating x32 code using default options, 0 +# otherwise. + +proc check_effective_target_x32 { } { + return [check_no_compiler_messages x32 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 4 + && sizeof (long) == 4 ? 1 : -1] = { __x86_64__ }; + }] +} + +# Return 1 if we're generating 32-bit integers using default +# options, 0 otherwise. + +proc check_effective_target_int32 { } { + return [check_no_compiler_messages int32 object { + int dummy[sizeof (int) == 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 32-bit or larger integers using default +# options, 0 otherwise. + +proc check_effective_target_int32plus { } { + return [check_no_compiler_messages int32plus object { + int dummy[sizeof (int) >= 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 64-bit long long using default options, +# 0 otherwise. + +proc check_effective_target_longlong64 { } { + return [check_no_compiler_messages longlong64 object { + int dummy[sizeof (long long) == 8 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 32-bit or larger pointers using default +# options, 0 otherwise. + +proc check_effective_target_ptr32plus { } { + # The msp430 has 16-bit or 20-bit pointers. The 20-bit pointer is stored + # in a 32-bit slot when in memory, so sizeof(void *) returns 4, but it + # cannot really hold a 32-bit address, so we always return false here. + if { [istarget msp430-*-*] } { + return 0 + } + + return [check_no_compiler_messages ptr32plus object { + int dummy[sizeof (void *) >= 4 ? 1 : -1]; + }] +} + +# Return 1 if we support 16-bit or larger array and structure sizes +# using default options, 0 otherwise. +# This implies at least a 20-bit address space, as no targets have an address +# space between 16 and 20 bits. + +proc check_effective_target_size20plus { } { + return [check_no_compiler_messages size20plus object { + char dummy[65537L]; + }] +} + +# Return 1 if target supports function pointers, 0 otherwise. + +proc check_effective_target_function_pointers { } { + if { [istarget pru-*-*] } { + return [check_no_compiler_messages func_ptr_avail assembly { + #ifdef __PRU_EABI_GNU__ + #error unsupported + #endif + }] + } + return 1 +} + +# Return 1 if target supports arbitrarily large return values, 0 otherwise. + +proc check_effective_target_large_return_values { } { + if { [istarget pru-*-*] } { + return [check_no_compiler_messages large_return_values assembly { + #ifdef __PRU_EABI_GNU__ + #error unsupported + #endif + }] + } + return 1 +} +# Return 1 if we support 20-bit or larger array and structure sizes +# using default options, 0 otherwise. +# This implies at least a 24-bit address space, as no targets have an address +# space between 20 and 24 bits. + +proc check_effective_target_size24plus { } { + return [check_no_compiler_messages size24plus object { + char dummy[524289L]; + }] +} + +# Return 1 if we support 24-bit or larger array and structure sizes +# using default options, 0 otherwise. +# This implies at least a 32-bit address space, as no targets have an address +# space between 24 and 32 bits. + +proc check_effective_target_size32plus { } { + return [check_no_compiler_messages size32plus object { + char dummy[16777217L]; + }] +} + +# Returns 1 if we're generating 16-bit or smaller integers with the +# default options, 0 otherwise. + +proc check_effective_target_int16 { } { + return [check_no_compiler_messages int16 object { + int dummy[sizeof (int) < 4 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 64-bit code using default options, 0 +# otherwise. + +proc check_effective_target_lp64 { } { + return [check_no_compiler_messages lp64 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 8 + && sizeof (long) == 8 ? 1 : -1]; + }] +} + +# Return 1 if we're generating 64-bit code using default llp64 options, +# 0 otherwise. + +proc check_effective_target_llp64 { } { + return [check_no_compiler_messages llp64 object { + int dummy[sizeof (int) == 4 + && sizeof (void *) == 8 + && sizeof (long long) == 8 + && sizeof (long) == 4 ? 1 : -1]; + }] +} + +# Return 1 if long and int have different sizes, +# 0 otherwise. + +proc check_effective_target_long_neq_int { } { + return [check_no_compiler_messages long_ne_int object { + int dummy[sizeof (int) != sizeof (long) ? 1 : -1]; + }] +} + +# Return 1 if int size is equal to float size, +# 0 otherwise. + +proc check_effective_target_int_eq_float { } { + return [check_no_compiler_messages int_eq_float object { + int dummy[sizeof (int) >= sizeof (float) ? 1 : -1]; + }] +} + +# Return 1 if short size is equal to int size, +# 0 otherwise. + +proc check_effective_target_short_eq_int { } { + return [check_no_compiler_messages short_eq_int object { + int dummy[sizeof (short) == sizeof (int) ? 1 : -1]; + }] +} + +# Return 1 if pointer size is equal to short size, +# 0 otherwise. + +proc check_effective_target_ptr_eq_short { } { + return [check_no_compiler_messages ptr_eq_short object { + int dummy[sizeof (void *) == sizeof (short) ? 1 : -1]; + }] +} + +# Return 1 if pointer size is equal to long size, +# 0 otherwise. + +proc check_effective_target_ptr_eq_long { } { + # sizeof (void *) == 4 for msp430-elf -mlarge which is equal to + # sizeof (long). Avoid false positive. + if { [istarget msp430-*-*] } { + return 0 + } + return [check_no_compiler_messages ptr_eq_long object { + int dummy[sizeof (void *) == sizeof (long) ? 1 : -1]; + }] +} + +# Return 1 if the target supports long double larger than double, +# 0 otherwise. + +proc check_effective_target_large_long_double { } { + return [check_no_compiler_messages large_long_double object { + int dummy[sizeof(long double) > sizeof(double) ? 1 : -1]; + }] +} + +# Return 1 if the target supports double larger than float, +# 0 otherwise. + +proc check_effective_target_large_double { } { + return [check_no_compiler_messages large_double object { + int dummy[sizeof(double) > sizeof(float) ? 1 : -1]; + }] +} + +# Return 1 if the target supports long double of 128 bits, +# 0 otherwise. + +proc check_effective_target_longdouble128 { } { + return [check_no_compiler_messages longdouble128 object { + int dummy[sizeof(long double) == 16 ? 1 : -1]; + }] +} + +# Return 1 if the target supports long double of 64 bits, +# 0 otherwise. + +proc check_effective_target_longdouble64 { } { + return [check_no_compiler_messages longdouble64 object { + int dummy[sizeof(long double) == 8 ? 1 : -1]; + }] +} + +# Return 1 if the target supports double of 64 bits, +# 0 otherwise. + +proc check_effective_target_double64 { } { + return [check_no_compiler_messages double64 object { + int dummy[sizeof(double) == 8 ? 1 : -1]; + }] +} + +# Return 1 if the target supports double of at least 64 bits, +# 0 otherwise. + +proc check_effective_target_double64plus { } { + return [check_no_compiler_messages double64plus object { + int dummy[sizeof(double) >= 8 ? 1 : -1]; + }] +} + +# Return 1 if the target supports 'w' suffix on floating constant +# 0 otherwise. + +proc check_effective_target_has_w_floating_suffix { } { + set opts "" + if [check_effective_target_c++] { + append opts "-std=gnu++03" + } + return [check_no_compiler_messages w_fp_suffix object { + float dummy = 1.0w; + } "$opts"] +} + +# Return 1 if the target supports 'q' suffix on floating constant +# 0 otherwise. + +proc check_effective_target_has_q_floating_suffix { } { + set opts "" + if [check_effective_target_c++] { + append opts "-std=gnu++03" + } + return [check_no_compiler_messages q_fp_suffix object { + float dummy = 1.0q; + } "$opts"] +} + +# Return 1 if the target supports the _FloatN / _FloatNx type +# indicated in the function name, 0 otherwise. + +proc check_effective_target_float16 {} { + return [check_no_compiler_messages_nocache float16 object { + _Float16 foo (_Float16 x) { return x; } + } [add_options_for_float16 ""]] +} + +proc check_effective_target_float32 {} { + return [check_no_compiler_messages_nocache float32 object { + _Float32 x; + } [add_options_for_float32 ""]] +} + +proc check_effective_target_float64 {} { + return [check_no_compiler_messages_nocache float64 object { + _Float64 x; + } [add_options_for_float64 ""]] +} + +proc check_effective_target_float128 {} { + return [check_no_compiler_messages_nocache float128 object { + _Float128 x; + } [add_options_for_float128 ""]] +} + +proc check_effective_target_float32x {} { + return [check_no_compiler_messages_nocache float32x object { + _Float32x x; + } [add_options_for_float32x ""]] +} + +proc check_effective_target_float64x {} { + return [check_no_compiler_messages_nocache float64x object { + _Float64x x; + } [add_options_for_float64x ""]] +} + +proc check_effective_target_float128x {} { + return [check_no_compiler_messages_nocache float128x object { + _Float128x x; + } [add_options_for_float128x ""]] +} + +# Likewise, but runtime support for any special options used as well +# as compile-time support is required. + +proc check_effective_target_float16_runtime {} { + return [check_effective_target_float16] +} + +proc check_effective_target_float32_runtime {} { + return [check_effective_target_float32] +} + +proc check_effective_target_float64_runtime {} { + return [check_effective_target_float64] +} + +proc check_effective_target_float128_runtime {} { + if { ![check_effective_target_float128] } { + return 0 + } + if { [istarget powerpc*-*-*] } { + return [check_effective_target_base_quadfloat_support] + } + return 1 +} + +proc check_effective_target_float32x_runtime {} { + return [check_effective_target_float32x] +} + +proc check_effective_target_float64x_runtime {} { + if { ![check_effective_target_float64x] } { + return 0 + } + if { [istarget powerpc*-*-*] } { + return [check_effective_target_base_quadfloat_support] + } + return 1 +} + +proc check_effective_target_float128x_runtime {} { + return [check_effective_target_float128x] +} + +# Return 1 if the target hardware supports any options added for +# _FloatN and _FloatNx types, 0 otherwise. + +proc check_effective_target_floatn_nx_runtime {} { + if { [istarget powerpc*-*-aix*] } { + return 0 + } + if { [istarget powerpc*-*-*] } { + return [check_effective_target_base_quadfloat_support] + } + return 1 +} + +# Add options needed to use the _FloatN / _FloatNx type indicated in +# the function name. + +proc add_options_for_float16 { flags } { + if { [istarget arm*-*-*] } { + return "$flags -mfp16-format=ieee" + } + return "$flags" +} + +proc add_options_for_float32 { flags } { + return "$flags" +} + +proc add_options_for_float64 { flags } { + return "$flags" +} + +proc add_options_for_float128 { flags } { + return [add_options_for___float128 "$flags"] +} + +proc add_options_for_float32x { flags } { + return "$flags" +} + +proc add_options_for_float64x { flags } { + return [add_options_for___float128 "$flags"] +} + +proc add_options_for_float128x { flags } { + return "$flags" +} + +# Return 1 if the target supports __float128, +# 0 otherwise. + +proc check_effective_target___float128 { } { + if { [istarget powerpc*-*-*] } { + return [check_ppc_float128_sw_available] + } + if { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] } { + return 1 + } + return 0 +} + +proc add_options_for___float128 { flags } { + if { [istarget powerpc*-*-*] } { + return "$flags -mfloat128 -mvsx" + } + return "$flags" +} + +# Return 1 if the target supports any special run-time requirements +# for __float128 or _Float128, +# 0 otherwise. + +proc check_effective_target_base_quadfloat_support { } { + if { [istarget powerpc*-*-*] } { + return [check_vsx_hw_available] + } + return 1 +} + +# Return 1 if the target supports all four forms of fused multiply-add +# (fma, fms, fnma, and fnms) for both float and double. + +proc check_effective_target_scalar_all_fma { } { + return [istarget aarch64*-*-*] +} + +# Return 1 if the target supports compiling fixed-point, +# 0 otherwise. + +proc check_effective_target_fixed_point { } { + return [check_no_compiler_messages fixed_point object { + _Sat _Fract x; _Sat _Accum y; + }] +} + +# Return 1 if the target supports compiling decimal floating point, +# 0 otherwise. + +proc check_effective_target_dfp_nocache { } { + verbose "check_effective_target_dfp_nocache: compiling source" 2 + set ret [check_no_compiler_messages_nocache dfp object { + float x __attribute__((mode(DD))); + }] + verbose "check_effective_target_dfp_nocache: returning $ret" 2 + return $ret +} + +proc check_effective_target_dfprt_nocache { } { + return [check_runtime_nocache dfprt { + typedef float d64 __attribute__((mode(DD))); + d64 x = 1.2df, y = 2.3dd, z; + int main () { z = x + y; return 0; } + }] +} + +# Return 1 if the target supports compiling Decimal Floating Point, +# 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_dfp { } { + return [check_cached_effective_target dfp { + check_effective_target_dfp_nocache + }] +} + +# Return 1 if the target supports linking and executing Decimal Floating +# Point, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_dfprt { } { + return [check_cached_effective_target dfprt { + check_effective_target_dfprt_nocache + }] +} + +# Return 1 iff target has unsigned plain 'char' by default. + +proc check_effective_target_unsigned_char {} { + return [check_no_compiler_messages unsigned_char assembly { + char ar[(char)-1]; + }] +} + +proc check_effective_target_powerpc_popcntb_ok { } { + return [check_cached_effective_target powerpc_popcntb_ok { + + # Disable on Darwin. + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + check_runtime_nocache powerpc_popcntb_ok { + volatile int r; + volatile int a = 0x12345678; + int main() + { + asm volatile ("popcntb %0,%1" : "=r" (r) : "r" (a)); + return 0; + } + } "-mcpu=power5" + } + }] +} + +# Return 1 if the target supports executing DFP hardware instructions, +# 0 otherwise. Cache the result. + +proc check_dfp_hw_available { } { + return [check_cached_effective_target dfp_hw_available { + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + check_runtime_nocache dfp_hw_available { + volatile _Decimal64 r; + volatile _Decimal64 a = 4.0DD; + volatile _Decimal64 b = 2.0DD; + int main() + { + asm volatile ("dadd %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + asm volatile ("dsub %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + asm volatile ("dmul %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + asm volatile ("ddiv %0,%1,%2" : "=d" (r) : "d" (a), "d" (b)); + return 0; + } + } "-mcpu=power6 -mhard-float" + } + }] +} + +# Return 1 if the target supports compiling and assembling UCN, 0 otherwise. + +proc check_effective_target_ucn_nocache { } { + # -std=c99 is only valid for C + if [check_effective_target_c] { + set ucnopts "-std=c99" + } else { + set ucnopts "" + } + verbose "check_effective_target_ucn_nocache: compiling source" 2 + set ret [check_no_compiler_messages_nocache ucn object { + int \u00C0; + } $ucnopts] + verbose "check_effective_target_ucn_nocache: returning $ret" 2 + return $ret +} + +# Return 1 if the target supports compiling and assembling UCN, 0 otherwise. +# +# This won't change for different subtargets, so cache the result. + +proc check_effective_target_ucn { } { + return [check_cached_effective_target ucn { + check_effective_target_ucn_nocache + }] +} + +# Return 1 if the target needs a command line argument to enable a SIMD +# instruction set. + +proc check_effective_target_vect_cmdline_needed { } { + global et_vect_cmdline_needed_target_name + + if { ![info exists et_vect_cmdline_needed_target_name] } { + set et_vect_cmdline_needed_target_name "" + } + + # If the target has changed since we set the cached value, clear it. + set current_target [current_target_name] + if { $current_target != $et_vect_cmdline_needed_target_name } { + verbose "check_effective_target_vect_cmdline_needed: `$et_vect_cmdline_needed_target_name' `$current_target'" 2 + set et_vect_cmdline_needed_target_name $current_target + if { [info exists et_vect_cmdline_needed_saved] } { + verbose "check_effective_target_vect_cmdline_needed: removing cached result" 2 + unset et_vect_cmdline_needed_saved + } + } + + return [check_cached_effective_target vect_cmdline_needed { + if { [istarget alpha*-*-*] + || [istarget ia64-*-*] + || (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && ![is-effective-target ia32]) + || ([istarget powerpc*-*-*] + && ([check_effective_target_powerpc_spe] + || [check_effective_target_powerpc_altivec])) + || ([istarget sparc*-*-*] && [check_effective_target_sparc_vis]) + || ([istarget arm*-*-*] && [check_effective_target_arm_neon]) + || [istarget aarch64*-*-*] + || [istarget amdgcn*-*-*]} { + return 0 + } else { + return 1 + }}] +} + +# Return 1 if the target supports hardware vectors of int, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_int { } { + return [check_cached_effective_target_indexed vect_int { + expr { + [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget amdgcn-*-*] + || [istarget sparc*-*-*] + || [istarget alpha*-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_loongson_mmi] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + }}] +} + +# Return 1 if the target supports hardware vectorization of complex additions of +# byte, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_complex_add_byte { } { + return [check_cached_effective_target_indexed vect_complex_add_byte { + expr { + ([check_effective_target_aarch64_sve2] + && [check_effective_target_aarch64_little_endian]) + || ([check_effective_target_arm_v8_1m_mve_fp_ok] + && [check_effective_target_arm_little_endian]) + }}] +} + +# Return 1 if the target supports hardware vectorization of complex additions of +# short, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_complex_add_short { } { + return [check_cached_effective_target_indexed vect_complex_add_short { + expr { + ([check_effective_target_aarch64_sve2] + && [check_effective_target_aarch64_little_endian]) + || ([check_effective_target_arm_v8_1m_mve_fp_ok] + && [check_effective_target_arm_little_endian]) + }}] +} + +# Return 1 if the target supports hardware vectorization of complex additions of +# int, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_complex_add_int { } { + return [check_cached_effective_target_indexed vect_complex_add_int { + expr { + ([check_effective_target_aarch64_sve2] + && [check_effective_target_aarch64_little_endian]) + || ([check_effective_target_arm_v8_1m_mve_fp_ok] + && [check_effective_target_arm_little_endian]) + }}] +} + +# Return 1 if the target supports hardware vectorization of complex additions of +# long, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_complex_add_long { } { + return [check_cached_effective_target_indexed vect_complex_add_long { + expr { + ([check_effective_target_aarch64_sve2] + && [check_effective_target_aarch64_little_endian]) + || ([check_effective_target_arm_v8_1m_mve_fp_ok] + && [check_effective_target_arm_little_endian]) + }}] +} + +# Return 1 if the target supports hardware vectorization of complex additions of +# half, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_complex_add_half { } { + return [check_cached_effective_target_indexed vect_complex_add_half { + expr { + ([check_effective_target_arm_v8_3a_fp16_complex_neon_ok] + && ([check_effective_target_aarch64_little_endian] + || [check_effective_target_arm_little_endian])) + || ([check_effective_target_aarch64_sve2] + && [check_effective_target_aarch64_little_endian]) + || ([check_effective_target_arm_v8_1m_mve_fp_ok] + && [check_effective_target_arm_little_endian]) + }}] +} + +# Return 1 if the target supports hardware vectorization of complex additions of +# float, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_complex_add_float { } { + return [check_cached_effective_target_indexed vect_complex_add_float { + expr { + ([check_effective_target_arm_v8_3a_complex_neon_ok] + && ([check_effective_target_aarch64_little_endian] + || [check_effective_target_arm_little_endian])) + || ([check_effective_target_aarch64_sve2] + && [check_effective_target_aarch64_little_endian]) + || ([check_effective_target_arm_v8_1m_mve_fp_ok] + && [check_effective_target_arm_little_endian]) + }}] +} + +# Return 1 if the target supports hardware vectorization of complex additions of +# double, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_complex_add_double { } { + return [check_cached_effective_target_indexed vect_complex_add_double { + expr { + (([check_effective_target_arm_v8_3a_complex_neon_ok] + && [check_effective_target_aarch64_little_endian]) + || ([check_effective_target_aarch64_sve2] + && [check_effective_target_aarch64_little_endian])) + }}] +} + +# Return 1 if the target supports signed int->float conversion +# + +proc check_effective_target_vect_intfloat_cvt { } { + return [check_cached_effective_target_indexed vect_intfloat_cvt { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vxe2]) }}] +} + +# Return 1 if the target supports signed double->int conversion +# + +proc check_effective_target_vect_doubleint_cvt { } { + return [check_cached_effective_target_indexed vect_doubleint_cvt { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_no_compiler_messages vect_doubleint_cvt assembly { + #ifdef __tune_atom__ + # error No double vectorizer support. + #endif + }]) + || [istarget aarch64*-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +# Return 1 if the target supports signed int->double conversion +# + +proc check_effective_target_vect_intdouble_cvt { } { + return [check_cached_effective_target_indexed vect_intdouble_cvt { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_no_compiler_messages vect_intdouble_cvt assembly { + #ifdef __tune_atom__ + # error No double vectorizer support. + #endif + }]) + || [istarget aarch64*-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +#Return 1 if we're supporting __int128 for target, 0 otherwise. + +proc check_effective_target_int128 { } { + return [check_no_compiler_messages int128 object { + int dummy[ + #ifndef __SIZEOF_INT128__ + -1 + #else + 1 + #endif + ]; + }] +} + +# Return 1 if the target supports unsigned int->float conversion +# + +proc check_effective_target_vect_uintfloat_cvt { } { + return [check_cached_effective_target_indexed vect_uintfloat_cvt { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vxe2]) }}] +} + + +# Return 1 if the target supports signed float->int conversion +# + +proc check_effective_target_vect_floatint_cvt { } { + return [check_cached_effective_target_indexed vect_floatint_cvt { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vxe2]) }}] +} + +# Return 1 if the target supports unsigned float->int conversion +# + +proc check_effective_target_vect_floatuint_cvt { } { + return [check_cached_effective_target_indexed vect_floatuint_cvt { + expr { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [istarget amdgcn-*-*] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vxe2]) }}] +} + +# Return 1 if peeling for alignment might be profitable on the target +# + +proc check_effective_target_vect_peeling_profitable { } { + return [check_cached_effective_target_indexed vect_peeling_profitable { + expr { ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [check_effective_target_vect_element_align_preferred] }}] +} + +# Return 1 if the target supports #pragma omp declare simd, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_simd_clones { } { + # On i?86/x86_64 #pragma omp declare simd builds a sse2, avx, + # avx2 and avx512f clone. Only the right clone for the + # specified arch will be chosen, but still we need to at least + # be able to assemble avx512f. + return [check_cached_effective_target_indexed vect_simd_clones { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_effective_target_avx512f]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if this is a AArch64 target supporting big endian +proc check_effective_target_aarch64_big_endian { } { + return [check_no_compiler_messages aarch64_big_endian assembly { + #if !defined(__aarch64__) || !defined(__AARCH64EB__) + #error !__aarch64__ || !__AARCH64EB__ + #endif + }] +} + +# Return 1 if this is a AArch64 target supporting little endian +proc check_effective_target_aarch64_little_endian { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + + return [check_no_compiler_messages aarch64_little_endian assembly { + #if !defined(__aarch64__) || defined(__AARCH64EB__) + #error FOO + #endif + }] +} + +# Return 1 if this is an AArch64 target supporting SVE. +proc check_effective_target_aarch64_sve { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_no_compiler_messages aarch64_sve assembly { + #if !defined (__ARM_FEATURE_SVE) + #error FOO + #endif + }] +} + +# Return 1 if this is an AArch64 target supporting SVE2. +proc check_effective_target_aarch64_sve2 { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_no_compiler_messages aarch64_sve2 assembly { + #if !defined (__ARM_FEATURE_SVE2) + #error FOO + #endif + }] +} + +# Return 1 if this is an AArch64 target only supporting SVE (not SVE2). +proc check_effective_target_aarch64_sve1_only { } { + return [expr { [check_effective_target_aarch64_sve] + && ![check_effective_target_aarch64_sve2] }] +} + +# Return the size in bits of an SVE vector, or 0 if the size is variable. +proc aarch64_sve_bits { } { + return [check_cached_effective_target aarch64_sve_bits { + global tool + + set src dummy[pid].c + set f [open $src "w"] + puts $f "int bits = __ARM_FEATURE_SVE_BITS;" + close $f + set output [${tool}_target_compile $src "" preprocess ""] + file delete $src + + regsub {.*bits = ([^;]*);.*} $output {\1} bits + expr { $bits } + }] +} + +# Return 1 if this is a compiler supporting ARC atomic operations +proc check_effective_target_arc_atomic { } { + return [check_no_compiler_messages arc_atomic assembly { + #if !defined(__ARC_ATOMIC__) + #error FOO + #endif + }] +} + +# Return 1 if this is an arm target using 32-bit instructions +proc check_effective_target_arm32 { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm32 assembly { + #if !defined(__arm__) || (defined(__thumb__) && !defined(__thumb2__)) + #error !__arm || __thumb__ && !__thumb2__ + #endif + }] +} + +# Return 1 if this is an arm target not using Thumb +proc check_effective_target_arm_nothumb { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm_nothumb assembly { + #if !defined(__arm__) || (defined(__thumb__) || defined(__thumb2__)) + #error !__arm__ || __thumb || __thumb2__ + #endif + }] +} + +# Return 1 if this is a little-endian ARM target +proc check_effective_target_arm_little_endian { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm_little_endian assembly { + #if !defined(__arm__) || !defined(__ARMEL__) + #error !__arm__ || !__ARMEL__ + #endif + }] +} + +# Return 1 if this is an ARM target that only supports aligned vector accesses +proc check_effective_target_arm_vect_no_misalign { } { + if { ![istarget arm*-*-*] } { + return 0 + } + + return [check_no_compiler_messages arm_vect_no_misalign assembly { + #if !defined(__arm__) \ + || (defined(__ARM_FEATURE_UNALIGNED) \ + && defined(__ARMEL__)) + #error !__arm__ || (__ARMEL__ && __ARM_FEATURE_UNALIGNED) + #endif + }] +} + + +# Return 1 if this is an ARM target supporting -mfloat-abi=soft. Some +# multilibs may be incompatible with this option. + +proc check_effective_target_arm_soft_ok { } { + return [check_no_compiler_messages arm_soft_ok object { + #include + int dummy; + int main (void) { return 0; } + } "-mfloat-abi=soft"] +} + +# Return 1 if this is an ARM target supporting -mfloat-abi=soft even +# for linking. Some multilibs may be incompatible with this option, +# and some linkers may reject incompatible options. + +proc check_effective_target_arm_soft_ok_link { } { + return [check_no_compiler_messages arm_soft_ok_link executable { + #include + int dummy; + int main (void) { return 0; } + } "-mfloat-abi=soft"] +} + +# Return 1 if this is an ARM target supporting -mfpu=vfp with an +# appropriate abi. + +proc check_effective_target_arm_vfp_ok_nocache { } { + global et_arm_vfp_flags + set et_arm_vfp_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"-mfpu=vfp" "-mfpu=vfp -mfloat-abi=softfp" "-mfpu=vfp -mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_vfp_ok object { + #ifndef __ARM_FP + #error __ARM_FP not defined + #endif + } "$flags"] } { + set et_arm_vfp_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_vfp_ok { } { + return [check_cached_effective_target arm_vfp_ok \ + check_effective_target_arm_vfp_ok_nocache] +} + +# Add the options needed to compile code with -mfpu=vfp. We need either +# -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already +# specified by the multilib, use it. + +proc add_options_for_arm_vfp { flags } { + if { ! [check_effective_target_arm_vfp_ok] } { + return "$flags" + } + global et_arm_vfp_flags + return "$flags $et_arm_vfp_flags" +} + +# Return 1 if this is an ARM target supporting -mfpu=vfp3 +# -mfloat-abi=softfp. + +proc check_effective_target_arm_vfp3_ok { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_vfp3_ok object { + int dummy; + } "-mfpu=vfp3 -mfloat-abi=softfp"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target supporting -mfpu=fp-armv8 +# -mfloat-abi=softfp. +proc check_effective_target_arm_v8_vfp_ok {} { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_v8_vfp_ok object { + int foo (void) + { + __asm__ volatile ("vrinta.f32.f32 s0, s0"); + return 0; + } + } "-mfpu=fp-armv8 -mfloat-abi=softfp"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target supporting -mfpu=vfp +# -mfloat-abi=hard. Some multilibs may be incompatible with these +# options. + +proc check_effective_target_arm_hard_vfp_ok { } { + if { [check_effective_target_arm32] + && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } { + return [check_no_compiler_messages arm_hard_vfp_ok executable { + int main() { return 0;} + } "-mfpu=vfp -mfloat-abi=hard"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target defining __ARM_FP. We may need +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_fp_flags to the +# best options to add. + +proc check_effective_target_arm_fp_ok_nocache { } { + global et_arm_fp_flags + set et_arm_fp_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_fp_ok object { + #ifndef __ARM_FP + #error __ARM_FP not defined + #endif + } "$flags"] } { + set et_arm_fp_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp_ok { } { + return [check_cached_effective_target arm_fp_ok \ + check_effective_target_arm_fp_ok_nocache] +} + +# Add the options needed to define __ARM_FP. We need either +# -mfloat-abi=softfp or -mfloat-abi=hard, but if one is already +# specified by the multilib, use it. + +proc add_options_for_arm_fp { flags } { + if { ! [check_effective_target_arm_fp_ok] } { + return "$flags" + } + global et_arm_fp_flags + return "$flags $et_arm_fp_flags" +} + +# Return 1 if this is an ARM target defining __ARM_FP with +# double-precision support. We may need -mfloat-abi=softfp or +# equivalent options. Some multilibs may be incompatible with these +# options. Also set et_arm_fp_dp_flags to the best options to add. + +proc check_effective_target_arm_fp_dp_ok_nocache { } { + global et_arm_fp_dp_flags + set et_arm_fp_dp_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_fp_dp_ok object { + #ifndef __ARM_FP + #error __ARM_FP not defined + #endif + #if ((__ARM_FP & 8) == 0) + #error __ARM_FP indicates that double-precision is not supported + #endif + } "$flags"] } { + set et_arm_fp_dp_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp_dp_ok { } { + return [check_cached_effective_target arm_fp_dp_ok \ + check_effective_target_arm_fp_dp_ok_nocache] +} + +# Add the options needed to define __ARM_FP with double-precision +# support. We need either -mfloat-abi=softfp or -mfloat-abi=hard, but +# if one is already specified by the multilib, use it. + +proc add_options_for_arm_fp_dp { flags } { + if { ! [check_effective_target_arm_fp_dp_ok] } { + return "$flags" + } + global et_arm_fp_dp_flags + return "$flags $et_arm_fp_dp_flags" +} + +# Return 1 if this is an ARM target that supports DSP multiply with +# current multilib flags. + +proc check_effective_target_arm_dsp { } { + return [check_no_compiler_messages arm_dsp assembly { + #ifndef __ARM_FEATURE_DSP + #error not DSP + #endif + #include + int i; + }] +} + +# Return 1 if this is an ARM target that supports unaligned word/halfword +# load/store instructions. + +proc check_effective_target_arm_unaligned { } { + return [check_no_compiler_messages arm_unaligned assembly { + #ifndef __ARM_FEATURE_UNALIGNED + #error no unaligned support + #endif + int i; + }] +} + +# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_crypto_flags to the +# best options to add. + +proc check_effective_target_arm_crypto_ok_nocache { } { + global et_arm_crypto_flags + set et_arm_crypto_flags "" + if { [check_effective_target_arm_v8_neon_ok] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=crypto-neon-fp-armv8" "-mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache arm_crypto_ok object { + #include "arm_neon.h" + uint8x16_t + foo (uint8x16_t a, uint8x16_t b) + { + return vaeseq_u8 (a, b); + } + } "$flags"] } { + set et_arm_crypto_flags $flags + return 1 + } + } + } + + return 0 +} + +# Return 1 if this is an ARM target supporting -mfpu=crypto-neon-fp-armv8 + +proc check_effective_target_arm_crypto_ok { } { + return [check_cached_effective_target arm_crypto_ok \ + check_effective_target_arm_crypto_ok_nocache] +} + +# Add options for crypto extensions. +proc add_options_for_arm_crypto { flags } { + if { ! [check_effective_target_arm_crypto_ok] } { + return "$flags" + } + global et_arm_crypto_flags + return "$flags $et_arm_crypto_flags" +} + +# Add the options needed for NEON. We need either -mfloat-abi=softfp +# or -mfloat-abi=hard, but if one is already specified by the +# multilib, use it. Similarly, if a -mfpu option already enables +# NEON, do not add -mfpu=neon. + +proc add_options_for_arm_neon { flags } { + if { ! [check_effective_target_arm_neon_ok] } { + return "$flags" + } + global et_arm_neon_flags + return "$flags $et_arm_neon_flags" +} + +proc add_options_for_arm_v8_vfp { flags } { + if { ! [check_effective_target_arm_v8_vfp_ok] } { + return "$flags" + } + return "$flags -mfpu=fp-armv8 -mfloat-abi=softfp" +} + +proc add_options_for_arm_v8_neon { flags } { + if { ! [check_effective_target_arm_v8_neon_ok] } { + return "$flags" + } + global et_arm_v8_neon_flags + return "$flags $et_arm_v8_neon_flags -march=armv8-a" +} + +# Add the options needed for ARMv8.1 Adv.SIMD. Also adds the ARMv8 NEON +# options for AArch64 and for ARM. + +proc add_options_for_arm_v8_1a_neon { flags } { + if { ! [check_effective_target_arm_v8_1a_neon_ok] } { + return "$flags" + } + global et_arm_v8_1a_neon_flags + return "$flags $et_arm_v8_1a_neon_flags" +} + +# Add the options needed for ARMv8.2 with the scalar FP16 extension. +# Also adds the ARMv8 FP options for ARM and for AArch64. + +proc add_options_for_arm_v8_2a_fp16_scalar { flags } { + if { ! [check_effective_target_arm_v8_2a_fp16_scalar_ok] } { + return "$flags" + } + global et_arm_v8_2a_fp16_scalar_flags + return "$flags $et_arm_v8_2a_fp16_scalar_flags" +} + +# Add the options needed for ARMv8.2 with the FP16 extension. Also adds +# the ARMv8 NEON options for ARM and for AArch64. + +proc add_options_for_arm_v8_2a_fp16_neon { flags } { + if { ! [check_effective_target_arm_v8_2a_fp16_neon_ok] } { + return "$flags" + } + global et_arm_v8_2a_fp16_neon_flags + return "$flags $et_arm_v8_2a_fp16_neon_flags" +} + +proc add_options_for_arm_crc { flags } { + if { ! [check_effective_target_arm_crc_ok] } { + return "$flags" + } + global et_arm_crc_flags + return "$flags $et_arm_crc_flags" +} + +# Add the options needed for NEON. We need either -mfloat-abi=softfp +# or -mfloat-abi=hard, but if one is already specified by the +# multilib, use it. Similarly, if a -mfpu option already enables +# NEON, do not add -mfpu=neon. + +proc add_options_for_arm_neonv2 { flags } { + if { ! [check_effective_target_arm_neonv2_ok] } { + return "$flags" + } + global et_arm_neonv2_flags + return "$flags $et_arm_neonv2_flags" +} + +# Add the options needed for vfp3. +proc add_options_for_arm_vfp3 { flags } { + if { ! [check_effective_target_arm_vfp3_ok] } { + return "$flags" + } + return "$flags -mfpu=vfp3 -mfloat-abi=softfp" +} + +# Return 1 if this is an ARM target supporting -mfpu=neon +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_neon_flags to the +# best options to add. + +proc check_effective_target_arm_neon_ok_nocache { } { + global et_arm_neon_flags + set et_arm_neon_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon" "-mfpu=neon -mfloat-abi=softfp" "-mfpu=neon -mfloat-abi=softfp -march=armv7-a" "-mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard" "-mfpu=neon -mfloat-abi=hard -march=armv7-a"} { + if { [check_no_compiler_messages_nocache arm_neon_ok object { + #include + int dummy; + #ifndef __ARM_NEON__ + #error not NEON + #endif + /* Avoid the case where a test adds -mfpu=neon, but the toolchain is + configured for -mcpu=arm926ej-s, for example. */ + #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M' + #error Architecture does not support NEON. + #endif + } "$flags"] } { + set et_arm_neon_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_ok { } { + return [check_cached_effective_target arm_neon_ok \ + check_effective_target_arm_neon_ok_nocache] +} + + +# Return 1 if this is an ARM target supporting the SIMD32 intrinsics +# from arm_acle.h. Some multilibs may be incompatible with these options. +# Also set et_arm_simd32_flags to the best options to add. +# arm_acle.h includes stdint.h which can cause trouble with incompatible +# -mfloat-abi= options. + +proc check_effective_target_arm_simd32_ok_nocache { } { + global et_arm_simd32_flags + set et_arm_simd32_flags "" + foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache arm_simd32_ok object { + #include + int dummy; + #ifndef __ARM_FEATURE_SIMD32 + #error not SIMD32 + #endif + } "$flags"] } { + set et_arm_simd32_flags $flags + return 1 + } + } + + return 0 +} + +proc check_effective_target_arm_simd32_ok { } { + return [check_cached_effective_target arm_simd32_ok \ + check_effective_target_arm_simd32_ok_nocache] +} + +proc add_options_for_arm_simd32 { flags } { + if { ! [check_effective_target_arm_simd32_ok] } { + return "$flags" + } + global et_arm_simd32_flags + return "$flags $et_arm_simd32_flags" +} + +# Return 1 if this is an ARM target supporting the __ssat and __usat +# saturation intrinsics from arm_acle.h. Some multilibs may be +# incompatible with these options. Also set et_arm_sat_flags to the +# best options to add. arm_acle.h includes stdint.h which can cause +# trouble with incompatible -mfloat-abi= options. + +proc check_effective_target_arm_sat_ok_nocache { } { + global et_arm_sat_flags + set et_arm_sat_flags "" + foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard -mfpu=vfp"} { + if { [check_no_compiler_messages_nocache et_arm_sat_flags object { + #include + int dummy; + #ifndef __ARM_FEATURE_SAT + #error not SAT + #endif + } "$flags"] } { + set et_arm_sat_flags $flags + return 1 + } + } + + return 0 +} + +proc check_effective_target_arm_sat_ok { } { + return [check_cached_effective_target et_arm_sat_flags \ + check_effective_target_arm_sat_ok_nocache] +} + +proc add_options_for_arm_sat { flags } { + if { ! [check_effective_target_arm_sat_ok] } { + return "$flags" + } + global et_arm_sat_flags + return "$flags $et_arm_sat_flags" +} + +# Return 1 if this is an ARM target supporting the DSP intrinsics from +# arm_acle.h. Some multilibs may be incompatible with these options. +# Also set et_arm_dsp_flags to the best options to add. +# arm_acle.h includes stdint.h which can cause trouble with incompatible +# -mfloat-abi= options. +# check_effective_target_arm_dsp also exists, which checks the current +# multilib, without trying other options. + +proc check_effective_target_arm_dsp_ok_nocache { } { + global et_arm_dsp_flags + set et_arm_dsp_flags "" + foreach flags {"" "-march=armv5te" "-march=armv5te -mfloat-abi=softfp" "-march=armv5te -mfloat-abi=hard"} { + if { [check_no_compiler_messages_nocache et_arm_dsp_ok object { + #include + int dummy; + #ifndef __ARM_FEATURE_DSP + #error not DSP + #endif + } "$flags"] } { + set et_arm_dsp_flags $flags + return 1 + } + } + + return 0 +} + +proc check_effective_target_arm_dsp_ok { } { + return [check_cached_effective_target et_arm_dsp_flags \ + check_effective_target_arm_dsp_ok_nocache] +} + +proc add_options_for_arm_dsp { flags } { + if { ! [check_effective_target_arm_dsp_ok] } { + return "$flags" + } + global et_arm_dsp_flags + return "$flags $et_arm_dsp_flags" +} + +# Return 1 if this is an ARM target supporting -mfpu=neon without any +# -mfloat-abi= option. Useful in tests where add_options is not +# supported (such as lto tests). + +proc check_effective_target_arm_neon_ok_no_float_abi_nocache { } { + if { [check_effective_target_arm32] } { + foreach flags {"-mfpu=neon"} { + if { [check_no_compiler_messages_nocache arm_neon_ok_no_float_abi object { + #include + int dummy; + #ifndef __ARM_NEON__ + #error not NEON + #endif + /* Avoid the case where a test adds -mfpu=neon, but the toolchain is + configured for -mcpu=arm926ej-s, for example. */ + #if __ARM_ARCH < 7 || __ARM_ARCH_PROFILE == 'M' + #error Architecture does not support NEON. + #endif + } "$flags"] } { + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_ok_no_float_abi { } { + return [check_cached_effective_target arm_neon_ok_no_float_abi \ + check_effective_target_arm_neon_ok_no_float_abi_nocache] +} + +proc check_effective_target_arm_crc_ok_nocache { } { + global et_arm_crc_flags + set et_arm_crc_flags "-march=armv8-a+crc" + return [check_no_compiler_messages_nocache arm_crc_ok object { + #if !defined (__ARM_FEATURE_CRC32) + #error FOO + #endif + #include + } "$et_arm_crc_flags"] +} + +proc check_effective_target_arm_crc_ok { } { + return [check_cached_effective_target arm_crc_ok \ + check_effective_target_arm_crc_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-fp16 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_neon_fp16_flags to +# the best options to add. + +proc check_effective_target_arm_neon_fp16_ok_nocache { } { + global et_arm_neon_fp16_flags + global et_arm_neon_flags + set et_arm_neon_fp16_flags "" + if { [check_effective_target_arm32] + && [check_effective_target_arm_neon_ok] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" + "-mfpu=neon-fp16 -mfloat-abi=softfp" + "-mfp16-format=ieee" + "-mfloat-abi=softfp -mfp16-format=ieee" + "-mfpu=neon-fp16 -mfp16-format=ieee" + "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} { + if { [check_no_compiler_messages_nocache arm_neon_fp16_ok object { + #include "arm_neon.h" + float16x4_t + foo (float32x4_t arg) + { + return vcvt_f16_f32 (arg); + } + } "$et_arm_neon_flags $flags"] } { + set et_arm_neon_fp16_flags [concat $et_arm_neon_flags $flags] + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_fp16_ok { } { + return [check_cached_effective_target arm_neon_fp16_ok \ + check_effective_target_arm_neon_fp16_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-fp16 +# and -mfloat-abi=softfp together. Some multilibs may be +# incompatible with these options. Also set et_arm_neon_softfp_fp16_flags to +# the best options to add. + +proc check_effective_target_arm_neon_softfp_fp16_ok_nocache { } { + global et_arm_neon_softfp_fp16_flags + global et_arm_neon_flags + set et_arm_neon_softfp_fp16_flags "" + if { [check_effective_target_arm32] + && [check_effective_target_arm_neon_ok] } { + foreach flags {"-mfpu=neon-fp16 -mfloat-abi=softfp" + "-mfpu=neon-fp16 -mfloat-abi=softfp -mfp16-format=ieee"} { + if { [check_no_compiler_messages_nocache arm_neon_softfp_fp16_ok object { + #include "arm_neon.h" + float16x4_t + foo (float32x4_t arg) + { + return vcvt_f16_f32 (arg); + } + } "$et_arm_neon_flags $flags"] } { + set et_arm_neon_softfp_fp16_flags [concat $et_arm_neon_flags $flags] + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neon_softfp_fp16_ok { } { + return [check_cached_effective_target arm_neon_softfp_fp16_ok \ + check_effective_target_arm_neon_softfp_fp16_ok_nocache] +} + + + +proc check_effective_target_arm_neon_fp16_hw { } { + if {! [check_effective_target_arm_neon_fp16_ok] } { + return 0 + } + global et_arm_neon_fp16_flags + check_runtime arm_neon_fp16_hw { + int + main (int argc, char **argv) + { + asm ("vcvt.f32.f16 q1, d0"); + return 0; + } + } $et_arm_neon_fp16_flags +} + +proc add_options_for_arm_neon_fp16 { flags } { + if { ! [check_effective_target_arm_neon_fp16_ok] } { + return "$flags" + } + global et_arm_neon_fp16_flags + return "$flags $et_arm_neon_fp16_flags" +} + +proc add_options_for_arm_neon_softfp_fp16 { flags } { + if { ! [check_effective_target_arm_neon_softfp_fp16_ok] } { + return "$flags" + } + global et_arm_neon_softfp_fp16_flags + return "$flags $et_arm_neon_softfp_fp16_flags" +} + +proc add_options_for_aarch64_sve { flags } { + if { ![istarget aarch64*-*-*] || [check_effective_target_aarch64_sve] } { + return "$flags" + } + return "$flags -march=armv8.2-a+sve" +} + +# Return 1 if this is an ARM target supporting the FP16 alternative +# format. Some multilibs may be incompatible with the options needed. Also +# set et_arm_neon_fp16_flags to the best options to add. + +proc check_effective_target_arm_fp16_alternative_ok_nocache { } { + if { [istarget *-*-vxworks7*] } { + # Not supported by the target system. + return 0 + } + global et_arm_neon_fp16_flags + set et_arm_neon_fp16_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" + "-mfpu=neon-fp16 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_fp16_alternative_ok object { + #if !defined (__ARM_FP16_FORMAT_ALTERNATIVE) + #error __ARM_FP16_FORMAT_ALTERNATIVE not defined + #endif + } "$flags -mfp16-format=alternative"] } { + set et_arm_neon_fp16_flags "$flags -mfp16-format=alternative" + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp16_alternative_ok { } { + return [check_cached_effective_target arm_fp16_alternative_ok \ + check_effective_target_arm_fp16_alternative_ok_nocache] +} + +# Return 1 if this is an ARM target supports specifying the FP16 none +# format. Some multilibs may be incompatible with the options needed. + +proc check_effective_target_arm_fp16_none_ok_nocache { } { + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp16" + "-mfpu=neon-fp16 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_fp16_none_ok object { + #if defined (__ARM_FP16_FORMAT_ALTERNATIVE) + #error __ARM_FP16_FORMAT_ALTERNATIVE defined + #endif + #if defined (__ARM_FP16_FORMAT_IEEE) + #error __ARM_FP16_FORMAT_IEEE defined + #endif + } "$flags -mfp16-format=none"] } { + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_fp16_none_ok { } { + return [check_cached_effective_target arm_fp16_none_ok \ + check_effective_target_arm_fp16_none_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-fp-armv8 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_v8_neon_flags to the +# best options to add. + +proc check_effective_target_arm_v8_neon_ok_nocache { } { + global et_arm_v8_neon_flags + set et_arm_v8_neon_flags "" + if { [check_effective_target_arm32] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-fp-armv8" "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache arm_v8_neon_ok object { + #if __ARM_ARCH < 8 + #error not armv8 or later + #endif + #include "arm_neon.h" + void + foo () + { + __asm__ volatile ("vrintn.f32 q0, q0"); + } + } "$flags -march=armv8-a"] } { + set et_arm_v8_neon_flags $flags + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_v8_neon_ok { } { + return [check_cached_effective_target arm_v8_neon_ok \ + check_effective_target_arm_v8_neon_ok_nocache] +} + +# Return 1 if this is an ARM target supporting -mfpu=neon-vfpv4 +# -mfloat-abi=softfp or equivalent options. Some multilibs may be +# incompatible with these options. Also set et_arm_neonv2_flags to the +# best options to add. + +proc check_effective_target_arm_neonv2_ok_nocache { } { + global et_arm_neonv2_flags + global et_arm_neon_flags + set et_arm_neonv2_flags "" + if { [check_effective_target_arm32] + && [check_effective_target_arm_neon_ok] } { + foreach flags {"" "-mfloat-abi=softfp" "-mfpu=neon-vfpv4" "-mfpu=neon-vfpv4 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache arm_neonv2_ok object { + #include "arm_neon.h" + float32x2_t + foo (float32x2_t a, float32x2_t b, float32x2_t c) + { + return vfma_f32 (a, b, c); + } + } "$et_arm_neon_flags $flags"] } { + set et_arm_neonv2_flags [concat $et_arm_neon_flags $flags] + return 1 + } + } + } + + return 0 +} + +proc check_effective_target_arm_neonv2_ok { } { + return [check_cached_effective_target arm_neonv2_ok \ + check_effective_target_arm_neonv2_ok_nocache] +} + +# Add the options needed for VFP FP16 support. We need either +# -mfloat-abi=softfp or -mfloat-abi=hard. If one is already specified by +# the multilib, use it. + +proc add_options_for_arm_fp16 { flags } { + if { ! [check_effective_target_arm_fp16_ok] } { + return "$flags" + } + global et_arm_fp16_flags + return "$flags $et_arm_fp16_flags" +} + +# Add the options needed to enable support for IEEE format +# half-precision support. This is valid for ARM targets. + +proc add_options_for_arm_fp16_ieee { flags } { + if { ! [check_effective_target_arm_fp16_ok] } { + return "$flags" + } + global et_arm_fp16_flags + return "$flags $et_arm_fp16_flags -mfp16-format=ieee" +} + +# Add the options needed to enable support for ARM Alternative format +# half-precision support. This is valid for ARM targets. + +proc add_options_for_arm_fp16_alternative { flags } { + if { ! [check_effective_target_arm_fp16_ok] } { + return "$flags" + } + global et_arm_fp16_flags + return "$flags $et_arm_fp16_flags -mfp16-format=alternative" +} + +# Return 1 if this is an ARM target that can support a VFP fp16 variant. +# Skip multilibs that are incompatible with these options and set +# et_arm_fp16_flags to the best options to add. This test is valid for +# ARM only. + +proc check_effective_target_arm_fp16_ok_nocache { } { + global et_arm_fp16_flags + set et_arm_fp16_flags "" + if { ! [check_effective_target_arm32] } { + return 0; + } + if [check-flags \ + [list "" { *-*-* } { "-mfpu=*" } \ + { "-mfpu=*fp16*" "-mfpu=*fpv[4-9]*" \ + "-mfpu=*fpv[1-9][0-9]*" "-mfpu=*fp-armv8*" } ]] { + # Multilib flags would override -mfpu. + return 0 + } + if [check-flags [list "" { *-*-* } { "-mfloat-abi=soft" } { "" } ]] { + # Must generate floating-point instructions. + return 0 + } + if [check_effective_target_arm_hf_eabi] { + # Use existing float-abi and force an fpu which supports fp16 + set et_arm_fp16_flags "-mfpu=vfpv4" + return 1; + } + if [check-flags [list "" { *-*-* } { "-mfpu=*" } { "" } ]] { + # The existing -mfpu value is OK; use it, but add softfp. + set et_arm_fp16_flags "-mfloat-abi=softfp" + return 1; + } + # Add -mfpu for a VFP fp16 variant since there is no preprocessor + # macro to check for this support. + set flags "-mfpu=vfpv4 -mfloat-abi=softfp" + if { [check_no_compiler_messages_nocache arm_fp16_ok assembly { + int dummy; + } "$flags"] } { + set et_arm_fp16_flags "$flags" + return 1 + } + + return 0 +} + +proc check_effective_target_arm_fp16_ok { } { + return [check_cached_effective_target arm_fp16_ok \ + check_effective_target_arm_fp16_ok_nocache] +} + +# Return 1 if the target supports executing VFP FP16 instructions, 0 +# otherwise. This test is valid for ARM only. + +proc check_effective_target_arm_fp16_hw { } { + if {! [check_effective_target_arm_fp16_ok] } { + return 0 + } + global et_arm_fp16_flags + check_runtime arm_fp16_hw { + int + main (int argc, char **argv) + { + __fp16 a = 1.0; + float r; + asm ("vcvtb.f32.f16 %0, %1" + : "=w" (r) : "w" (a) + : /* No clobbers. */); + return (r == 1.0) ? 0 : 1; + } + } "$et_arm_fp16_flags -mfp16-format=ieee" +} + +# Creates a series of routines that return 1 if the given architecture +# can be selected and a routine to give the flags to select that architecture +# Note: Extra flags may be added to disable options from newer compilers +# (Thumb in particular - but others may be added in the future). +# Warning: Do not use check_effective_target_arm_arch_*_ok for architecture +# extension (eg. ARMv8.1-A) since there is no macro defined for them. See +# how only __ARM_ARCH_8A__ is checked for ARMv8.1-A. +# Usage: /* { dg-require-effective-target arm_arch_v5_ok } */ +# /* { dg-add-options arm_arch_v5t } */ +# /* { dg-require-effective-target arm_arch_v5t_multilib } */ +foreach { armfunc armflag armdefs } { + v4 "-march=armv4 -marm" __ARM_ARCH_4__ + v4t "-march=armv4t -mfloat-abi=softfp" __ARM_ARCH_4T__ + v4t_arm "-march=armv4t -marm" __ARM_ARCH_4T__ + v4t_thumb "-march=armv4t -mthumb -mfloat-abi=softfp" __ARM_ARCH_4T__ + v5t "-march=armv5t -mfloat-abi=softfp" __ARM_ARCH_5T__ + v5t_arm "-march=armv5t -marm" __ARM_ARCH_5T__ + v5t_thumb "-march=armv5t -mthumb -mfloat-abi=softfp" __ARM_ARCH_5T__ + v5te "-march=armv5te -mfloat-abi=softfp" __ARM_ARCH_5TE__ + v5te_arm "-march=armv5te -marm" __ARM_ARCH_5TE__ + v5te_thumb "-march=armv5te -mthumb -mfloat-abi=softfp" __ARM_ARCH_5TE__ + v6 "-march=armv6 -mfloat-abi=softfp" __ARM_ARCH_6__ + v6_arm "-march=armv6 -marm" __ARM_ARCH_6__ + v6_thumb "-march=armv6 -mthumb -mfloat-abi=softfp" __ARM_ARCH_6__ + v6k "-march=armv6k -mfloat-abi=softfp" __ARM_ARCH_6K__ + v6k_arm "-march=armv6k -marm" __ARM_ARCH_6K__ + v6k_thumb "-march=armv6k -mthumb -mfloat-abi=softfp" __ARM_ARCH_6K__ + v6t2 "-march=armv6t2" __ARM_ARCH_6T2__ + v6z "-march=armv6z -mfloat-abi=softfp" __ARM_ARCH_6Z__ + v6z_arm "-march=armv6z -marm" __ARM_ARCH_6Z__ + v6z_thumb "-march=armv6z -mthumb -mfloat-abi=softfp" __ARM_ARCH_6Z__ + v6m "-march=armv6-m -mthumb -mfloat-abi=soft" __ARM_ARCH_6M__ + v7a "-march=armv7-a" __ARM_ARCH_7A__ + v7r "-march=armv7-r" __ARM_ARCH_7R__ + v7m "-march=armv7-m -mthumb" __ARM_ARCH_7M__ + v7em "-march=armv7e-m -mthumb" __ARM_ARCH_7EM__ + v7ve "-march=armv7ve -marm" + "__ARM_ARCH_7A__ && __ARM_FEATURE_IDIV" + v8a "-march=armv8-a" __ARM_ARCH_8A__ + v8a_hard "-march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=hard" __ARM_ARCH_8A__ + v8_1a "-march=armv8.1-a" __ARM_ARCH_8A__ + v8_2a "-march=armv8.2-a" __ARM_ARCH_8A__ + v8r "-march=armv8-r" __ARM_ARCH_8R__ + v8m_base "-march=armv8-m.base -mthumb -mfloat-abi=soft" + __ARM_ARCH_8M_BASE__ + v8m_main "-march=armv8-m.main -mthumb" __ARM_ARCH_8M_MAIN__ + v8_1m_main "-march=armv8.1-m.main -mthumb" __ARM_ARCH_8M_MAIN__ + v9a "-march=armv9-a" __ARM_ARCH_9A__ } { + eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] { + proc check_effective_target_arm_arch_FUNC_ok { } { + return [check_no_compiler_messages arm_arch_FUNC_ok assembly { + #if !(DEFS) + #error !(DEFS) + #endif + int + main (void) + { + return 0; + } + } "FLAG" ] + } + + proc add_options_for_arm_arch_FUNC { flags } { + return "$flags FLAG" + } + + proc check_effective_target_arm_arch_FUNC_multilib { } { + return [check_runtime arm_arch_FUNC_multilib { + int + main (void) + { + return 0; + } + } [add_options_for_arm_arch_FUNC ""]] + } + }] +} + +# Return 1 if GCC was configured with --with-mode= +proc check_effective_target_default_mode { } { + + return [check_configured_with "with-mode="] +} + +# Return 1 if this is an ARM target where -marm causes ARM to be +# used (not Thumb) + +proc check_effective_target_arm_arm_ok { } { + return [check_no_compiler_messages arm_arm_ok assembly { + #if !defined (__arm__) || defined (__thumb__) || defined (__thumb2__) + #error !__arm__ || __thumb__ || __thumb2__ + #endif + } "-marm"] +} + + +# Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be +# used. + +proc check_effective_target_arm_thumb1_ok { } { + return [check_no_compiler_messages arm_thumb1_ok assembly { + #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__) + #error !__arm__ || !__thumb__ || __thumb2__ + #endif + int foo (int i) { return i; } + } "-mthumb"] +} + +# Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be +# used. + +proc check_effective_target_arm_thumb2_ok { } { + return [check_no_compiler_messages arm_thumb2_ok assembly { + #if !defined(__thumb2__) + #error !__thumb2__ + #endif + int foo (int i) { return i; } + } "-mthumb"] +} + +# Return 1 if this is an ARM target where Thumb-1 is used without options +# added by the test. + +proc check_effective_target_arm_thumb1 { } { + return [check_no_compiler_messages arm_thumb1 assembly { + #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__) + #error !__arm__ || !__thumb__ || __thumb2__ + #endif + int i; + } ""] +} + +# Return 1 if this is an ARM target where Thumb-2 is used without options +# added by the test. + +proc check_effective_target_arm_thumb2 { } { + return [check_no_compiler_messages arm_thumb2 assembly { + #if !defined(__thumb2__) + #error !__thumb2__ + #endif + int i; + } ""] +} + +# Return 1 if this is an ARM target where conditional execution is available. + +proc check_effective_target_arm_cond_exec { } { + return [check_no_compiler_messages arm_cond_exec assembly { + #if defined(__arm__) && defined(__thumb__) && !defined(__thumb2__) + #error FOO + #endif + int i; + } ""] +} + +# Return 1 if this is an ARM cortex-M profile cpu + +proc check_effective_target_arm_cortex_m { } { + if { ![istarget arm*-*-*] } { + return 0 + } + return [check_no_compiler_messages arm_cortex_m assembly { + #if defined(__ARM_ARCH_ISA_ARM) + #error __ARM_ARCH_ISA_ARM is defined + #endif + int i; + } "-mthumb"] +} + +# Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be +# used and MOVT/MOVW instructions to be available. + +proc check_effective_target_arm_thumb1_movt_ok {} { + if [check_effective_target_arm_thumb1_ok] { + return [check_no_compiler_messages arm_movt object { + int + foo (void) + { + asm ("movt r0, #42"); + } + } "-mthumb"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be +# used and CBZ and CBNZ instructions are available. + +proc check_effective_target_arm_thumb1_cbz_ok {} { + if [check_effective_target_arm_thumb1_ok] { + return [check_no_compiler_messages arm_movt object { + int + foo (void) + { + asm ("cbz r0, 2f\n2:"); + } + } "-mthumb"] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target where ARMv8-M Security Extensions is +# available. + +proc check_effective_target_arm_cmse_ok {} { + return [check_no_compiler_messages arm_cmse object { + int + foo (void) + { + asm ("bxns r0"); + } + } "-mcmse"]; +} + +# Return 1 if the target supports executing CMSE instructions, 0 +# otherwise. Cache the result. + +proc check_effective_target_arm_cmse_hw { } { + return [check_runtime arm_cmse_hw_available { + int main (void) + { + unsigned id_pfr1; + asm ("ldr\t%0, =0xe000ed44\n" \ + "ldr\t%0, [%0]\n" \ + "sg" : "=l" (id_pfr1)); + /* Exit with code 0 iff security extension is available. */ + return !(id_pfr1 & 0xf0); + } + } "-mcmse"] +} + +# Return 1 if the target supports executing MVE instructions, 0 +# otherwise. + +proc check_effective_target_arm_mve_hw {} { + return [check_runtime arm_mve_hw_available { + int + main (void) + { + long long a = 16; + int b = 3; + asm ("sqrshrl %Q1, %R1, #64, %2" + : "=l" (a) + : "0" (a), "r" (b)); + return (a != 2); + } + } [add_options_for_arm_v8_1m_mve_fp ""]] +} + +# Return 1 if this is an ARM target where ARMv8-M Security Extensions with +# clearing instructions (clrm, vscclrm, vstr/vldr with FPCXT) is available. + +proc check_effective_target_arm_cmse_clear_ok {} { + return [check_no_compiler_messages arm_cmse_clear object { + int + foo (void) + { + asm ("clrm {r1, r2}"); + } + } "-mcmse"]; +} + +# Return 1 if this compilation turns on string_ops_prefer_neon on. + +proc check_effective_target_arm_tune_string_ops_prefer_neon { } { + return [check_no_messages_and_pattern arm_tune_string_ops_prefer_neon "@string_ops_prefer_neon:\t1" assembly { + int foo (void) { return 0; } + } "-O2 -mprint-tune-info" ] +} + +# Return 1 if the target supports executing NEON instructions, 0 +# otherwise. Cache the result. + +proc check_effective_target_arm_neon_hw { } { + return [check_runtime arm_neon_hw_available { + int + main (void) + { + long long a = 0, b = 1; + asm ("vorr %P0, %P1, %P2" + : "=w" (a) + : "0" (a), "w" (b)); + return (a != 1); + } + } [add_options_for_arm_neon ""]] +} + +# Return true if this is an AArch64 target that can run SVE code. + +proc check_effective_target_aarch64_sve_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_sve_hw_available { + int + main (void) + { + asm volatile ("ptrue p0.b"); + return 0; + } + } [add_options_for_aarch64_sve ""]] +} + +# Return true if this is an AArch64 target that can run SVE2 code. + +proc check_effective_target_aarch64_sve2_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_sve2_hw_available { + int + main (void) + { + asm volatile ("addp z0.b, p0/m, z0.b, z1.b"); + return 0; + } + }] +} + +# Return true if this is an AArch64 target that can run SVE code and +# if its SVE vectors have exactly BITS bits. + +proc aarch64_sve_hw_bits { bits } { + if { ![check_effective_target_aarch64_sve_hw] } { + return 0 + } + return [check_runtime aarch64_sve${bits}_hw [subst { + int + main (void) + { + int res; + asm volatile ("cntd %0" : "=r" (res)); + if (res * 64 != $bits) + __builtin_abort (); + return 0; + } + }] [add_options_for_aarch64_sve ""]] +} + +# Return true if this is an AArch64 target that can run SVE code and +# if its SVE vectors have exactly 256 bits. + +foreach N { 128 256 512 1024 2048 } { + eval [string map [list N $N] { + proc check_effective_target_aarch64_sveN_hw { } { + return [aarch64_sve_hw_bits N] + } + }] +} + +proc check_effective_target_arm_neonv2_hw { } { + return [check_runtime arm_neon_hwv2_available { + #include "arm_neon.h" + int + main (void) + { + float32x2_t a, b, c; + asm ("vfma.f32 %P0, %P1, %P2" + : "=w" (a) + : "w" (b), "w" (c)); + return 0; + } + } [add_options_for_arm_neonv2 ""]] +} + +# ID_AA64PFR1_EL1.BT using bits[3:0] == 1 implies BTI implimented. +proc check_effective_target_aarch64_bti_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_bti_hw_available { + int + main (void) + { + int a; + asm volatile ("mrs %0, id_aa64pfr1_el1" : "=r" (a)); + return !((a & 0xf) == 1); + } + } "-O2" ] +} + +# Return 1 if the target supports executing the armv8.3-a FJCVTZS +# instruction. +proc check_effective_target_aarch64_fjcvtzs_hw { } { + if { ![istarget aarch64*-*-*] } { + return 0 + } + return [check_runtime aarch64_fjcvtzs_hw_available { + int + main (void) + { + double in = 25.1; + int out; + asm volatile ("fjcvtzs %w0, %d1" + : "=r" (out) + : "w" (in) + : /* No clobbers. */); + return out != 25; + } + } "-march=armv8.3-a" ] +} + +# Return 1 if GCC was configured with --enable-standard-branch-protection +proc check_effective_target_default_branch_protection { } { + return [check_configured_with "enable-standard-branch-protection"] +} + +# Return 1 if this is an ARM target supporting -mfloat-abi=softfp. + +proc check_effective_target_arm_softfp_ok { } { + return [check_no_compiler_messages arm_softfp_ok object { + #include + int dummy; + int main (void) { return 0; } + } "-mfloat-abi=softfp"] +} + +# Return 1 if this is an ARM target supporting -mfloat-abi=hard. + +proc check_effective_target_arm_hard_ok { } { + return [check_no_compiler_messages arm_hard_ok object { + #include + int dummy; + int main (void) { return 0; } + } "-mfloat-abi=hard"] +} + +# Return 1 if this is an ARM target supporting MVE. +proc check_effective_target_arm_mve { } { + if { ![istarget arm*-*-*] } { + return 0 + } + return [check_no_compiler_messages arm_mve assembly { + #if !defined (__ARM_FEATURE_MVE) + #error FOO + #endif + }] +} + +# Return 1 if the target supports ARMv8.1-M MVE with floating point +# instructions, 0 otherwise. The test is valid for ARM. +# Record the command line options needed. + +proc check_effective_target_arm_v8_1m_mve_fp_ok_nocache { } { + global et_arm_v8_1m_mve_fp_flags + set et_arm_v8_1m_mve_fp_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve.fp" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve.fp"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_1m_mve_fp_ok object { + #include + #if !(__ARM_FEATURE_MVE & 2) + #error "__ARM_FEATURE_MVE for floating point not defined" + #endif + #if __ARM_BIG_ENDIAN + #error "MVE intrinsics are not supported in Big-Endian mode." + #endif + } "$flags -mthumb"] } { + set et_arm_v8_1m_mve_fp_flags "$flags -mthumb --save-temps" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_1m_mve_fp_ok { } { + return [check_cached_effective_target arm_v8_1m_mve_fp_ok \ + check_effective_target_arm_v8_1m_mve_fp_ok_nocache] +} + +proc add_options_for_arm_v8_1m_mve_fp { flags } { + if { ! [check_effective_target_arm_v8_1m_mve_fp_ok] } { + return "$flags" + } + global et_arm_v8_1m_mve_fp_flags + return "$flags $et_arm_v8_1m_mve_fp_flags" +} + +# Return 1 if the target supports the ARMv8.1 Adv.SIMD extension, 0 +# otherwise. The test is valid for AArch64 and ARM. Record the command +# line options needed. + +proc check_effective_target_arm_v8_1a_neon_ok_nocache { } { + global et_arm_v8_1a_neon_flags + set et_arm_v8_1a_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. Start with the empty set + # since AArch64 only needs the -march setting. + foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \ + "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { + foreach arches { "-march=armv8-a+rdma" "-march=armv8.1-a" } { + if { [check_no_compiler_messages_nocache arm_v8_1a_neon_ok object { + #if !defined (__ARM_FEATURE_QRDMX) + #error "__ARM_FEATURE_QRDMX not defined" + #endif + } "$flags $arches"] } { + set et_arm_v8_1a_neon_flags "$flags $arches" + return 1 + } + } + } + + return 0; +} + +proc check_effective_target_arm_v8_1a_neon_ok { } { + return [check_cached_effective_target arm_v8_1a_neon_ok \ + check_effective_target_arm_v8_1a_neon_ok_nocache] +} + +# Return 1 if the target supports ARMv8.2 scalar FP16 arithmetic +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache { } { + global et_arm_v8_2a_fp16_scalar_flags + set et_arm_v8_2a_fp16_scalar_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfpu=fp-armv8" "-mfloat-abi=softfp" \ + "-mfpu=fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_fp16_scalar_ok object { + #if !defined (__ARM_FEATURE_FP16_SCALAR_ARITHMETIC) + #error "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC not defined" + #endif + } "$flags -march=armv8.2-a+fp16"] } { + set et_arm_v8_2a_fp16_scalar_flags "$flags -march=armv8.2-a+fp16" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_fp16_scalar_ok { } { + return [check_cached_effective_target arm_v8_2a_fp16_scalar_ok \ + check_effective_target_arm_v8_2a_fp16_scalar_ok_nocache] +} + +# Return 1 if the target supports ARMv8.2 Adv.SIMD FP16 arithmetic +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_fp16_neon_ok_nocache { } { + global et_arm_v8_2a_fp16_neon_flags + set et_arm_v8_2a_fp16_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfpu=neon-fp-armv8" "-mfloat-abi=softfp" \ + "-mfpu=neon-fp-armv8 -mfloat-abi=softfp"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_fp16_neon_ok object { + #if !defined (__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) + #error "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC not defined" + #endif + } "$flags -march=armv8.2-a+fp16"] } { + set et_arm_v8_2a_fp16_neon_flags "$flags -march=armv8.2-a+fp16" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_fp16_neon_ok { } { + return [check_cached_effective_target arm_v8_2a_fp16_neon_ok \ + check_effective_target_arm_v8_2a_fp16_neon_ok_nocache] +} + +# Return 1 if the target supports ARMv8.2 Adv.SIMD Dot Product +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache { } { + global et_arm_v8_2a_dotprod_neon_flags + set et_arm_v8_2a_dotprod_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_dotprod_neon_ok object { + #include + #if !defined (__ARM_FEATURE_DOTPROD) + #error "__ARM_FEATURE_DOTPROD not defined" + #endif + } "$flags -march=armv8.2-a+dotprod"] } { + set et_arm_v8_2a_dotprod_neon_flags "$flags -march=armv8.2-a+dotprod" + return 1 + } + } + + return 0; +} + +# Return 1 if the target supports ARMv8.1-M MVE +# instructions, 0 otherwise. The test is valid for ARM. +# Record the command line options needed. + +proc check_effective_target_arm_v8_1m_mve_ok_nocache { } { + global et_arm_v8_1m_mve_flags + set et_arm_v8_1m_mve_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=auto -march=armv8.1-m.main+mve" "-mfloat-abi=hard -mfpu=auto -march=armv8.1-m.main+mve"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_1m_mve_ok object { + #if !defined (__ARM_FEATURE_MVE) + #error "__ARM_FEATURE_MVE not defined" + #endif + #if __ARM_BIG_ENDIAN + #error "MVE intrinsics are not supported in Big-Endian mode." + #endif + #include + } "$flags -mthumb"] } { + set et_arm_v8_1m_mve_flags "$flags -mthumb --save-temps" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_1m_mve_ok { } { + return [check_cached_effective_target arm_v8_1m_mve_ok \ + check_effective_target_arm_v8_1m_mve_ok_nocache] +} + +proc add_options_for_arm_v8_1m_mve { flags } { + if { ! [check_effective_target_arm_v8_1m_mve_ok] } { + return "$flags" + } + global et_arm_v8_1m_mve_flags + return "$flags $et_arm_v8_1m_mve_flags" +} + +proc check_effective_target_arm_v8_2a_dotprod_neon_ok { } { + return [check_cached_effective_target arm_v8_2a_dotprod_neon_ok \ + check_effective_target_arm_v8_2a_dotprod_neon_ok_nocache] +} + +proc add_options_for_arm_v8_2a_dotprod_neon { flags } { + if { ! [check_effective_target_arm_v8_2a_dotprod_neon_ok] } { + return "$flags" + } + global et_arm_v8_2a_dotprod_neon_flags + return "$flags $et_arm_v8_2a_dotprod_neon_flags" +} + +# Return 1 if the target supports ARMv8.2+i8mm Adv.SIMD Dot Product +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_2a_i8mm_ok_nocache { } { + global et_arm_v8_2a_i8mm_flags + set et_arm_v8_2a_i8mm_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8" } { + if { [check_no_compiler_messages_nocache \ + arm_v8_2a_i8mm_ok object { + #include + #if !defined (__ARM_FEATURE_MATMUL_INT8) + #error "__ARM_FEATURE_MATMUL_INT8 not defined" + #endif + } "$flags -march=armv8.2-a+i8mm"] } { + set et_arm_v8_2a_i8mm_flags "$flags -march=armv8.2-a+i8mm" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_i8mm_ok { } { + return [check_cached_effective_target arm_v8_2a_i8mm_ok \ + check_effective_target_arm_v8_2a_i8mm_ok_nocache] +} + +proc add_options_for_arm_v8_2a_i8mm { flags } { + if { ! [check_effective_target_arm_v8_2a_i8mm_ok] } { + return "$flags" + } + global et_arm_v8_2a_i8mm_flags + return "$flags $et_arm_v8_2a_i8mm_flags" +} + +# Return 1 if the target supports FP16 VFMAL and VFMSL +# instructions, 0 otherwise. +# Record the command line options needed. + +proc check_effective_target_arm_fp16fml_neon_ok_nocache { } { + global et_arm_fp16fml_neon_flags + set et_arm_fp16fml_neon_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8"} { + if { [check_no_compiler_messages_nocache \ + arm_fp16fml_neon_ok assembly { + #include + float32x2_t + foo (float32x2_t r, float16x4_t a, float16x4_t b) + { + return vfmlal_high_f16 (r, a, b); + } + } "$flags -march=armv8.2-a+fp16fml"] } { + set et_arm_fp16fml_neon_flags "$flags -march=armv8.2-a+fp16fml" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_fp16fml_neon_ok { } { + return [check_cached_effective_target arm_fp16fml_neon_ok \ + check_effective_target_arm_fp16fml_neon_ok_nocache] +} + +proc add_options_for_arm_fp16fml_neon { flags } { + if { ! [check_effective_target_arm_fp16fml_neon_ok] } { + return "$flags" + } + global et_arm_fp16fml_neon_flags + return "$flags $et_arm_fp16fml_neon_flags" +} + +# Return 1 if the target supports BFloat16 SIMD instructions, 0 otherwise. +# The test is valid for ARM and for AArch64. + +proc check_effective_target_arm_v8_2a_bf16_neon_ok_nocache { } { + global et_arm_v8_2a_bf16_neon_flags + set et_arm_v8_2a_bf16_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + foreach flags {"" "-mfloat-abi=softfp -mfpu=neon-fp-armv8" "-mfloat-abi=hard -mfpu=neon-fp-armv8" } { + if { [check_no_compiler_messages_nocache arm_v8_2a_bf16_neon_ok object { + #include + #if !defined (__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) + #error "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC not defined" + #endif + } "$flags -march=armv8.2-a+bf16"] } { + set et_arm_v8_2a_bf16_neon_flags "$flags -march=armv8.2-a+bf16" + return 1 + } + } + + return 0; +} + +proc check_effective_target_arm_v8_2a_bf16_neon_ok { } { + return [check_cached_effective_target arm_v8_2a_bf16_neon_ok \ + check_effective_target_arm_v8_2a_bf16_neon_ok_nocache] +} + +proc add_options_for_arm_v8_2a_bf16_neon { flags } { + if { ! [check_effective_target_arm_v8_2a_bf16_neon_ok] } { + return "$flags" + } + global et_arm_v8_2a_bf16_neon_flags + return "$flags $et_arm_v8_2a_bf16_neon_flags" +} + +# A series of routines are created to 1) check if a given architecture is +# effective (check_effective_target_*_ok) and then 2) give the corresponding +# flags that enable the architecture (add_options_for_*). +# The series includes: +# arm_v8m_main_cde: Armv8-m CDE (Custom Datapath Extension). +# arm_v8m_main_cde_fp: Armv8-m CDE with FP registers. +# arm_v8_1m_main_cde_mve: Armv8.1-m CDE with MVE. +# Usage: +# /* { dg-require-effective-target arm_v8m_main_cde_ok } */ +# /* { dg-add-options arm_v8m_main_cde } */ +# The tests are valid for Arm. + +foreach { armfunc armflag armdef arminc } { + arm_v8m_main_cde + "-march=armv8-m.main+cdecp0+cdecp6 -mthumb" + "defined (__ARM_FEATURE_CDE)" + "" + arm_v8m_main_cde_fp + "-march=armv8-m.main+fp+cdecp0+cdecp6 -mthumb -mfpu=auto" + "defined (__ARM_FEATURE_CDE) && defined (__ARM_FP)" + "" + arm_v8_1m_main_cde_mve + "-march=armv8.1-m.main+mve+cdecp0+cdecp6 -mthumb -mfpu=auto" + "defined (__ARM_FEATURE_CDE) && defined (__ARM_FEATURE_MVE)" + "#include " + arm_v8_1m_main_cde_mve_fp + "-march=armv8.1-m.main+mve.fp+cdecp0+cdecp6 -mthumb -mfpu=auto" + "defined (__ARM_FEATURE_CDE) || __ARM_FEATURE_MVE == 3" + "#include " + } { + eval [string map [list FUNC $armfunc FLAG $armflag DEF $armdef INC $arminc ] { + proc check_effective_target_FUNC_ok_nocache { } { + global et_FUNC_flags + set et_FUNC_flags "" + + if { ![istarget arm*-*-*] } { + return 0; + } + + if { [check_no_compiler_messages_nocache FUNC_ok assembly { + #if !(DEF) + #error "DEF failed" + #endif + #include + INC + } "FLAG"] } { + set et_FUNC_flags "FLAG" + return 1 + } + + return 0; + } + + proc check_effective_target_FUNC_ok { } { + return [check_cached_effective_target FUNC_ok \ + check_effective_target_FUNC_ok_nocache] + } + + proc add_options_for_FUNC { flags } { + if { ! [check_effective_target_FUNC_ok] } { + return "$flags" + } + global et_FUNC_flags + return "$flags $et_FUNC_flags" + } + + proc check_effective_target_FUNC_multilib { } { + if { ! [check_effective_target_FUNC_ok] } { + return 0; + } + return [check_runtime FUNC_multilib { + #if !(DEF) + #error "DEF failed" + #endif + #include + INC + int + main (void) + { + return 0; + } + } [add_options_for_FUNC ""]] + } + }] +} + +# Return 1 if the target supports executing ARMv8 NEON instructions, 0 +# otherwise. + +proc check_effective_target_arm_v8_neon_hw { } { + return [check_runtime arm_v8_neon_hw_available { + #include "arm_neon.h" + int + main (void) + { + float32x2_t a = { 1.0f, 2.0f }; + #ifdef __ARM_ARCH_ISA_A64 + asm ("frinta %0.2s, %1.2s" + : "=w" (a) + : "w" (a)); + #else + asm ("vrinta.f32 %P0, %P1" + : "=w" (a) + : "0" (a)); + #endif + return a[0] == 2.0f; + } + } [add_options_for_arm_v8_neon ""]] +} + +# Return 1 if the target supports executing the ARMv8.1 Adv.SIMD extension, 0 +# otherwise. The test is valid for AArch64 and ARM. + +proc check_effective_target_arm_v8_1a_neon_hw { } { + if { ![check_effective_target_arm_v8_1a_neon_ok] } { + return 0; + } + return [check_runtime arm_v8_1a_neon_hw_available { + int + main (void) + { + #ifdef __ARM_ARCH_ISA_A64 + __Int32x2_t a = {0, 1}; + __Int32x2_t b = {0, 2}; + __Int32x2_t result; + + asm ("sqrdmlah %0.2s, %1.2s, %2.2s" + : "=w"(result) + : "w"(a), "w"(b) + : /* No clobbers. */); + + #else + + __simd64_int32_t a = {0, 1}; + __simd64_int32_t b = {0, 2}; + __simd64_int32_t result; + + asm ("vqrdmlah.s32 %P0, %P1, %P2" + : "=w"(result) + : "w"(a), "w"(b) + : /* No clobbers. */); + #endif + + return result[0]; + } + } [add_options_for_arm_v8_1a_neon ""]] +} + +# Return 1 if the target supports executing floating point instructions from +# ARMv8.2 with the FP16 extension, 0 otherwise. The test is valid for ARM and +# for AArch64. + +proc check_effective_target_arm_v8_2a_fp16_scalar_hw { } { + if { ![check_effective_target_arm_v8_2a_fp16_scalar_ok] } { + return 0; + } + return [check_runtime arm_v8_2a_fp16_scalar_hw_available { + int + main (void) + { + __fp16 a = 1.0; + __fp16 result; + + #ifdef __ARM_ARCH_ISA_A64 + + asm ("fabs %h0, %h1" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #else + + asm ("vabs.f16 %0, %1" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #endif + + return (result == 1.0) ? 0 : 1; + } + } [add_options_for_arm_v8_2a_fp16_scalar ""]] +} + +# Return 1 if the target supports executing Adv.SIMD instructions from ARMv8.2 +# with the FP16 extension, 0 otherwise. The test is valid for ARM and for +# AArch64. + +proc check_effective_target_arm_v8_2a_fp16_neon_hw { } { + if { ![check_effective_target_arm_v8_2a_fp16_neon_ok] } { + return 0; + } + return [check_runtime arm_v8_2a_fp16_neon_hw_available { + int + main (void) + { + #ifdef __ARM_ARCH_ISA_A64 + + __Float16x4_t a = {1.0, -1.0, 1.0, -1.0}; + __Float16x4_t result; + + asm ("fabs %0.4h, %1.4h" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #else + + __simd64_float16_t a = {1.0, -1.0, 1.0, -1.0}; + __simd64_float16_t result; + + asm ("vabs.f16 %P0, %P1" + : "=w"(result) + : "w"(a) + : /* No clobbers. */); + + #endif + + return (result[0] == 1.0) ? 0 : 1; + } + } [add_options_for_arm_v8_2a_fp16_neon ""]] +} + +# Return 1 if the target supports executing AdvSIMD instructions from ARMv8.2 +# with the Dot Product extension, 0 otherwise. The test is valid for ARM and for +# AArch64. + +proc check_effective_target_arm_v8_2a_dotprod_neon_hw { } { + if { ![check_effective_target_arm_v8_2a_dotprod_neon_ok] } { + return 0; + } + return [check_runtime arm_v8_2a_dotprod_neon_hw_available { + #include "arm_neon.h" + int + main (void) + { + + uint32x2_t results = {0,0}; + uint8x8_t a = {1,1,1,1,2,2,2,2}; + uint8x8_t b = {2,2,2,2,3,3,3,3}; + + #ifdef __ARM_ARCH_ISA_A64 + asm ("udot %0.2s, %1.8b, %2.8b" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + + #else + asm ("vudot.u8 %P0, %P1, %P2" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + #endif + + return (results[0] == 8 && results[1] == 24) ? 1 : 0; + } + } [add_options_for_arm_v8_2a_dotprod_neon ""]] +} + +# Return 1 if the target supports executing AdvSIMD instructions from ARMv8.2 +# with the i8mm extension, 0 otherwise. The test is valid for ARM and for +# AArch64. + +proc check_effective_target_arm_v8_2a_i8mm_neon_hw { } { + if { ![check_effective_target_arm_v8_2a_i8mm_ok] } { + return 0; + } + return [check_runtime arm_v8_2a_i8mm_neon_hw_available { + #include "arm_neon.h" + int + main (void) + { + + uint32x2_t results = {0,0}; + uint8x8_t a = {1,1,1,1,2,2,2,2}; + int8x8_t b = {2,2,2,2,3,3,3,3}; + + #ifdef __ARM_ARCH_ISA_A64 + asm ("usdot %0.2s, %1.8b, %2.8b" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + + #else + asm ("vusdot.u8 %P0, %P1, %P2" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + #endif + + return (vget_lane_u32 (results, 0) == 8 + && vget_lane_u32 (results, 1) == 24) ? 1 : 0; + } + } [add_options_for_arm_v8_2a_i8mm ""]] +} + +# Return 1 if this is a ARM target with NEON enabled. + +proc check_effective_target_arm_neon { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_neon object { + #ifndef __ARM_NEON__ + #error not NEON + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +proc check_effective_target_arm_neonv2 { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_neon object { + #ifndef __ARM_NEON__ + #error not NEON + #else + #ifndef __ARM_FEATURE_FMA + #error not NEONv2 + #else + int dummy; + #endif + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is an ARM target with load acquire and store release +# instructions for 8-, 16- and 32-bit types. + +proc check_effective_target_arm_acq_rel { } { + return [check_no_compiler_messages arm_acq_rel object { + void + load_acquire_store_release (void) + { + asm ("lda r0, [r1]\n\t" + "stl r0, [r1]\n\t" + "ldah r0, [r1]\n\t" + "stlh r0, [r1]\n\t" + "ldab r0, [r1]\n\t" + "stlb r0, [r1]" + : : : "r0", "memory"); + } + }] +} + +# Add the options needed for MIPS Paired-Single. + +proc add_options_for_mpaired_single { flags } { + if { ! [check_effective_target_mpaired_single] } { + return "$flags" + } + return "$flags -mpaired-single" +} + +# Add the options needed for MIPS SIMD Architecture. + +proc add_options_for_mips_msa { flags } { + if { ! [check_effective_target_mips_msa] } { + return "$flags" + } + return "$flags -mmsa" +} + +# Add the options needed for MIPS Loongson MMI Architecture. + +proc add_options_for_mips_loongson_mmi { flags } { + if { ! [check_effective_target_mips_loongson_mmi] } { + return "$flags" + } + return "$flags -mloongson-mmi" +} + + +# Return 1 if this a Loongson-2E or -2F target using an ABI that supports +# the Loongson vector modes. + +proc check_effective_target_mips_loongson_mmi { } { + return [check_no_compiler_messages loongson assembly { + #if !defined(__mips_loongson_mmi) + #error !__mips_loongson_mmi + #endif + #if !defined(__mips_loongson_vector_rev) + #error !__mips_loongson_vector_rev + #endif + }] +} + +# Return 1 if this is a MIPS target that supports the legacy NAN. + +proc check_effective_target_mips_nanlegacy { } { + return [check_no_compiler_messages nanlegacy assembly { + #include + int main () { return 0; } + } "-mnan=legacy"] +} + +# Return 1 if an MSA program can be compiled to object + +proc check_effective_target_mips_msa { } { + if ![check_effective_target_nomips16] { + return 0 + } + return [check_no_compiler_messages msa object { + #if !defined(__mips_msa) + #error "MSA NOT AVAIL" + #else + #if !(((__mips == 64) || (__mips == 32)) && (__mips_isa_rev >= 2)) + #error "MSA NOT AVAIL FOR ISA REV < 2" + #endif + #if !defined(__mips_hard_float) + #error "MSA HARD_FLOAT REQUIRED" + #endif + #if __mips_fpr != 64 + #error "MSA 64-bit FPR REQUIRED" + #endif + #include + + int main() + { + v8i16 v = __builtin_msa_ldi_h (1); + + return v[0]; + } + #endif + } "-mmsa" ] +} + +# Return 1 if this is an ARM target that adheres to the ABI for the ARM +# Architecture. + +proc check_effective_target_arm_eabi { } { + return [check_no_compiler_messages arm_eabi object { + #ifndef __ARM_EABI__ + #error not EABI + #else + int dummy; + #endif + }] +} + +# Return 1 if this is an ARM target that adheres to the hard-float variant of +# the ABI for the ARM Architecture (e.g. -mfloat-abi=hard). + +proc check_effective_target_arm_hf_eabi { } { + return [check_no_compiler_messages arm_hf_eabi object { + #if !defined(__ARM_EABI__) || !defined(__ARM_PCS_VFP) + #error not hard-float EABI + #else + int dummy; + #endif + }] +} + +# Return 1 if this is an ARM target uses emulated floating point +# operations. + +proc check_effective_target_arm_softfloat { } { + return [check_no_compiler_messages arm_softfloat object { + #if !defined(__SOFTFP__) + #error not soft-float EABI + #else + int dummy; + #endif + }] +} + +# Return 1 if this is an ARM target supporting -mcpu=iwmmxt. +# Some multilibs may be incompatible with this option. + +proc check_effective_target_arm_iwmmxt_ok { } { + if { [check_effective_target_arm32] } { + return [check_no_compiler_messages arm_iwmmxt_ok object { + int dummy; + } "-mcpu=iwmmxt"] + } else { + return 0 + } +} + +# Return true if LDRD/STRD instructions are prefered over LDM/STM instructions +# for an ARM target. +proc check_effective_target_arm_prefer_ldrd_strd { } { + if { ![check_effective_target_arm32] } { + return 0; + } + + return [check_no_messages_and_pattern arm_prefer_ldrd_strd "strd\tr" assembly { + void foo (void) { __asm__ ("" ::: "r4", "r5"); } + } "-O2 -mthumb" ] +} + +# Return true if LDRD/STRD instructions are available on this target. +proc check_effective_target_arm_ldrd_strd_ok { } { + if { ![check_effective_target_arm32] } { + return 0; + } + + return [check_no_compiler_messages arm_ldrd_strd_ok object { + int main(void) + { + __UINT64_TYPE__ a = 1, b = 10; + __UINT64_TYPE__ *c = &b; + // `a` will be in a valid register since it's a DImode quantity. + asm ("ldrd %0, %1" + : "=r" (a) + : "m" (c)); + return a == 10; + } + }] +} + +# Return 1 if this is a PowerPC target supporting -meabi. + +proc check_effective_target_powerpc_eabi_ok { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_eabi_ok object { + int dummy; + } "-meabi"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with floating-point registers. + +proc check_effective_target_powerpc_fprs { } { + if { [istarget powerpc*-*-*] + || [istarget rs6000-*-*] } { + return [check_no_compiler_messages powerpc_fprs object { + #ifdef __NO_FPRS__ + #error no FPRs + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with hardware double-precision +# floating point. + +proc check_effective_target_powerpc_hard_double { } { + if { [istarget powerpc*-*-*] + || [istarget rs6000-*-*] } { + return [check_no_compiler_messages powerpc_hard_double object { + #ifdef _SOFT_DOUBLE + #error soft double + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with hardware floating point sqrt. + +proc check_effective_target_powerpc_sqrt { } { + # We need to be PowerPC, and we need to have hardware fp enabled. + if {![check_effective_target_powerpc_fprs]} { + return 0; + } + + return [check_no_compiler_messages powerpc_sqrt object { + void test (void) + { + #ifndef _ARCH_PPCSQ + #error _ARCH_PPCSQ is not defined + #endif + } + } {}] +} + +# Return 1 if this is a PowerPC target supporting -maltivec. + +proc check_effective_target_powerpc_altivec_ok { } { + # Not PowerPC, then not ok + if { !([istarget powerpc*-*-*] || [istarget rs6000-*-*]) } { return 0 } + + # Paired Single, then not ok + if { [istarget powerpc-*-linux*paired*] } { return 0 } + + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { return 0 } + + # Return true iff compiling with -maltivec does not error. + return [check_no_compiler_messages powerpc_altivec_ok object { + int dummy; + } "-maltivec"] +} + +# Return 1 if this is a PowerPC target supporting -mpower8-vector + +proc check_effective_target_powerpc_p8vector_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't run on power8, so far. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_p8vector_ok object { + int main (void) { + asm volatile ("xxlorc 0,0,0"); + return 0; + } + } "-mpower8-vector"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mpower9-vector + +proc check_effective_target_powerpc_p9vector_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't run on power9, so far. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_p9vector_ok object { + int main (void) { + long e = -1; + vector double v = (vector double) { 0.0, 0.0 }; + asm ("xsxexpdp %0,%1" : "+r" (e) : "wa" (v)); + return e; + } + } "-mpower9-vector"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mmodulo + +proc check_effective_target_powerpc_p9modulo_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + return [check_no_compiler_messages powerpc_p9modulo_ok object { + int main (void) { + int i = 5, j = 3, r = -1; + asm ("modsw %0,%1,%2" : "+r" (r) : "r" (i), "r" (j)); + return (r == 2); + } + } "-mmodulo"] + } else { + return 0 + } +} + +# return 1 if our compiler returns the ARCH_PWR defines with the options +# as provided by the test. +proc check_effective_target_has_arch_pwr5 { } { + return [check_no_compiler_messages_nocache arch_pwr5 assembly { + void test (void) + { + #ifndef _ARCH_PWR5 + #error does not have power5 support. + #else + /* "has power5 support" */ + #endif + } + } [current_compiler_flags]] +} + +proc check_effective_target_has_arch_pwr6 { } { + return [check_no_compiler_messages_nocache arch_pwr6 assembly { + void test (void) + { + #ifndef _ARCH_PWR6 + #error does not have power6 support. + #else + /* "has power6 support" */ + #endif + } + } [current_compiler_flags]] +} + +proc check_effective_target_has_arch_pwr7 { } { + return [check_no_compiler_messages_nocache arch_pwr7 assembly { + void test (void) + { + #ifndef _ARCH_PWR7 + #error does not have power7 support. + #else + /* "has power7 support" */ + #endif + } + } [current_compiler_flags]] +} + +proc check_effective_target_has_arch_pwr8 { } { + return [check_no_compiler_messages_nocache arch_pwr8 assembly { + void test (void) + { + #ifndef _ARCH_PWR8 + #error does not have power8 support. + #else + /* "has power8 support" */ + #endif + } + } [current_compiler_flags]] +} + +proc check_effective_target_has_arch_pwr9 { } { + return [check_no_compiler_messages_nocache arch_pwr9 assembly { + void test (void) + { + #ifndef _ARCH_PWR9 + #error does not have power9 support. + #else + /* "has power9 support" */ + #endif + } + } [current_compiler_flags]] +} + +proc check_effective_target_has_arch_pwr10 { } { + return [check_no_compiler_messages_nocache arch_pwr10 assembly { + void test (void) + { + #ifndef _ARCH_PWR10 + #error does not have power10 support. + #else + /* "has power10 support" */ + #endif + } + } [current_compiler_flags]] +} + +proc check_effective_target_has_arch_ppc64 { } { + return [check_no_compiler_messages_nocache arch_ppc64 assembly { + void test (void) + { + #ifndef _ARCH_PPC64 + #error does not have ppc64 support. + #else + /* "has ppc64 support" */ + #endif + } + } [current_compiler_flags]] +} + +# Return 1 if this is a PowerPC target supporting -mcpu=power10. +# Limit this to 64-bit linux systems for now until other targets support +# power10. + +proc check_effective_target_power10_ok { } { + if { ([istarget powerpc64*-*-linux*]) } { + return [check_no_compiler_messages power10_ok object { + int main (void) { + long e; + asm ("pli %0,%1" : "=r" (e) : "n" (0x12345)); + return e; + } + } "-mcpu=power10"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mfloat128 via either +# software emulation on power7/power8 systems or hardware support on power9. + +proc check_effective_target_powerpc_float128_sw_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't have VSX, so no soft support for float128. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_float128_sw_ok object { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() { + __float128 z = x + y; + return (z == 3.0q); + } + } "-mfloat128 -mvsx"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mfloat128 via hardware +# support on power9. + +proc check_effective_target_powerpc_float128_hw_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # AltiVec is not supported on AIX before 5.3. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5.1*] + || [istarget powerpc*-*-aix5.2*] } { + return 0 + } + # Darwin doesn't run on any machine with float128 h/w so far. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_float128_hw_ok object { + volatile __float128 x = 1.0q; + volatile __float128 y = 2.0q; + int main() { + __float128 z; + __asm__ ("xsaddqp %0,%1,%2" : "=v" (z) : "v" (x), "v" (y)); + return (z == 3.0q); + } + } "-mfloat128-hardware"] + } else { + return 0 + } +} + +# Return 1 if current options define float128, 0 otherwise. + +proc check_effective_target_ppc_float128 { } { + return [check_no_compiler_messages_nocache ppc_float128 object { + void test (void) + { + #ifndef __FLOAT128__ + nope no good + #endif + } + }] +} + +# Return 1 if current options generate float128 insns, 0 otherwise. + +proc check_effective_target_ppc_float128_insns { } { + return [check_no_compiler_messages_nocache ppc_float128 object { + void test (void) + { + #ifndef __FLOAT128_HARDWARE__ + nope no good + #endif + } + }] +} + +# Return 1 if current options generate VSX instructions, 0 otherwise. + +proc check_effective_target_powerpc_vsx { } { + return [check_no_compiler_messages_nocache powerpc_vsx object { + void test (void) + { + #ifndef __VSX__ + nope no vsx + #endif + } + }] +} + +# Return 1 if this is a PowerPC target supporting -mvsx + +proc check_effective_target_powerpc_vsx_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # VSX is not supported on AIX before 7.1. + if { [istarget powerpc*-*-aix4*] + || [istarget powerpc*-*-aix5*] + || [istarget powerpc*-*-aix6*] } { + return 0 + } + # Darwin doesn't have VSX, even if it's used with an assembler + # which recognises the insns. + if { [istarget *-*-darwin*] } { + return 0 + } + return [check_no_compiler_messages powerpc_vsx_ok object { + int main (void) { + asm volatile ("xxlor 0,0,0"); + return 0; + } + } "-mvsx"] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mhtm + +proc check_effective_target_powerpc_htm_ok { } { + if { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget rs6000-*-*] } { + # HTM is not supported on AIX yet. + if { [istarget powerpc*-*-aix*] } { + return 0 + } + return [check_no_compiler_messages powerpc_htm_ok object { + int main (void) { + asm volatile ("tbegin. 0"); + return 0; + } + } "-mhtm"] + } else { + return 0 + } +} + +# Return 1 if the target supports executing HTM hardware instructions, +# 0 otherwise. Cache the result. + +proc check_htm_hw_available { } { + return [check_cached_effective_target htm_hw_available { + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + check_runtime_nocache htm_hw_available { + int main() + { + __builtin_ttest (); + return 0; + } + } "-mhtm" + } + }] +} +# Return 1 if this is a PowerPC target supporting -mcpu=cell. + +proc check_effective_target_powerpc_ppu_ok { } { + if [check_effective_target_powerpc_altivec_ok] { + return [check_no_compiler_messages cell_asm_available object { + int main (void) { +#ifdef __MACH__ + asm volatile ("lvlx v0,v0,v0"); +#else + asm volatile ("lvlx 0,0,0"); +#endif + return 0; + } + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target that supports SPU. + +proc check_effective_target_powerpc_spu { } { + if { [istarget powerpc*-*-linux*] } { + return [check_effective_target_powerpc_altivec_ok] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC SPE target. The check includes options +# specified by dg-options for this test, so don't cache the result. + +proc check_effective_target_powerpc_spe_nocache { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages_nocache powerpc_spe object { + #ifndef __SPE__ + #error not SPE + #else + int dummy; + #endif + } [current_compiler_flags]] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with SPE enabled. + +proc check_effective_target_powerpc_spe { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_spe object { + #ifndef __SPE__ + #error not SPE + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target with Altivec enabled. + +proc check_effective_target_powerpc_altivec { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_altivec object { + #ifndef __ALTIVEC__ + #error not Altivec + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC 405 target. The check includes options +# specified by dg-options for this test, so don't cache the result. + +proc check_effective_target_powerpc_405_nocache { } { + if { [istarget powerpc*-*-*] || [istarget rs6000-*-*] } { + return [check_no_compiler_messages_nocache powerpc_405 object { + #ifdef __PPC405__ + int dummy; + #else + #error not a PPC405 + #endif + } [current_compiler_flags]] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target using the ELFv2 ABI. + +proc check_effective_target_powerpc_elfv2 { } { + if { [istarget powerpc*-*-*] } { + return [check_no_compiler_messages powerpc_elfv2 object { + #if _CALL_ELF != 2 + #error not ELF v2 ABI + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if this is a PowerPC target supporting -mrop-protect + +proc check_effective_target_rop_ok { } { + return [check_effective_target_power10_ok] && [check_effective_target_powerpc_elfv2] +} + +# The VxWorks SPARC simulator accepts only EM_SPARC executables and +# chokes on EM_SPARC32PLUS or EM_SPARCV9 executables. Return 1 if the +# test environment appears to run executables on such a simulator. + +proc check_effective_target_ultrasparc_hw { } { + return [check_runtime ultrasparc_hw { + int main() { return 0; } + } "-mcpu=ultrasparc"] +} + +# Return 1 if the test environment supports executing UltraSPARC VIS2 +# instructions. We check this by attempting: "bmask %g0, %g0, %g0" + +proc check_effective_target_ultrasparc_vis2_hw { } { + return [check_runtime ultrasparc_vis2_hw { + int main() { __asm__(".word 0x81b00320"); return 0; } + } "-mcpu=ultrasparc3"] +} + +# Return 1 if the test environment supports executing UltraSPARC VIS3 +# instructions. We check this by attempting: "addxc %g0, %g0, %g0" + +proc check_effective_target_ultrasparc_vis3_hw { } { + return [check_runtime ultrasparc_vis3_hw { + int main() { __asm__(".word 0x81b00220"); return 0; } + } "-mcpu=niagara3"] +} + +# Return 1 if this is a SPARC-V9 target. + +proc check_effective_target_sparc_v9 { } { + if { [istarget sparc*-*-*] } { + return [check_no_compiler_messages sparc_v9 object { + int main (void) { + asm volatile ("return %i7+8"); + return 0; + } + }] + } else { + return 0 + } +} + +# Return 1 if this is a SPARC target with VIS enabled. + +proc check_effective_target_sparc_vis { } { + if { [istarget sparc*-*-*] } { + return [check_no_compiler_messages sparc_vis object { + #ifndef __VIS__ + #error not VIS + #else + int dummy; + #endif + }] + } else { + return 0 + } +} + +# Return 1 if the target supports hardware vector shift operation. + +proc check_effective_target_vect_shift { } { + return [check_cached_effective_target_indexed vect_shift { + expr {([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_msa] + || [et-is-effective-target mips_loongson_mmi])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports hardware vector shift by register operation. + +proc check_effective_target_vect_var_shift { } { + return [check_cached_effective_target_indexed vect_var_shift { + expr {(([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_avx2_available]) + }}] +} + +proc check_effective_target_whole_vector_shift { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [istarget powerpc64*-*-*] + || ([is-effective-target arm_neon] + && [check_effective_target_arm_little_endian]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_loongson_mmi]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] } { + set answer 1 + } else { + set answer 0 + } + + verbose "check_effective_target_vect_long: returning $answer" 2 + return $answer +} + +# Return 1 if the target supports vector bswap operations. + +proc check_effective_target_vect_bswap { } { + return [check_cached_effective_target_indexed vect_bswap { + expr { [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports comparison of bool vectors for at +# least one vector length. + +proc check_effective_target_vect_bool_cmp { } { + return [check_cached_effective_target_indexed vect_bool_cmp { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] }}] +} + +# Return 1 if the target supports addition of char vectors for at least +# one vector length. + +proc check_effective_target_vect_char_add { } { + return [check_cached_effective_target_indexed vect_char_add { + expr { + [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [istarget amdgcn-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_loongson_mmi] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + }}] +} + +# Return 1 if the target supports hardware vector shift operation for char. + +proc check_effective_target_vect_shift_char { } { + return [check_cached_effective_target_indexed vect_shift_char { + expr { ([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + || [is-effective-target arm_neon] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports hardware vectors of long, 0 otherwise. +# +# This can change for different subtargets so do not cache the result. + +proc check_effective_target_vect_long { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || (([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + && [check_effective_target_ilp32]) + || [is-effective-target arm_neon] + || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] } { + set answer 1 + } else { + set answer 0 + } + + verbose "check_effective_target_vect_long: returning $answer" 2 + return $answer +} + +# Return 1 if the target supports hardware vectors of float when +# -funsafe-math-optimizations is enabled, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_float { } { + return [check_cached_effective_target_indexed vect_float { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] + || [istarget mips-sde-elf] + || [istarget mipsisa64*-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [is-effective-target arm_neon] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vxe]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports hardware vectors of float without +# -funsafe-math-optimizations being enabled, 0 otherwise. + +proc check_effective_target_vect_float_strict { } { + return [expr { [check_effective_target_vect_float] + && ![istarget arm*-*-*] }] +} + +# Return 1 if the target supports hardware vectors of double, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_double { } { + return [check_cached_effective_target_indexed vect_double { + expr { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_no_compiler_messages vect_double assembly { + #ifdef __tune_atom__ + # error No double vectorizer support. + #endif + }]) + || [istarget aarch64*-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*]} }] +} + +# Return 1 if the target supports conditional addition, subtraction, +# multiplication, division, minimum and maximum on vectors of double, +# via the cond_ optabs. Return 0 otherwise. + +proc check_effective_target_vect_double_cond_arith { } { + return [check_effective_target_aarch64_sve] +} + +# Return 1 if the target supports hardware vectors of long long, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_long_long { } { + return [check_cached_effective_target_indexed vect_long_long { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + + +# Return 1 if the target plus current options does not support a vector +# max instruction on "int", 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_int_min_max { } { + return [check_cached_effective_target_indexed vect_no_int_min_max { + expr { [istarget sparc*-*-*] + || [istarget alpha*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_loongson_mmi]) }}] +} + +# Return 1 if the target plus current options does not support a vector +# add instruction on "int", 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_int_add { } { + # Alpha only supports vector add on V8QI and V4HI. + return [check_cached_effective_target_indexed vect_no_int_add { + expr { [istarget alpha*-*-*] }}] +} + +# Return 1 if the target plus current options does not support vector +# bitwise instructions, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_bitwise { } { + return [check_cached_effective_target_indexed vect_no_bitwise { return 0 }] +} + +# Return 1 if the target plus current options supports vector permutation, +# 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_perm { } { + return [check_cached_effective_target_indexed vect_perm { + expr { [is-effective-target arm_neon] + || [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && ([et-is-effective-target mpaired_single] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if, for some VF: +# +# - the target's default vector size is VF * ELEMENT_BITS bits +# +# - it is possible to implement the equivalent of: +# +# int_t s1[COUNT][COUNT * VF], s2[COUNT * VF]; +# for (int i = 0; i < COUNT; ++i) +# for (int j = 0; j < COUNT * VF; ++j) +# s1[i][j] = s2[j - j % COUNT + i] +# +# using only a single 2-vector permute for each vector in s1. +# +# E.g. for COUNT == 3 and vector length 4, the two arrays would be: +# +# s2 | a0 a1 a2 a3 | b0 b1 b2 b3 | c0 c1 c2 c3 +# ------+-------------+-------------+------------ +# s1[0] | a0 a0 a0 a3 | a3 a3 b2 b2 | b2 c1 c1 c1 +# s1[1] | a1 a1 a1 b0 | b0 b0 b3 b3 | b3 c2 c2 c2 +# s1[2] | a2 a2 a2 b1 | b1 b1 c0 c0 | c0 c3 c3 c3 +# +# Each s1 permute requires only two of a, b and c. +# +# The distance between the start of vector n in s1[0] and the start +# of vector n in s2 is: +# +# A = (n * VF) % COUNT +# +# The corresponding value for the end of vector n is: +# +# B = (n * VF + VF - 1) % COUNT +# +# Subtracting i from each value gives the corresponding difference +# for s1[i]. The condition being tested by this function is false +# iff A - i > 0 and B - i < 0 for some i and n, such that the first +# element for s1[i] comes from vector n - 1 of s2 and the last element +# comes from vector n + 1 of s2. The condition is therefore true iff +# A <= B for all n. This is turn means the condition is true iff: +# +# (n * VF) % COUNT + (VF - 1) % COUNT < COUNT +# +# for all n. COUNT - (n * VF) % COUNT is bounded by gcd (VF, COUNT), +# and will be that value for at least one n in [0, COUNT), so we want: +# +# (VF - 1) % COUNT < gcd (VF, COUNT) + +proc vect_perm_supported { count element_bits } { + set vector_bits [lindex [available_vector_sizes] 0] + # The number of vectors has to be a power of 2 when permuting + # variable-length vectors. + if { $vector_bits <= 0 && ($count & -$count) != $count } { + return 0 + } + set vf [expr { $vector_bits / $element_bits }] + + # Compute gcd (VF, COUNT). + set gcd $vf + set temp1 $count + while { $temp1 > 0 } { + set temp2 [expr { $gcd % $temp1 }] + set gcd $temp1 + set temp1 $temp2 + } + return [expr { ($vf - 1) % $count < $gcd }] +} + +# Return 1 if the target supports SLP permutation of 3 vectors when each +# element has 32 bits. + +proc check_effective_target_vect_perm3_int { } { + return [expr { [check_effective_target_vect_perm] + && [vect_perm_supported 3 32] }] +} + +# Return 1 if the target plus current options supports vector permutation +# on byte-sized elements, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_perm_byte { } { + return [check_cached_effective_target_indexed vect_perm_byte { + expr { ([is-effective-target arm_neon] + && [is-effective-target arm_little_endian]) + || ([istarget aarch64*-*-*] + && [is-effective-target aarch64_little_endian]) + || [istarget powerpc*-*-*] + || ([istarget mips-*.*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports SLP permutation of 3 vectors when each +# element has 8 bits. + +proc check_effective_target_vect_perm3_byte { } { + return [expr { [check_effective_target_vect_perm_byte] + && [vect_perm_supported 3 8] }] +} + +# Return 1 if the target plus current options supports vector permutation +# on short-sized elements, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_perm_short { } { + return [check_cached_effective_target_indexed vect_perm_short { + expr { ([is-effective-target arm_neon] + && [is-effective-target arm_little_endian]) + || ([istarget aarch64*-*-*] + && [is-effective-target aarch64_little_endian]) + || [istarget powerpc*-*-*] + || (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_ssse3_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports SLP permutation of 3 vectors when each +# element has 16 bits. + +proc check_effective_target_vect_perm3_short { } { + return [expr { [check_effective_target_vect_perm_short] + && [vect_perm_supported 3 16] }] +} + +# Return 1 if the target plus current options supports folding of +# copysign into XORSIGN. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_xorsign { } { + return [check_cached_effective_target_indexed xorsign { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] || [istarget arm*-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *short* args into *int* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_hi_to_si_pattern { } { + return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si_pattern { + expr { [istarget powerpc*-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || [is-effective-target arm_neon] + || [istarget ia64-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *short* args into *int* result, 0 otherwise. +# A target can also support this widening summation if it can support +# promotion (unpacking) from shorts to ints. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_hi_to_si { } { + return [check_cached_effective_target_indexed vect_widen_sum_hi_to_si { + expr { [check_effective_target_vect_unpack] + || [istarget powerpc*-*-*] + || [istarget ia64-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *char* args into *short* result, 0 otherwise. +# A target can also support this widening summation if it can support +# promotion (unpacking) from chars to shorts. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_qi_to_hi { } { + return [check_cached_effective_target_indexed vect_widen_sum_qi_to_hi { + expr { [check_effective_target_vect_unpack] + || [is-effective-target arm_neon] + || [istarget ia64-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening summation of *char* args into *int* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_sum_qi_to_si { } { + return [check_cached_effective_target_indexed vect_widen_sum_qi_to_si { + expr { [istarget powerpc*-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *char* args into *short* result, 0 otherwise. +# A target can also support this widening multplication if it can support +# promotion (unpacking) from chars to shorts, and vect_short_mult (non-widening +# multiplication of shorts). +# +# This won't change for different subtargets so cache the result. + + +proc check_effective_target_vect_widen_mult_qi_to_hi { } { + return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi { + expr { ([check_effective_target_vect_unpack] + && [check_effective_target_vect_short_mult]) + || ([istarget powerpc*-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || [is-effective-target arm_neon] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx])) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *short* args into *int* result, 0 otherwise. +# A target can also support this widening multplication if it can support +# promotion (unpacking) from shorts to ints, and vect_int_mult (non-widening +# multiplication of ints). +# +# This won't change for different subtargets so cache the result. + + +proc check_effective_target_vect_widen_mult_hi_to_si { } { + return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si { + expr { ([check_effective_target_vect_unpack] + && [check_effective_target_vect_int_mult]) + || ([istarget powerpc*-*-*] + || [istarget ia64-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [is-effective-target arm_neon] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx])) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *char* args into *short* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_mult_qi_to_hi_pattern { } { + return [check_cached_effective_target_indexed vect_widen_mult_qi_to_hi_pattern { + expr { [istarget powerpc*-*-*] + || ([is-effective-target arm_neon] + && [check_effective_target_arm_little_endian]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *short* args into *int* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } { + return [check_cached_effective_target_indexed vect_widen_mult_hi_to_si_pattern { + expr { [istarget powerpc*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([is-effective-target arm_neon] + && [check_effective_target_arm_little_endian]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# widening multiplication of *int* args into *long* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_mult_si_to_di_pattern { } { + return [check_cached_effective_target_indexed vect_widen_mult_si_to_di_pattern { + expr { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +# Return 1 if the target plus current options supports a vector +# widening shift, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_shift { } { + return [check_cached_effective_target_indexed vect_widen_shift { + expr { [is-effective-target arm_neon] }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product of signed chars, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_sdot_qi { } { + return [check_cached_effective_target_indexed vect_sdot_qi { + expr { [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || [istarget arm*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product of unsigned chars, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_udot_qi { } { + return [check_cached_effective_target_indexed vect_udot_qi { + expr { [istarget powerpc*-*-*] + || [istarget aarch64*-*-*] + || [istarget arm*-*-*] + || [istarget ia64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product where one operand of the multiply is signed char +# and the other unsigned chars, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_usdot_qi { } { + return [check_cached_effective_target_indexed vect_usdot_qi { + expr { [istarget aarch64*-*-*] + || [istarget arm*-*-*] }}] +} + + +# Return 1 if the target plus current options supports a vector +# dot-product of signed shorts, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_sdot_hi { } { + return [check_cached_effective_target_indexed vect_sdot_hi { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# dot-product of unsigned shorts, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_udot_hi { } { + return [check_cached_effective_target_indexed vect_udot_hi { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) }}] +} + +# Return 1 if the target plus current options supports a vector +# sad operation of unsigned chars, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_usad_char { } { + return [check_cached_effective_target_indexed vect_usad_char { + expr { [istarget i?86-*-*] + || [istarget x86_64-*-*] + || ([istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve]) + || ([istarget powerpc*-*-*] + && [check_p9vector_hw_available])}}] +} + +# Return 1 if the target plus current options supports both signed +# and unsigned average operations on vectors of bytes. + +proc check_effective_target_vect_avg_qi {} { + return [expr { [istarget aarch64*-*-*] + && ![check_effective_target_aarch64_sve1_only] }] +} + +# Return 1 if the target plus current options supports both signed +# and unsigned multiply-high-with-round-and-scale operations +# on vectors of half-words. + +proc check_effective_target_vect_mulhrs_hi {} { + return [expr { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_sve2] }] +} + +# Return 1 if the target plus current options supports signed division +# by power-of-2 operations on vectors of 4-byte integers. + +proc check_effective_target_vect_sdiv_pow2_si {} { + return [expr { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_sve] }] +} + +# Return 1 if the target plus current options supports a vector +# demotion (packing) of shorts (to chars) and ints (to shorts) +# using modulo arithmetic, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_pack_trunc { } { + return [check_cached_effective_target_indexed vect_pack_trunc { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok] + && [check_effective_target_arm_little_endian]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn*-*-*] }}] +} + +# Return 1 if the target plus current options supports a vector +# promotion (unpacking) of chars (to shorts) and shorts (to ints), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_unpack { } { + return [check_cached_effective_target_indexed vect_unpack { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*paired*]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok] + && [check_effective_target_arm_little_endian]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn*-*-*] }}] +} + +# Return 1 if the target plus current options does not guarantee +# that its STACK_BOUNDARY is >= the reguired vector alignment. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_unaligned_stack { } { + return [check_cached_effective_target_indexed unaligned_stack { expr 0 }] +} + +# Return 1 if the target plus current options does not support a vector +# alignment mechanism, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_no_align { } { + return [check_cached_effective_target_indexed vect_no_align { + expr { [istarget mipsisa64*-*-*] + || [istarget mips-sde-elf] + || [istarget sparc*-*-*] + || [istarget ia64-*-*] + || [check_effective_target_arm_vect_no_misalign] + || ([istarget powerpc*-*-*] && [check_p8vector_hw_available]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_loongson_mmi]) }}] +} + +# Return 1 if the target supports a vector misalign access, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_hw_misalign { } { + return [check_cached_effective_target_indexed vect_hw_misalign { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] && [check_p8vector_hw_available]) + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) } { + return 1 + } + if { [istarget arm*-*-*] + && ![check_effective_target_arm_vect_no_misalign] } { + return 1 + } + return 0 + }] +} + + +# Return 1 if arrays are aligned to the vector alignment +# boundary, 0 otherwise. + +proc check_effective_target_vect_aligned_arrays { } { + set et_vect_aligned_arrays 0 + if { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && !([is-effective-target ia32] + || ([check_avx_available] && ![check_prefer_avx128]))) } { + set et_vect_aligned_arrays 1 + } + + verbose "check_effective_target_vect_aligned_arrays:\ + returning $et_vect_aligned_arrays" 2 + return $et_vect_aligned_arrays +} + +# Return 1 if types of size 32 bit or less are naturally aligned +# (aligned to their type-size), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_natural_alignment_32 { } { + # FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER. + # FIXME: m68k has -malign-int + return [check_cached_effective_target_indexed natural_alignment_32 { + if { ([istarget *-*-darwin*] && [is-effective-target lp64]) + || [istarget avr-*-*] + || [istarget m68k-*-linux*] + || [istarget pru-*-*] + || [istarget stormy16-*-*] + || [istarget rl78-*-*] + || [istarget pdp11-*-*] + || [istarget msp430-*-*] + || [istarget m32c-*-*] + || [istarget cris-*-*] } { + return 0 + } else { + return 1 + } + }] +} + +# Return 1 if types of size 64 bit or less are naturally aligned (aligned to their +# type-size), 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_natural_alignment_64 { } { + return [check_cached_effective_target_indexed natural_alignment_64 { + expr { [is-effective-target natural_alignment_32] + && [is-effective-target lp64] && ![istarget *-*-darwin*] } + }] +} + +# Return 1 if all vector types are naturally aligned (aligned to their +# type-size), 0 otherwise. + +proc check_effective_target_vect_natural_alignment { } { + set et_vect_natural_alignment 1 + if { [check_effective_target_arm_eabi] + || [istarget nvptx-*-*] + || [istarget s390*-*-*] + || [istarget amdgcn-*-*] } { + set et_vect_natural_alignment 0 + } + verbose "check_effective_target_vect_natural_alignment:\ + returning $et_vect_natural_alignment" 2 + return $et_vect_natural_alignment +} + +# Return true if the target supports the check_raw_ptrs and check_war_ptrs +# optabs on vectors. + +proc check_effective_target_vect_check_ptrs { } { + return [check_effective_target_aarch64_sve2] +} + +# Return true if fully-masked loops are supported. + +proc check_effective_target_vect_fully_masked { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return true if the target supports the @code{len_load} and +# @code{len_store} optabs. + +proc check_effective_target_vect_len_load_store { } { + return [check_effective_target_has_arch_pwr9] +} + +# Return the value of parameter vect-partial-vector-usage specified for +# target by checking the output of "-Q --help=params". Return zero if +# the desirable pattern isn't found. + +proc check_vect_partial_vector_usage { } { + global tool + + return [check_cached_effective_target vect_partial_vector_usage { + set result [check_compile vect_partial_vector_usage assembly { + int i; + } "-Q --help=params" ] + + # Get compiler emitted messages and delete generated file. + set lines [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $output + + set pattern {=vect-partial-vector-usage=<0,2>\s+([0-2])} + # Capture the usage value to val, set it to zero if not found. + if { ![regexp $pattern $lines whole val] } then { + set val 0 + } + + return $val + }] +} + +# Return true if the target supports loop vectorization with partial vectors +# and @code{vect-partial-vector-usage} is set to 1. + +proc check_effective_target_vect_partial_vectors_usage_1 { } { + return [expr { ([check_effective_target_vect_fully_masked] + || [check_effective_target_vect_len_load_store]) + && [check_vect_partial_vector_usage] == 1 }] +} + +# Return true if the target supports loop vectorization with partial vectors +# and @code{vect-partial-vector-usage} is set to 2. + +proc check_effective_target_vect_partial_vectors_usage_2 { } { + return [expr { ([check_effective_target_vect_fully_masked] + || [check_effective_target_vect_len_load_store]) + && [check_vect_partial_vector_usage] == 2 }] +} + +# Return true if the target supports loop vectorization with partial vectors +# and @code{vect-partial-vector-usage} is nonzero. + +proc check_effective_target_vect_partial_vectors { } { + return [expr { ([check_effective_target_vect_fully_masked] + || [check_effective_target_vect_len_load_store]) + && [check_vect_partial_vector_usage] != 0 }] +} + +# Return 1 if the target doesn't prefer any alignment beyond element +# alignment during vectorization. + +proc check_effective_target_vect_element_align_preferred { } { + return [expr { [check_effective_target_aarch64_sve] + && [check_effective_target_vect_variable_length] }] +} + +# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is enabed. +# Return zero if the desirable pattern isn't found. +# It's used by Warray-bounds/Wstringop-overflow testcases which are +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706 +proc check_vect_slp_store_usage { pattern macro } { + global tool + + set result [check_compile slp_aligned_store_usage assembly { + extern void sink (void* ); + #define Ac8 (AC8){ 0, 1, 2, 3, 4, 5, 6, 7 } + #define Ac16 (AC16){ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } + #ifdef TEST_V16QI + typedef struct AC16 { char a[16]; } AC16; + extern char a16[16]; + void + foo1 () + { + *(AC16*)a16 = Ac16; + } + #elif TEST_V8QI + typedef struct AC8 { char a[8]; } AC8; + extern char a8[8]; + void + foo () + { + *(AC8*)a8 = Ac8; + } + #elif TEST_V4QI + struct A1 + { + char n; + char a[3]; + }; + + extern void sink (void*); + void + foo2 () + { + struct A1 a = { 0, { } }; + a.a[0] = 3; + a.a[1] = 4; + a.a[2] = 5; + sink (&a); + } + #elif TEST_V4QI_2 + extern char p[4]; + void + foo2_2 () + { + p[0] = 0; + p[1] = 1; + p[2] = 2; + p[3] = 3; + } + #elif TEST_V4QI_3 + #define Ac4 (AC4){ 0, 1, 2, 3 } + typedef struct AC4 { char a[4]; } AC4; + extern char a[4]; + void + foo () + { + *(AC4*)a = Ac4; + } + #elif TEST_V2QI + struct A2 + { + char a[2]; + }; + void + foo3 () + { + struct A2 a; + a.a[0] = 3; + a.a[1] = 4; + sink (&a); + } + #elif TEST_V2QI_2 + extern char p[2]; + void + foo3_2 () + { + p[0] = 0; + p[1] = 1; + } + #elif TEST_V4HI + struct Ax + { + int n; + short a[4]; + }; + void + foo5 (struct Ax *p) + { + p->a[0] = 0; + p->a[1] = 1; + p->a[2] = 2; + p->a[3] = 3; + } + #elif TEST_V2HI + extern char b[4]; + void + foo4 () + { + *(short*) b = 0; + *(short*) (b + 2) = 1; + } + #elif TEST_V2HI_2 + struct Ax + { + int n; + short a[2]; + }; + void + foo4_2 (struct Ax *p) + { + p->a[0] = 0; + p->a[1] = 1; + } + #elif TEST_V4SI + struct A { int i; }; + struct B { int j; struct A a[4]; }; + + struct C + { + struct B b1; + struct B b2; + }; + char cbuf2[2 * sizeof (struct C)] = { }; + void + foo6 () + { + struct C *p = (struct C*)&cbuf2; + p->b2.a[0].i = 0; + p->b2.a[1].i = 0; + p->b2.a[2].i = 0; + p->b2.a[3].i = 0; + } + #elif TEST_V2SI + struct A { int i; }; + struct B { int j; struct A a[2]; }; + + struct C + { + struct B b1; + struct B b2; + }; + char cbuf2[2 * sizeof (struct C)] = { }; + void + foo6 () + { + struct C *p = (struct C*)&cbuf2; + p->b2.a[0].i = 0; + p->b2.a[1].i = 0; + } + + #endif + } "-O2 -fopt-info-all -D$macro" ] + + # Get compiler emitted messages and delete generated file. + set lines [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $output + + # Check pattern exits in lines, set it to zero if not found. + if { [regexp $pattern $lines] } then { + return 1 + } + + return 0 +} + +# Return the true if target support vectorization of 2-byte char stores +# with 2-byte aligned address at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v2qi_store_align { } { + set pattern {add new stmt: MEM } + set macro "TEST_V2QI" + return [check_cached_effective_target vect_slp_v2qi_store_align { + expr [check_vect_slp_store_usage $pattern $macro] }] +} + +# Return the true if target support vectorization of 2-byte char stores +# with unaligned address at plain O2. +proc check_effective_target_vect_slp_v2qi_store_unalign { } { + set pattern {add new stmt: MEM } + set macro "TEST_V2QI_2" + return [check_cached_effective_target vect_slp_v2qi_store_unalign { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 4-byte char stores +# with 4-byte aligned address at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v4qi_store_align { } { + set pattern {add new stmt: MEM } + set macro "TEST_V4QI" + return [check_cached_effective_target vect_slp_v4qi_store_align { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 4-byte char stores +# with unaligned address at plain O2. +proc check_effective_target_vect_slp_v4qi_store_unalign { } { + set pattern {add new stmt: MEM } + set macro "TEST_V4QI_2" + return [check_cached_effective_target vect_slp_v4qi_store_unalign { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support block move for +# 8-byte aligned 4-byte size struct initialization. +proc check_effective_target_struct_4char_block_move { } { + set pattern {not vectorized: more than one data ref in stmt:} + set macro "TEST_V4QI_3" + return [check_cached_effective_target struct_4char_block_move { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 4-byte char stores +# with unaligned address or store them with a constant pool at plain O2. +proc check_effective_target_vect_slp_v4qi_store_unalign_1 { } { + set pattern {add new stmt: MEM } + set macro "TEST_V4QI_3" + return [check_cached_effective_target vect_slp_v4qi_store_unalign_1 { + expr { [check_vect_slp_store_usage $pattern $macro ] + || [check_effective_target_struct_4char_block_move] } }] +} + +# Return the true if target support block move for +# 8-byte aligned 8-byte size struct initialization. +proc check_effective_target_struct_8char_block_move { } { + set pattern {not vectorized: more than one data ref in stmt:} + set macro "TEST_V8QI" + return [check_cached_effective_target struct_8char_block_move { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 8-byte char stores +# with unaligned address or store them with a constant pool at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v8qi_store_unalign_1 { } { + set pattern {add new stmt: MEM } + set macro "TEST_V8QI" + return [check_cached_effective_target vect_slp_v8qi_store_unalign_1 { + expr { [check_vect_slp_store_usage $pattern $macro ] + || [check_effective_target_struct_8char_block_move] } }] +} + +# Return the true if target support block move for +# 8-byte aligned 16-byte size struct initialization. +proc check_effective_target_struct_16char_block_move { } { + set pattern {not vectorized: more than one data ref in stmt:} + set macro "TEST_V16QI" + return [check_cached_effective_target struct_16char_block_move { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 16-byte char stores +# with unaligned address or store them with a constant pool at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v16qi_store_unalign_1 { } { + set pattern {add new stmt: MEM } + set macro "TEST_V16QI" + return [check_cached_effective_target vect_slp_v16qi_store_unalign_1 { + expr { [check_vect_slp_store_usage $pattern $macro ] + || [check_effective_target_struct_16char_block_move] } }] +} + +# Return the true if target support vectorization of 4-byte short stores +# with unaligned address at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v2hi_store_unalign { } { + set pattern {add new stmt: MEM } + set macro "TEST_V2HI" + return [check_cached_effective_target vect_slp_v2hi_store_unalign { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 4-byte short stores +# with 4-byte aligned address at plain O2. +proc check_effective_target_vect_slp_v2hi_store_align { } { + set pattern {add new stmt: MEM } + set macro "TEST_V2HI_2" + return [check_cached_effective_target vect_slp_v2hi_store_align { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 8-byte short stores +# with unaligned address at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v4hi_store_unalign { } { + set pattern {add new stmt: MEM } + set macro "TEST_V4HI" + return [check_cached_effective_target vect_slp_v4hi_store_unalign { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 8-byte int stores +# with 8-byte aligned address at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v2si_store_align { } { + set pattern {add new stmt: MEM } + set macro "TEST_V2SI" + return [check_cached_effective_target vect_slp_v2si_store_align { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return the true if target support vectorization of 16-byte int stores +# with unaligned address at plain O2. +# NB: This target should be removed after real issues are fixed for +# -Wstringop-overflow with O2 vect. Be careful if you want to reuse +# this target since tests in check_vect_slp_store_usage +# is the exact match of relative testcases +proc check_effective_target_vect_slp_v4si_store_unalign { } { + set pattern {add new stmt: MEM } + set macro "TEST_V4SI" + return [check_cached_effective_target vect_slp_v4si_store_unalign { + expr [check_vect_slp_store_usage $pattern $macro ] }] +} + +# Return 1 if we can align stack data to the preferred vector alignment. + +proc check_effective_target_vect_align_stack_vars { } { + if { [check_effective_target_aarch64_sve] } { + return [check_effective_target_vect_variable_length] + } + return 1 +} + +# Return 1 if vector alignment (for types of size 32 bit or less) is reachable, 0 otherwise. + +proc check_effective_target_vector_alignment_reachable { } { + set et_vector_alignment_reachable 0 + if { [check_effective_target_vect_aligned_arrays] + || [check_effective_target_natural_alignment_32] } { + set et_vector_alignment_reachable 1 + } + verbose "check_effective_target_vector_alignment_reachable:\ + returning $et_vector_alignment_reachable" 2 + return $et_vector_alignment_reachable +} + +# Return 1 if vector alignment for 64 bit is reachable, 0 otherwise. + +proc check_effective_target_vector_alignment_reachable_for_64bit { } { + set et_vector_alignment_reachable_for_64bit 0 + if { [check_effective_target_vect_aligned_arrays] + || [check_effective_target_natural_alignment_64] } { + set et_vector_alignment_reachable_for_64bit 1 + } + verbose "check_effective_target_vector_alignment_reachable_for_64bit:\ + returning $et_vector_alignment_reachable_for_64bit" 2 + return $et_vector_alignment_reachable_for_64bit +} + +# Return 1 if the target only requires element alignment for vector accesses + +proc check_effective_target_vect_element_align { } { + return [check_cached_effective_target_indexed vect_element_align { + expr { ([istarget arm*-*-*] + && ![check_effective_target_arm_vect_no_misalign]) + || [check_effective_target_vect_hw_misalign] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if we expect to see unaligned accesses in at least some +# vector dumps. + +proc check_effective_target_vect_unaligned_possible { } { + return [expr { ![check_effective_target_vect_element_align_preferred] + && (![check_effective_target_vect_no_align] + || [check_effective_target_vect_hw_misalign]) }] +} + +# Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise. + +proc check_effective_target_vect_load_lanes { } { + # We don't support load_lanes correctly on big-endian arm. + return [check_cached_effective_target vect_load_lanes { + expr { ([check_effective_target_arm_little_endian] + && [check_effective_target_arm_neon_ok]) + || [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector masked loads. + +proc check_effective_target_vect_masked_load { } { + return [expr { [check_avx_available] + || [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] } ] +} + +# Return 1 if the target supports vector masked stores. + +proc check_effective_target_vect_masked_store { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return 1 if the target supports vector gather loads via internal functions. + +proc check_effective_target_vect_gather_load_ifn { } { + return [expr { [check_effective_target_aarch64_sve] }] +} + +# Return 1 if the target supports vector scatter stores. + +proc check_effective_target_vect_scatter_store { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return 1 if the target supports vector conditional operations, 0 otherwise. + +proc check_effective_target_vect_condition { } { + return [check_cached_effective_target_indexed vect_condition { + expr { [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget arm*-*-*] + && [check_effective_target_arm_neon_ok]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector conditional operations where +# the comparison has different type from the lhs, 0 otherwise. + +proc check_effective_target_vect_cond_mixed { } { + return [check_cached_effective_target_indexed vect_cond_mixed { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || ([istarget arm*-*-*] + && [check_effective_target_arm_neon_ok]) + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector char multiplication, 0 otherwise. + +proc check_effective_target_vect_char_mult { } { + return [check_cached_effective_target_indexed vect_char_mult { + expr { [istarget aarch64*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [check_effective_target_arm32] + || [check_effective_target_powerpc_altivec] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector short multiplication, 0 otherwise. + +proc check_effective_target_vect_short_mult { } { + return [check_cached_effective_target_indexed vect_short_mult { + expr { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] + || [istarget aarch64*-*-*] + || [check_effective_target_arm32] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_msa] + || [et-is-effective-target mips_loongson_mmi])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector int multiplication, 0 otherwise. + +proc check_effective_target_vect_int_mult { } { + return [check_cached_effective_target_indexed vect_int_mult { + expr { ([istarget powerpc*-*-*] && ![istarget powerpc-*-linux*paired*]) + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) + || [check_effective_target_arm32] + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports 64 bit hardware vector +# multiplication of long operands with a long result, 0 otherwise. +# +# This can change for different subtargets so do not cache the result. + +proc check_effective_target_vect_long_mult { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || (([istarget powerpc*-*-*] + && ![istarget powerpc-*-linux*paired*]) + && [check_effective_target_ilp32]) + || [is-effective-target arm_neon] + || ([istarget sparc*-*-*] && [check_effective_target_ilp32]) + || [istarget aarch64*-*-*] + || ([istarget mips*-*-*] + && [et-is-effective-target mips_msa]) } { + set answer 1 + } else { + set answer 0 + } + + verbose "check_effective_target_vect_long_mult: returning $answer" 2 + return $answer +} + +# Return 1 if the target supports vector even/odd elements extraction, 0 otherwise. + +proc check_effective_target_vect_extract_even_odd { } { + return [check_cached_effective_target_indexed extract_even_odd { + expr { [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [is-effective-target arm_neon] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || ([istarget mips*-*-*] + && ([et-is-effective-target mips_msa] + || [et-is-effective-target mpaired_single])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +# Return 1 if the target supports vector interleaving, 0 otherwise. + +proc check_effective_target_vect_interleave { } { + return [check_cached_effective_target_indexed vect_interleave { + expr { [istarget aarch64*-*-*] + || [istarget powerpc*-*-*] + || [is-effective-target arm_neon] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget ia64-*-*] + || ([istarget mips*-*-*] + && ([et-is-effective-target mpaired_single] + || [et-is-effective-target mips_msa])) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +foreach N {2 3 4 8} { + eval [string map [list N $N] { + # Return 1 if the target supports 2-vector interleaving + proc check_effective_target_vect_stridedN { } { + return [check_cached_effective_target_indexed vect_stridedN { + if { (N & -N) == N + && [check_effective_target_vect_interleave] + && [check_effective_target_vect_extract_even_odd] } { + return 1 + } + if { ([istarget arm*-*-*] + || [istarget aarch64*-*-*]) && N >= 2 && N <= 4 } { + return 1 + } + if [check_effective_target_vect_fully_masked] { + return 1 + } + return 0 + }] + } + }] +} + +# Return the list of vector sizes (in bits) that each target supports. +# A vector length of "0" indicates variable-length vectors. + +proc available_vector_sizes { } { + set result {} + if { [istarget aarch64*-*-*] } { + if { [check_effective_target_aarch64_sve] } { + lappend result [aarch64_sve_bits] + } + lappend result 128 64 + } elseif { [istarget arm*-*-*] + && [check_effective_target_arm_neon_ok] } { + lappend result 128 64 + } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } { + if { [check_avx_available] && ![check_prefer_avx128] } { + lappend result 256 + } + lappend result 128 + if { ![is-effective-target ia32] } { + lappend result 64 + } + lappend result 32 + } elseif { [istarget sparc*-*-*] } { + lappend result 64 + } elseif { [istarget amdgcn*-*-*] } { + lappend result 4096 + } else { + # The traditional default asumption. + lappend result 128 + } + return $result +} + +# Return 1 if the target supports multiple vector sizes + +proc check_effective_target_vect_multiple_sizes { } { + return [expr { [llength [available_vector_sizes]] > 1 }] +} + +# Return true if variable-length vectors are supported. + +proc check_effective_target_vect_variable_length { } { + return [expr { [lindex [available_vector_sizes] 0] == 0 }] +} + +# Return 1 if the target supports vectors of 64 bits. + +proc check_effective_target_vect64 { } { + return [expr { [lsearch -exact [available_vector_sizes] 64] >= 0 }] +} + +# Return 1 if the target supports vectors of 32 bits. + +proc check_effective_target_vect32 { } { + return [expr { [lsearch -exact [available_vector_sizes] 32] >= 0 }] +} + +# Return 1 if the target supports vector copysignf calls. + +proc check_effective_target_vect_call_copysignf { } { + return [check_cached_effective_target_indexed vect_call_copysignf { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget powerpc*-*-*] + || [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports hardware square root instructions. + +proc check_effective_target_sqrt_insn { } { + return [check_cached_effective_target sqrt_insn { + expr { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [check_effective_target_powerpc_sqrt] + || [istarget aarch64*-*-*] + || ([istarget arm*-*-*] && [check_effective_target_arm_vfp_ok]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) + || [istarget amdgcn-*-*] }}] +} + +# Return any additional options to enable square root intructions. + +proc add_options_for_sqrt_insn { flags } { + if { [istarget amdgcn*-*-*] } { + return "$flags -ffast-math" + } + if { [istarget arm*-*-*] } { + return [add_options_for_arm_vfp "$flags"] + } + return $flags +} + +# Return 1 if the target supports vector sqrtf calls. + +proc check_effective_target_vect_call_sqrtf { } { + return [check_cached_effective_target_indexed vect_call_sqrtf { + expr { [istarget aarch64*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || ([istarget powerpc*-*-*] && [check_vsx_hw_available]) + || ([istarget s390*-*-*] + && [check_effective_target_s390_vx]) }}] +} + +# Return 1 if the target supports vector lrint calls. + +proc check_effective_target_vect_call_lrint { } { + set et_vect_call_lrint 0 + if { (([istarget i?86-*-*] || [istarget x86_64-*-*]) + && [check_effective_target_ilp32]) + || [istarget amdgcn-*-*] } { + set et_vect_call_lrint 1 + } + + verbose "check_effective_target_vect_call_lrint: returning $et_vect_call_lrint" 2 + return $et_vect_call_lrint +} + +# Return 1 if the target supports vector btrunc calls. + +proc check_effective_target_vect_call_btrunc { } { + return [check_cached_effective_target_indexed vect_call_btrunc { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector btruncf calls. + +proc check_effective_target_vect_call_btruncf { } { + return [check_cached_effective_target_indexed vect_call_btruncf { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector ceil calls. + +proc check_effective_target_vect_call_ceil { } { + return [check_cached_effective_target_indexed vect_call_ceil { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector ceilf calls. + +proc check_effective_target_vect_call_ceilf { } { + return [check_cached_effective_target_indexed vect_call_ceilf { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector floor calls. + +proc check_effective_target_vect_call_floor { } { + return [check_cached_effective_target_indexed vect_call_floor { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector floorf calls. + +proc check_effective_target_vect_call_floorf { } { + return [check_cached_effective_target_indexed vect_call_floorf { + expr { [istarget aarch64*-*-*] + || [istarget amdgcn-*-*] }}] +} + +# Return 1 if the target supports vector lceil calls. + +proc check_effective_target_vect_call_lceil { } { + return [check_cached_effective_target_indexed vect_call_lceil { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector lfloor calls. + +proc check_effective_target_vect_call_lfloor { } { + return [check_cached_effective_target_indexed vect_call_lfloor { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector nearbyint calls. + +proc check_effective_target_vect_call_nearbyint { } { + return [check_cached_effective_target_indexed vect_call_nearbyint { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector nearbyintf calls. + +proc check_effective_target_vect_call_nearbyintf { } { + return [check_cached_effective_target_indexed vect_call_nearbyintf { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector round calls. + +proc check_effective_target_vect_call_round { } { + return [check_cached_effective_target_indexed vect_call_round { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports vector roundf calls. + +proc check_effective_target_vect_call_roundf { } { + return [check_cached_effective_target_indexed vect_call_roundf { + expr { [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports AND, OR and XOR reduction. + +proc check_effective_target_vect_logical_reduc { } { + return [check_effective_target_aarch64_sve] +} + +# Return 1 if the target supports the fold_extract_last optab. + +proc check_effective_target_vect_fold_extract_last { } { + return [expr { [check_effective_target_aarch64_sve] + || [istarget amdgcn*-*-*] }] +} + +# Return 1 if the target supports section-anchors + +proc check_effective_target_section_anchors { } { + return [check_cached_effective_target section_anchors { + expr { [istarget powerpc*-*-*] + || [istarget arm*-*-*] + || [istarget aarch64*-*-*] }}] +} + +# Return 1 if the target supports atomic operations on "int_128" values. + +proc check_effective_target_sync_int_128 { } { + return 0 +} + +# Return 1 if the target supports atomic operations on "int_128" values +# and can execute them. +# This requires support for both compare-and-swap and true atomic loads. + +proc check_effective_target_sync_int_128_runtime { } { + return 0 +} + +# Return 1 if the target supports atomic operations on "long long". +# +# Note: 32bit x86 targets require -march=pentium in dg-options. +# Note: 32bit s390 targets require -mzarch in dg-options. + +proc check_effective_target_sync_long_long { } { + if { [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [istarget arm*-*-*] + || [istarget alpha*-*-*] + || ([istarget sparc*-*-*] && [check_effective_target_lp64]) + || [istarget s390*-*-*] } { + return 1 + } else { + return 0 + } +} + +# Return 1 if the target supports popcount on long. + +proc check_effective_target_popcountl { } { + return [check_no_messages_and_pattern popcountl "!\\(call" rtl-expand { + int foo (long b) + { + return __builtin_popcountl (b); + } + } "" ] +} + +# Return 1 if the target supports popcount on long long. + +proc check_effective_target_popcountll { } { + return [check_no_messages_and_pattern popcountll "!\\(call" rtl-expand { + int foo (long long b) + { + return __builtin_popcountll (b); + } + } "" ] +} + + +# Return 1 if the target supports popcount on int. + +proc check_effective_target_popcount { } { + return [check_no_messages_and_pattern popcount "!\\(call" rtl-expand { + int foo (int b) + { + return __builtin_popcount (b); + } + } "" ] +} + +# Return 1 if the target supports atomic operations on "long long" +# and can execute them. +# +# Note: 32bit x86 targets require -march=pentium in dg-options. + +proc check_effective_target_sync_long_long_runtime { } { + if { (([istarget x86_64-*-*] || [istarget i?86-*-*]) + && [check_cached_effective_target sync_long_long_available { + check_runtime_nocache sync_long_long_available { + #include "cpuid.h" + int main () + { + unsigned int eax, ebx, ecx, edx; + if (__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return !(edx & bit_CMPXCHG8B); + return 1; + } + } "" + }]) + || [istarget aarch64*-*-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-linux-*] + && [check_runtime sync_longlong_runtime { + #include + int main () + { + long long l1; + + if (sizeof (long long) != 8) + exit (1); + + /* Just check for native; + checking for kernel fallback is tricky. */ + asm volatile ("ldrexd r0,r1, [%0]" + : : "r" (&l1) : "r0", "r1"); + exit (0); + } + } "" ]) + || [istarget alpha*-*-*] + || ([istarget sparc*-*-*] + && [check_effective_target_lp64] + && [check_effective_target_ultrasparc_hw]) + || ([istarget powerpc*-*-*] && [check_effective_target_lp64]) } { + return 1 + } else { + return 0 + } +} + +# Return 1 if the target supports byte swap instructions. + +proc check_effective_target_bswap { } { + return [check_cached_effective_target bswap { + expr { [istarget aarch64*-*-*] + || [istarget alpha*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget m68k-*-*] + || [istarget powerpc*-*-*] + || [istarget rs6000-*-*] + || [istarget s390*-*-*] + || ([istarget arm*-*-*] + && [check_no_compiler_messages_nocache arm_v6_or_later object { + #if __ARM_ARCH < 6 + #error not armv6 or later + #endif + int i; + } ""]) }}] +} + +# Return 1 if the target supports atomic operations on "int" and "long". + +proc check_effective_target_sync_int_long { } { +# This is intentionally powerpc but not rs6000, rs6000 doesn't have the +# load-reserved/store-conditional instructions. + return [check_cached_effective_target sync_int_long { + expr { [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget aarch64*-*-*] + || [istarget alpha*-*-*] + || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-*] + && [check_effective_target_arm_acq_rel]) + || [istarget bfin*-*linux*] + || [istarget hppa*-*linux*] + || [istarget s390*-*-*] + || [istarget powerpc*-*-*] + || [istarget cris-*-*] + || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9]) + || ([istarget arc*-*-*] && [check_effective_target_arc_atomic]) + || [check_effective_target_mips_llsc] + || [istarget nvptx*-*-*] + }}] +} + +# Return 1 if the target supports atomic operations on "int" and "long" on +# stack addresses. + +proc check_effective_target_sync_int_long_stack { } { + return [check_cached_effective_target sync_int_long_stack { + expr { ![istarget nvptx*-*-*] + && [check_effective_target_sync_int_long] + }}] +} + +# Return 1 if the target supports atomic operations on "char" and "short". + +proc check_effective_target_sync_char_short { } { +# This is intentionally powerpc but not rs6000, rs6000 doesn't have the +# load-reserved/store-conditional instructions. + return [check_cached_effective_target sync_char_short { + expr { [istarget aarch64*-*-*] + || [istarget ia64-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget alpha*-*-*] + || [istarget arm*-*-linux-*] + || [istarget arm*-*-uclinuxfdpiceabi] + || ([istarget arm*-*-*] + && [check_effective_target_arm_acq_rel]) + || [istarget hppa*-*linux*] + || [istarget s390*-*-*] + || [istarget powerpc*-*-*] + || [istarget cris-*-*] + || ([istarget sparc*-*-*] && [check_effective_target_sparc_v9]) + || ([istarget arc*-*-*] && [check_effective_target_arc_atomic]) + || [istarget loongarch*-*-*] + || [check_effective_target_mips_llsc] }}] +} + +# Return 1 if the target uses a ColdFire FPU. + +proc check_effective_target_coldfire_fpu { } { + return [check_no_compiler_messages coldfire_fpu assembly { + #ifndef __mcffpu__ + #error !__mcffpu__ + #endif + }] +} + +# Return true if this is a uClibc target. + +proc check_effective_target_uclibc {} { + return [check_no_compiler_messages uclibc object { + #include + #if !defined (__UCLIBC__) + #error !__UCLIBC__ + #endif + }] +} + +# Return true if this is a uclibc target and if the uclibc feature +# described by __$feature__ is not present. + +proc check_missing_uclibc_feature {feature} { + return [check_no_compiler_messages $feature object " + #include + #if !defined (__UCLIBC) || defined (__${feature}__) + #error FOO + #endif + "] +} + +# Return true if this is a Newlib target. + +proc check_effective_target_newlib {} { + return [check_no_compiler_messages newlib object { + #include + }] +} + +# Return true if GCC was configured with --enable-newlib-nano-formatted-io +proc check_effective_target_newlib_nano_io { } { + return [check_configured_with "--enable-newlib-nano-formatted-io"] +} + +# Some newlib versions don't provide a frexpl and instead depend +# on frexp to implement long double conversions in their printf-like +# functions. This leads to broken results. Detect such versions here. + +proc check_effective_target_newlib_broken_long_double_io {} { + if { [is-effective-target newlib] && ![is-effective-target frexpl] } { + return 1 + } + return 0 +} + +# Return true if this is NOT a Bionic target. + +proc check_effective_target_non_bionic {} { + return [check_no_compiler_messages non_bionic object { + #include + #if defined (__BIONIC__) + #error FOO + #endif + }] +} + +# Return true if this target has error.h header. + +proc check_effective_target_error_h {} { + return [check_no_compiler_messages error_h object { + #include + }] +} + +# Return true if this target has tgmath.h header. + +proc check_effective_target_tgmath_h {} { + return [check_no_compiler_messages tgmath_h object { + #include + }] +} + +# Return true if target's libc supports complex functions. + +proc check_effective_target_libc_has_complex_functions {} { + return [check_no_compiler_messages libc_has_complex_functions object { + #include + }] +} + +# Return 1 if +# (a) an error of a few ULP is expected in string to floating-point +# conversion functions; and +# (b) overflow is not always detected correctly by those functions. + +proc check_effective_target_lax_strtofp {} { + # By default, assume that all uClibc targets suffer from this. + return [check_effective_target_uclibc] +} + +# Return 1 if this is a target for which wcsftime is a dummy +# function that always returns 0. + +proc check_effective_target_dummy_wcsftime {} { + # By default, assume that all uClibc targets suffer from this. + return [check_effective_target_uclibc] +} + +# Return 1 if constructors with initialization priority arguments are +# supposed on this target. + +proc check_effective_target_init_priority {} { + return [check_no_compiler_messages init_priority assembly " + void f() __attribute__((constructor (1000))); + void f() \{\} + "] +} + +# Return 1 if the target matches the effective target 'arg', 0 otherwise. +# This can be used with any check_* proc that takes no argument and +# returns only 1 or 0. It could be used with check_* procs that take +# arguments with keywords that pass particular arguments. + +proc is-effective-target { arg } { + global et_index + set selected 0 + if { ![info exists et_index] } { + # Initialize the effective target index that is used in some + # check_effective_target_* procs. + set et_index 0 + } + if { [info procs check_effective_target_${arg}] != [list] } { + set selected [check_effective_target_${arg}] + } else { + switch $arg { + "vmx_hw" { set selected [check_vmx_hw_available] } + "vsx_hw" { set selected [check_vsx_hw_available] } + "p8vector_hw" { set selected [check_p8vector_hw_available] } + "p9vector_hw" { set selected [check_p9vector_hw_available] } + "p9modulo_hw" { set selected [check_p9modulo_hw_available] } + "power10_hw" { set selected [check_power10_hw_available] } + "ppc_float128_sw" { set selected [check_ppc_float128_sw_available] } + "ppc_float128_hw" { set selected [check_ppc_float128_hw_available] } + "ppc_recip_hw" { set selected [check_ppc_recip_hw_available] } + "ppc_cpu_supports_hw" { set selected [check_ppc_cpu_supports_hw_available] } + "ppc_mma_hw" { set selected [check_ppc_mma_hw_available] } + "dfp_hw" { set selected [check_dfp_hw_available] } + "htm_hw" { set selected [check_htm_hw_available] } + "named_sections" { set selected [check_named_sections_available] } + "gc_sections" { set selected [check_gc_sections_available] } + "cxa_atexit" { set selected [check_cxa_atexit_available] } + default { error "unknown effective target keyword `$arg'" } + } + } + + verbose "is-effective-target: $arg $selected" 2 + return $selected +} + +# Return 1 if the argument is an effective-target keyword, 0 otherwise. + +proc is-effective-target-keyword { arg } { + if { [info procs check_effective_target_${arg}] != [list] } { + return 1 + } else { + # These have different names for their check_* procs. + switch $arg { + "vmx_hw" { return 1 } + "vsx_hw" { return 1 } + "p8vector_hw" { return 1 } + "p9vector_hw" { return 1 } + "p9modulo_hw" { return 1 } + "power10_hw" { return 1 } + "ppc_float128_sw" { return 1 } + "ppc_float128_hw" { return 1 } + "ppc_recip_hw" { return 1 } + "ppc_mma_hw" { return 1 } + "dfp_hw" { return 1 } + "htm_hw" { return 1 } + "named_sections" { return 1 } + "gc_sections" { return 1 } + "cxa_atexit" { return 1 } + default { return 0 } + } + } +} + +# Execute tests for all targets in EFFECTIVE_TARGETS list. Set et_index to +# indicate what target is currently being processed. This is for +# the vectorizer tests, e.g. vect_int, to keep track what target supports +# a given feature. + +proc et-dg-runtest { runtest testcases flags default-extra-flags } { + global dg-do-what-default + global EFFECTIVE_TARGETS + global et_index + + if { [llength $EFFECTIVE_TARGETS] > 0 } { + foreach target $EFFECTIVE_TARGETS { + set target_flags $flags + set dg-do-what-default compile + set et_index [lsearch -exact $EFFECTIVE_TARGETS $target] + if { [info procs add_options_for_${target}] != [list] } { + set target_flags [add_options_for_${target} "$flags"] + } + if { [info procs check_effective_target_${target}_runtime] + != [list] && [check_effective_target_${target}_runtime] } { + set dg-do-what-default run + } + $runtest $testcases $target_flags ${default-extra-flags} + } + } else { + set et_index 0 + $runtest $testcases $flags ${default-extra-flags} + } +} + +# Return 1 if a target matches the target in EFFECTIVE_TARGETS at index +# et_index, 0 otherwise. + +proc et-is-effective-target { target } { + global EFFECTIVE_TARGETS + global et_index + + if { [llength $EFFECTIVE_TARGETS] > $et_index + && [lindex $EFFECTIVE_TARGETS $et_index] == $target } { + return 1 + } + return 0 +} + +# Return 1 if target default to short enums + +proc check_effective_target_short_enums { } { + return [check_no_compiler_messages short_enums assembly { + enum foo { bar }; + int s[sizeof (enum foo) == 1 ? 1 : -1]; + }] +} + +# Return 1 if target supports merging string constants at link time. + +proc check_effective_target_string_merging { } { + return [check_no_messages_and_pattern string_merging \ + "rodata\\.str" assembly { + const char *var = "String"; + } {-O2}] +} + +# Return 1 if target has the basic signed and unsigned types in +# , 0 otherwise. This will be obsolete when GCC ensures a +# working for all targets. + +proc check_effective_target_stdint_types { } { + return [check_no_compiler_messages stdint_types assembly { + #include + int8_t a; int16_t b; int32_t c; int64_t d; + uint8_t e; uint16_t f; uint32_t g; uint64_t h; + }] +} + +# Like check_effective_target_stdint_types, but test what happens when +# -mbig-endian is passed. This test only makes sense on targets that +# support -mbig-endian; it will fail elsewhere. + +proc check_effective_target_stdint_types_mbig_endian { } { + return [check_no_compiler_messages stdint_types_mbig_endian assembly { + #include + int8_t a; int16_t b; int32_t c; int64_t d; + uint8_t e; uint16_t f; uint32_t g; uint64_t h; + } "-mbig-endian"] +} + +# Return 1 if target has the basic signed and unsigned types in +# , 0 otherwise. This is for tests that GCC's notions of +# these types agree with those in the header, as some systems have +# only . + +proc check_effective_target_inttypes_types { } { + return [check_no_compiler_messages inttypes_types assembly { + #include + int8_t a; int16_t b; int32_t c; int64_t d; + uint8_t e; uint16_t f; uint32_t g; uint64_t h; + }] +} + +# Return 1 if programs are intended to be run on a simulator +# (i.e. slowly) rather than hardware (i.e. fast). + +proc check_effective_target_simulator { } { + + # All "src/sim" simulators set this one. + if [board_info target exists is_simulator] { + return [board_info target is_simulator] + } + + # The "sid" simulators don't set that one, but at least they set + # this one. + if [board_info target exists slow_simulator] { + return [board_info target slow_simulator] + } + + return 0 +} + +# Return 1 if programs are intended to be run on hardware rather than +# on a simulator + +proc check_effective_target_hw { } { + + # All "src/sim" simulators set this one. + if [board_info target exists is_simulator] { + if [board_info target is_simulator] { + return 0 + } else { + return 1 + } + } + + # The "sid" simulators don't set that one, but at least they set + # this one. + if [board_info target exists slow_simulator] { + if [board_info target slow_simulator] { + return 0 + } else { + return 1 + } + } + + return 1 +} + +# Return 1 if the target is a VxWorks kernel. + +proc check_effective_target_vxworks_kernel { } { + return [check_no_compiler_messages vxworks_kernel assembly { + #if !defined __vxworks || defined __RTP__ + #error NO + #endif + }] +} + +# Return 1 if the target is a VxWorks RTP. + +proc check_effective_target_vxworks_rtp { } { + return [check_no_compiler_messages vxworks_rtp assembly { + #if !defined __vxworks || !defined __RTP__ + #error NO + #endif + }] +} + +# Return 1 if the target is expected to provide wide character support. + +proc check_effective_target_wchar { } { + if {[check_missing_uclibc_feature UCLIBC_HAS_WCHAR]} { + return 0 + } + return [check_no_compiler_messages wchar assembly { + #include + }] +} + +# Return 1 if the target has . + +proc check_effective_target_pthread_h { } { + return [check_no_compiler_messages pthread_h assembly { + #include + }] +} + +# Return 1 if the target can truncate a file from a file-descriptor, +# as used by libgfortran/io/unix.c:fd_truncate; i.e. ftruncate or +# chsize. We test for a trivially functional truncation; no stubs. +# As libgfortran uses _FILE_OFFSET_BITS 64, we do too; it'll cause a +# different function to be used. + +proc check_effective_target_fd_truncate { } { + set prog { + #define _FILE_OFFSET_BITS 64 + #include + #include + #include + #include + int main () + { + FILE *f = fopen ("tst.tmp", "wb"); + int fd; + const char t[] = "test writing more than ten characters"; + char s[11]; + int status = 0; + fd = fileno (f); + write (fd, t, sizeof (t) - 1); + lseek (fd, 0, 0); + if (ftruncate (fd, 10) != 0) + status = 1; + close (fd); + fclose (f); + if (status) + { + unlink ("tst.tmp"); + exit (status); + } + f = fopen ("tst.tmp", "rb"); + if (fread (s, 1, sizeof (s), f) != 10 || strncmp (s, t, 10) != 0) + status = 1; + fclose (f); + unlink ("tst.tmp"); + exit (status); + } + } + + if { [check_runtime ftruncate $prog] } { + return 1; + } + + regsub "ftruncate" $prog "chsize" prog + return [check_runtime chsize $prog] +} + +# Add to FLAGS all the target-specific flags needed to enable +# full IEEE compliance mode. + +proc add_options_for_ieee { flags } { + if { [istarget alpha*-*-*] + || [istarget sh*-*-*] } { + return "$flags -mieee" + } + if { [istarget rx-*-*] } { + return "$flags -mnofpu" + } + return $flags +} + +if {![info exists flags_to_postpone]} { + set flags_to_postpone "" +} + +# Add to FLAGS the flags needed to enable functions to bind locally +# when using pic/PIC passes in the testsuite. +proc add_options_for_bind_pic_locally { flags } { + global flags_to_postpone + + # Instead of returning 'flags' with the -fPIE or -fpie appended, we save it + # in 'flags_to_postpone' and append it later in gcc_target_compile procedure in + # order to make sure that the multilib_flags doesn't override this. + + if {[check_no_compiler_messages using_pic2 assembly { + #if __PIC__ != 2 + #error __PIC__ != 2 + #endif + }]} { + set flags_to_postpone "-fPIE" + return $flags + } + if {[check_no_compiler_messages using_pic1 assembly { + #if __PIC__ != 1 + #error __PIC__ != 1 + #endif + }]} { + set flags_to_postpone "-fpie" + return $flags + } + return $flags +} + +# Add to FLAGS the flags needed to enable 64-bit vectors. + +proc add_options_for_double_vectors { flags } { + if [is-effective-target arm_neon_ok] { + return "$flags -mvectorize-with-neon-double" + } + + return $flags +} + +# Add to FLAGS the flags needed to define the STACK_SIZE macro. + +proc add_options_for_stack_size { flags } { + if [is-effective-target stack_size] { + set stack_size [dg-effective-target-value stack_size] + return "$flags -DSTACK_SIZE=$stack_size" + } + + return $flags +} + +# Return 1 if the target provides a full C99 runtime. + +proc check_effective_target_c99_runtime { } { + return [check_cached_effective_target c99_runtime { + global srcdir + + set file [open "$srcdir/gcc.dg/builtins-config.h"] + set contents [read $file] + close $file + append contents { + #ifndef HAVE_C99_RUNTIME + #error !HAVE_C99_RUNTIME + #endif + } + check_no_compiler_messages_nocache c99_runtime assembly $contents + }] +} + +# Return 1 if the target provides the D runtime. + +proc check_effective_target_d_runtime { } { + return [check_no_compiler_messages d_runtime executable { + // D + module mod; + + extern(C) int main() { + return 0; + } + }] +} + +# Return 1 if the target provides the D standard library. + +proc check_effective_target_d_runtime_has_std_library { } { + return [check_no_compiler_messages d_runtime_has_std_library executable { + // D + module mod; + + extern(C) int main() { + import std.math; + real function(real) pcos = &cos; + return 0; + } + }] +} + +# Return 1 if target wchar_t is at least 4 bytes. + +proc check_effective_target_4byte_wchar_t { } { + return [check_no_compiler_messages 4byte_wchar_t object { + int dummy[sizeof (__WCHAR_TYPE__) >= 4 ? 1 : -1]; + }] +} + +# Return 1 if the target supports automatic stack alignment. + +proc check_effective_target_automatic_stack_alignment { } { + # Ordinarily x86 supports automatic stack alignment ... + if { [istarget i?86*-*-*] || [istarget x86_64-*-*] } then { + if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } { + # ... except Win64 SEH doesn't. Succeed for Win32 though. + return [check_effective_target_ilp32]; + } + return 1; + } + return 0; +} + +# Return true if we are compiling for AVX target. + +proc check_avx_available { } { + if { [check_no_compiler_messages avx_available assembly { + #ifndef __AVX__ + #error unsupported + #endif + } ""] } { + return 1; + } + return 0; +} + +# Return true if we are compiling for AVX2 target. + +proc check_avx2_available { } { + if { [check_no_compiler_messages avx2_available assembly { + #ifndef __AVX2__ + #error unsupported + #endif + } ""] } { + return 1; + } + return 0; +} + +# Return true if we are compiling for SSSE3 target. + +proc check_ssse3_available { } { + if { [check_no_compiler_messages sse3a_available assembly { + #ifndef __SSSE3__ + #error unsupported + #endif + } ""] } { + return 1; + } + return 0; +} + +# Return true if 32- and 16-bytes vectors are available. + +proc check_effective_target_vect_sizes_32B_16B { } { + return [expr { [available_vector_sizes] == [list 256 128] }] +} + +# Return true if 16- and 8-bytes vectors are available. + +proc check_effective_target_vect_sizes_16B_8B { } { + if { [check_avx_available] + || [is-effective-target arm_neon] + || [istarget aarch64*-*-*] } { + return 1; + } else { + return 0; + } +} + + +# Return true if 128-bits vectors are preferred even if 256-bits vectors +# are available. + +proc check_prefer_avx128 { } { + if ![check_avx_available] { + return 0; + } + return [check_no_messages_and_pattern avx_explicit "xmm" assembly { + float a[1024],b[1024],c[1024]; + void foo (void) { int i; for (i = 0; i < 1024; i++) a[i]=b[i]+c[i];} + } "-O2 -ftree-vectorize"] +} + + +# Return 1 if avx512fp16 instructions can be compiled. + +proc check_effective_target_avx512fp16 { } { + return [check_no_compiler_messages avx512fp16 object { + void foo (void) + { + asm volatile ("vmovw %edi, %xmm0"); + } + } "-O2 -mavx512fp16" ] +} + +# Return 1 if avx512f instructions can be compiled. + +proc check_effective_target_avx512f { } { + return [check_no_compiler_messages avx512f object { + typedef double __m512d __attribute__ ((__vector_size__ (64))); + typedef double __m128d __attribute__ ((__vector_size__ (16))); + + __m512d _mm512_add (__m512d a) + { + return __builtin_ia32_addpd512_mask (a, a, a, 1, 4); + } + + __m128d _mm128_add (__m128d a) + { + return __builtin_ia32_addsd_round (a, a, 8); + } + + __m128d _mm128_getmant (__m128d a) + { + return __builtin_ia32_getmantsd_round (a, a, 0, 8); + } + } "-O2 -mavx512f" ] +} + +# Return 1 if avx instructions can be compiled. + +proc check_effective_target_avx { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages avx object { + void _mm256_zeroall (void) + { + __builtin_ia32_vzeroall (); + } + } "-O2 -mavx" ] +} + +# Return 1 if avx2 instructions can be compiled. +proc check_effective_target_avx2 { } { + return [check_no_compiler_messages avx2 object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + __v4di + mm256_is32_andnotsi256 (__v4di __X, __v4di __Y) + { + return __builtin_ia32_andnotsi256 (__X, __Y); + } + } "-O0 -mavx2" ] +} + +# Return 1 if avxvnni instructions can be compiled. +proc check_effective_target_avxvnni { } { + return [check_no_compiler_messages avxvnni object { + typedef int __v8si __attribute__ ((__vector_size__ (32))); + __v8si + _mm256_dpbusd_epi32 (__v8si __A, __v8si __B, __v8si __C) + { + return __builtin_ia32_vpdpbusd_v8si (__A, __B, __C); + } + } "-mavxvnni" ] +} + +# Return 1 if amx-complex instructions can be compiled. +proc check_effective_target_amx_complex { } { + return [check_no_compiler_messages amx_complex object { + void + foo () + { + __asm__ volatile ("tcmmimfp16ps\t%%tmm1, %%tmm2, %%tmm3" ::); + } + } "-mamx-complex" ] +} + +# Return 1 if sse instructions can be compiled. +proc check_effective_target_sse { } { + return [check_no_compiler_messages sse object { + int main () + { + __builtin_ia32_stmxcsr (); + return 0; + } + } "-O2 -msse" ] +} + +# Return 1 if sse2 instructions can be compiled. +proc check_effective_target_sse2 { } { + return [check_no_compiler_messages sse2 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + + __m128i _mm_srli_si128 (__m128i __A, int __N) + { + return (__m128i)__builtin_ia32_psrldqi128 (__A, 8); + } + } "-O2 -msse2" ] +} + +# Return 1 if sse4.1 instructions can be compiled. +proc check_effective_target_sse4 { } { + return [check_no_compiler_messages sse4.1 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_mullo_epi32 (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pmulld128 ((__v4si)__X, + (__v4si)__Y); + } + } "-O2 -msse4.1" ] +} + +# Return 1 if F16C instructions can be compiled. + +proc check_effective_target_f16c { } { + return [check_no_compiler_messages f16c object { + #include "immintrin.h" + float + foo (unsigned short val) + { + return _cvtsh_ss (val); + } + } "-O2 -mf16c" ] +} + +proc check_effective_target_ms_hook_prologue { } { + if { [check_no_compiler_messages ms_hook_prologue object { + void __attribute__ ((__ms_hook_prologue__)) foo (); + } ""] } { + return 1 + } else { + return 0 + } +} + +# Return 1 if 3dnow instructions can be compiled. +proc check_effective_target_3dnow { } { + return [check_no_compiler_messages 3dnow object { + typedef int __m64 __attribute__ ((__vector_size__ (8))); + typedef float __v2sf __attribute__ ((__vector_size__ (8))); + + __m64 _m_pfadd (__m64 __A, __m64 __B) + { + return (__m64) __builtin_ia32_pfadd ((__v2sf)__A, (__v2sf)__B); + } + } "-O2 -m3dnow" ] +} + +# Return 1 if sse3 instructions can be compiled. +proc check_effective_target_sse3 { } { + return [check_no_compiler_messages sse3 object { + typedef double __m128d __attribute__ ((__vector_size__ (16))); + typedef double __v2df __attribute__ ((__vector_size__ (16))); + + __m128d _mm_addsub_pd (__m128d __X, __m128d __Y) + { + return (__m128d) __builtin_ia32_addsubpd ((__v2df)__X, (__v2df)__Y); + } + } "-O2 -msse3" ] +} + +# Return 1 if ssse3 instructions can be compiled. +proc check_effective_target_ssse3 { } { + return [check_no_compiler_messages ssse3 object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_abs_epi32 (__m128i __X) + { + return (__m128i) __builtin_ia32_pabsd128 ((__v4si)__X); + } + } "-O2 -mssse3" ] +} + +# Return 1 if aes instructions can be compiled. +proc check_effective_target_aes { } { + return [check_no_compiler_messages aes object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_aesimc_si128 (__m128i __X) + { + return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); + } + } "-O2 -maes" ] +} + +# Return 1 if vaes instructions can be compiled. +proc check_effective_target_vaes { } { + return [check_no_compiler_messages vaes object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_aesimc_si128 (__m128i __X) + { + return (__m128i) __builtin_ia32_aesimc128 ((__v2di)__X); + } + } "-O2 -maes -mavx" ] +} + +# Return 1 if pclmul instructions can be compiled. +proc check_effective_target_pclmul { } { + return [check_no_compiler_messages pclmul object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i pclmulqdq_test (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, + (__v2di)__Y, + 1); + } + } "-O2 -mpclmul" ] +} + +# Return 1 if vpclmul instructions can be compiled. +proc check_effective_target_vpclmul { } { + return [check_no_compiler_messages vpclmul object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i pclmulqdq_test (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_pclmulqdq128 ((__v2di)__X, + (__v2di)__Y, + 1); + } + } "-O2 -mpclmul -mavx" ] +} + +# Return 1 if sse4a instructions can be compiled. +proc check_effective_target_sse4a { } { + return [check_no_compiler_messages sse4a object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef long long __v2di __attribute__ ((__vector_size__ (16))); + + __m128i _mm_insert_si64 (__m128i __X,__m128i __Y) + { + return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y); + } + } "-O2 -msse4a" ] +} + +# Return 1 if fma4 instructions can be compiled. +proc check_effective_target_fma4 { } { + return [check_no_compiler_messages fma4 object { + typedef float __m128 __attribute__ ((__vector_size__ (16))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) + { + return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, + (__v4sf)__B, + (__v4sf)__C); + } + } "-O2 -mfma4" ] +} + +# Return 1 if fma instructions can be compiled. +proc check_effective_target_fma { } { + return [check_no_compiler_messages fma object { + typedef float __m128 __attribute__ ((__vector_size__ (16))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + __m128 _mm_macc_ps(__m128 __A, __m128 __B, __m128 __C) + { + return (__m128) __builtin_ia32_vfmaddps ((__v4sf)__A, + (__v4sf)__B, + (__v4sf)__C); + } + } "-O2 -mfma" ] +} + +# Return 1 if xop instructions can be compiled. +proc check_effective_target_xop { } { + return [check_no_compiler_messages xop object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef short __v8hi __attribute__ ((__vector_size__ (16))); + __m128i _mm_maccs_epi16(__m128i __A, __m128i __B, __m128i __C) + { + return (__m128i) __builtin_ia32_vpmacssww ((__v8hi)__A, + (__v8hi)__B, + (__v8hi)__C); + } + } "-O2 -mxop" ] +} + +# Return 1 if lzcnt instruction can be compiled. +proc check_effective_target_lzcnt { } { + return [check_no_compiler_messages lzcnt object { + unsigned short _lzcnt (unsigned short __X) + { + return __builtin_clzs (__X); + } + } "-mlzcnt" ] +} + +# Return 1 if bmi instructions can be compiled. +proc check_effective_target_bmi { } { + return [check_no_compiler_messages bmi object { + unsigned int __bextr_u32 (unsigned int __X, unsigned int __Y) + { + return __builtin_ia32_bextr_u32 (__X, __Y); + } + } "-mbmi" ] +} + +# Return 1 if ADX instructions can be compiled. +proc check_effective_target_adx { } { + return [check_no_compiler_messages adx object { + unsigned char + _adxcarry_u32 (unsigned char __CF, unsigned int __X, + unsigned int __Y, unsigned int *__P) + { + return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P); + } + } "-madx" ] +} + +# Return 1 if rtm instructions can be compiled. +proc check_effective_target_rtm { } { + return [check_no_compiler_messages rtm object { + void + _rtm_xend (void) + { + return __builtin_ia32_xend (); + } + } "-mrtm" ] +} + +# Return 1 if avx512vl instructions can be compiled. +proc check_effective_target_avx512vl { } { + return [check_no_compiler_messages avx512vl object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + __v4di + mm256_and_epi64 (__v4di __X, __v4di __Y) + { + __v4di __W; + return __builtin_ia32_pandq256_mask (__X, __Y, __W, -1); + } + } "-mavx512vl" ] +} + +# Return 1 if avx512cd instructions can be compiled. +proc check_effective_target_avx512cd { } { + return [check_no_compiler_messages avx512cd_trans object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_conflict_epi64 (__v8di __W, __v8di __A) + { + return (__v8di) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A, + (__v8di) __W, + -1); + } + } "-Wno-psabi -mavx512cd" ] +} + +# Return 1 if avx512er instructions can be compiled. +proc check_effective_target_avx512er { } { + return [check_no_compiler_messages avx512er_trans object { + typedef float __v16sf __attribute__ ((__vector_size__ (64))); + __v16sf + mm512_exp2a23_ps (__v16sf __X) + { + return __builtin_ia32_exp2ps_mask (__X, __X, -1, 4); + } + } "-Wno-psabi -mavx512er" ] +} + +# Return 1 if sha instructions can be compiled. +proc check_effective_target_sha { } { + return [check_no_compiler_messages sha object { + typedef long long __m128i __attribute__ ((__vector_size__ (16))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __m128i _mm_sha1msg1_epu32 (__m128i __X, __m128i __Y) + { + return (__m128i) __builtin_ia32_sha1msg1 ((__v4si)__X, + (__v4si)__Y); + } + } "-O2 -msha" ] +} + +# Return 1 if avx512dq instructions can be compiled. +proc check_effective_target_avx512dq { } { + return [check_no_compiler_messages avx512dq object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_mask_mullo_epi64 (__v8di __W, __v8di __A, __v8di __B) + { + return (__v8di) __builtin_ia32_pmullq512_mask ((__v8di) __A, + (__v8di) __B, + (__v8di) __W, + -1); + } + } "-mavx512dq" ] +} + +# Return 1 if avx512bw instructions can be compiled. +proc check_effective_target_avx512bw { } { + return [check_no_compiler_messages avx512bw object { + typedef short __v32hi __attribute__ ((__vector_size__ (64))); + __v32hi + _mm512_mask_mulhrs_epi16 (__v32hi __W, __v32hi __A, __v32hi __B) + { + return (__v32hi) __builtin_ia32_pmulhrsw512_mask ((__v32hi) __A, + (__v32hi) __B, + (__v32hi) __W, + -1); + } + } "-mavx512bw" ] +} + +# Return 1 if -Wa,-march=+noavx512bw is supported. +proc check_effective_target_assembler_march_noavx512bw {} { + if { [istarget i?86*-*-*] || [istarget x86_64*-*-*] } { + return [check_no_compiler_messages assembler_march_noavx512bw object { + void foo (void) {} + } "-mno-avx512bw -Wa,-march=+noavx512bw"] + } + return 0 +} + +# Return 1 if avx512vp2intersect instructions can be compiled. +proc check_effective_target_avx512vp2intersect { } { + return [check_no_compiler_messages avx512vp2intersect object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + typedef short __mmask16; + void + _mm512_2intersect_epi32 (__v16si __A, __v16si __B, __mmask16 *__U, + __mmask16 *__M) + { + __builtin_ia32_2intersectd512 (__U, __M, (__v16si) __A, (__v16si) __B); + } + } "-mavx512vp2intersect" ] +} + +# Return 1 if avx512ifma instructions can be compiled. +proc check_effective_target_avx512ifma { } { + return [check_no_compiler_messages avx512ifma object { + typedef long long __v8di __attribute__ ((__vector_size__ (64))); + __v8di + _mm512_madd52lo_epu64 (__v8di __X, __v8di __Y, __v8di __Z) + { + return (__v8di) __builtin_ia32_vpmadd52luq512_mask ((__v8di) __X, + (__v8di) __Y, + (__v8di) __Z, + -1); + } + } "-mavx512ifma" ] +} + +# Return 1 if avx512vbmi instructions can be compiled. +proc check_effective_target_avx512vbmi { } { + return [check_no_compiler_messages avx512vbmi object { + typedef char __v64qi __attribute__ ((__vector_size__ (64))); + __v64qi + _mm512_multishift_epi64_epi8 (__v64qi __X, __v64qi __Y) + { + return (__v64qi) __builtin_ia32_vpmultishiftqb512_mask ((__v64qi) __X, + (__v64qi) __Y, + (__v64qi) __Y, + -1); + } + } "-mavx512vbmi" ] +} + +# Return 1 if avx512_4fmaps instructions can be compiled. +proc check_effective_target_avx5124fmaps { } { + return [check_no_compiler_messages avx5124fmaps object { + typedef float __v16sf __attribute__ ((__vector_size__ (64))); + typedef float __v4sf __attribute__ ((__vector_size__ (16))); + + __v16sf + _mm512_mask_4fmadd_ps (__v16sf __DEST, __v16sf __A, __v16sf __B, __v16sf __C, + __v16sf __D, __v16sf __E, __v4sf *__F) + { + return (__v16sf) __builtin_ia32_4fmaddps_mask ((__v16sf) __A, + (__v16sf) __B, + (__v16sf) __C, + (__v16sf) __D, + (__v16sf) __E, + (const __v4sf *) __F, + (__v16sf) __DEST, + 0xffff); + } + } "-mavx5124fmaps" ] +} + +# Return 1 if avx512_4vnniw instructions can be compiled. +proc check_effective_target_avx5124vnniw { } { + return [check_no_compiler_messages avx5124vnniw object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + typedef int __v4si __attribute__ ((__vector_size__ (16))); + + __v16si + _mm512_4dpwssd_epi32 (__v16si __A, __v16si __B, __v16si __C, + __v16si __D, __v16si __E, __v4si *__F) + { + return (__v16si) __builtin_ia32_vp4dpwssd ((__v16si) __B, + (__v16si) __C, + (__v16si) __D, + (__v16si) __E, + (__v16si) __A, + (const __v4si *) __F); + } + } "-mavx5124vnniw" ] +} + +# Return 1 if avx512_vpopcntdq instructions can be compiled. +proc check_effective_target_avx512vpopcntdq { } { + return [check_no_compiler_messages avx512vpopcntdq object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v16si + _mm512_popcnt_epi32 (__v16si __A) + { + return (__v16si) __builtin_ia32_vpopcountd_v16si ((__v16si) __A); + } + } "-mavx512vpopcntdq" ] +} + +# Return 1 if 128 or 256-bit avx512_vpopcntdq instructions can be compiled. +proc check_effective_target_avx512vpopcntdqvl { } { + return [check_no_compiler_messages avx512vpopcntdqvl object { + typedef int __v8si __attribute__ ((__vector_size__ (32))); + + __v8si + _mm256_popcnt_epi32 (__v8si __A) + { + return (__v8si) __builtin_ia32_vpopcountd_v8si ((__v8si) __A); + } + } "-mavx512vpopcntdq -mavx512vl" ] +} + +# Return 1 if gfni instructions can be compiled. +proc check_effective_target_gfni { } { + return [check_no_compiler_messages gfni object { + typedef char __v16qi __attribute__ ((__vector_size__ (16))); + + __v16qi + _mm_gf2p8affineinv_epi64_epi8 (__v16qi __A, __v16qi __B, const int __C) + { + return (__v16qi) __builtin_ia32_vgf2p8affineinvqb_v16qi ((__v16qi) __A, + (__v16qi) __B, + 0); + } + } "-mgfni" ] +} + +# Return 1 if avx512vbmi2 instructions can be compiled. +proc check_effective_target_avx512vbmi2 { } { + return [check_no_compiler_messages avx512vbmi2 object { + typedef char __v16qi __attribute__ ((__vector_size__ (16))); + typedef unsigned long long __mmask16; + + __v16qi + _mm_mask_compress_epi8 (__v16qi __A, __mmask16 __B, __v16qi __C) + { + return (__v16qi) __builtin_ia32_compressqi128_mask((__v16qi)__C, + (__v16qi)__A, + (__mmask16)__B); + } + } "-mavx512vbmi2 -mavx512vl" ] +} + +# Return 1 if avx512vbmi2 instructions can be compiled. +proc check_effective_target_avx512vnni { } { + return [check_no_compiler_messages avx512vnni object { + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v16si + _mm_mask_compress_epi8 (__v16si __A, __v16si __B, __v16si __C) + { + return (__v16si) __builtin_ia32_vpdpbusd_v16si ((__v16si)__A, + (__v16si)__B, + (__v16si)__C); + } + } "-mavx512vnni -mavx512f" ] +} + +# Return 1 if vaes instructions can be compiled. +proc check_effective_target_avx512vaes { } { + return [check_no_compiler_messages avx512vaes object { + + typedef int __v16si __attribute__ ((__vector_size__ (64))); + + __v32qi + _mm256_aesdec_epi128 (__v32qi __A, __v32qi __B) + { + return (__v32qi)__builtin_ia32_vaesdec_v32qi ((__v32qi) __A, (__v32qi) __B); + } + } "-mvaes" ] +} + +# Return 1 if amx-tile instructions can be compiled. +proc check_effective_target_amx_tile { } { + return [check_no_compiler_messages amx_tile object { + void + foo () + { + __asm__ volatile ("tilerelease" ::); + } + } "-mamx-tile" ] +} + +# Return 1 if amx-int8 instructions can be compiled. +proc check_effective_target_amx_int8 { } { + return [check_no_compiler_messages amx_int8 object { + void + foo () + { + __asm__ volatile ("tdpbssd\t%%tmm1, %%tmm2, %%tmm3" ::); + } + } "-mamx-int8" ] +} + +# Return 1 if amx-bf16 instructions can be compiled. +proc check_effective_target_amx_bf16 { } { + return [check_no_compiler_messages amx_bf16 object { + void + foo () + { + __asm__ volatile ("tdpbf16ps\t%%tmm1, %%tmm2, %%tmm3" ::); + } + } "-mamx-bf16" ] +} + +# Return 1 if amx-fp16 instructions can be compiled. +proc check_effective_target_amx_fp16 { } { + return [check_no_compiler_messages amx_fp16 object { + void + foo () + { + __asm__ volatile ("tdpfp16ps\t%%tmm1, %%tmm2, %%tmm3" ::); + } + } "-mamx-fp16" ] +} + +# Return 1 if vpclmulqdq instructions can be compiled. +proc check_effective_target_vpclmulqdq { } { + return [check_no_compiler_messages vpclmulqdq object { + typedef long long __v4di __attribute__ ((__vector_size__ (32))); + + __v4di + _mm256_clmulepi64_epi128 (__v4di __A, __v4di __B) + { + return (__v4di) __builtin_ia32_vpclmulqdq_v4di (__A, __B, 0); + } + } "-mvpclmulqdq -mavx512vl" ] +} + +# Return 1 if avx512_bitalg instructions can be compiled. +proc check_effective_target_avx512bitalg { } { + return [check_no_compiler_messages avx512bitalg object { + typedef short int __v32hi __attribute__ ((__vector_size__ (64))); + + __v32hi + _mm512_popcnt_epi16 (__v32hi __A) + { + return (__v32hi) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A); + } + } "-mavx512bitalg" ] +} + +# Return 1 if C wchar_t type is compatible with char16_t. + +proc check_effective_target_wchar_t_char16_t_compatible { } { + return [check_no_compiler_messages wchar_t_char16_t object { + __WCHAR_TYPE__ wc; + __CHAR16_TYPE__ *p16 = &wc; + char t[(((__CHAR16_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1]; + }] +} + +# Return 1 if C wchar_t type is compatible with char32_t. + +proc check_effective_target_wchar_t_char32_t_compatible { } { + return [check_no_compiler_messages wchar_t_char32_t object { + __WCHAR_TYPE__ wc; + __CHAR32_TYPE__ *p32 = &wc; + char t[(((__CHAR32_TYPE__) -1) < 0 == ((__WCHAR_TYPE__) -1) < 0) ? 1 : -1]; + }] +} + +# Return 1 if pow10 function exists. + +proc check_effective_target_pow10 { } { + return [check_runtime pow10 { + #include + int main () { + double x; + x = pow10 (1); + return 0; + } + } "-lm" ] +} + +# Return 1 if frexpl function exists. + +proc check_effective_target_frexpl { } { + return [check_runtime frexpl { + #include + int main () { + long double x; + int y; + x = frexpl (5.0, &y); + return 0; + } + } "-lm" ] +} + + +# Return 1 if issignaling function exists. +proc check_effective_target_issignaling {} { + return [check_runtime issignaling { + #define _GNU_SOURCE + #include + int main () + { + return issignaling (0.0); + } + } "-lm" ] +} + +# Return 1 if current options generate DFP instructions, 0 otherwise. +proc check_effective_target_hard_dfp {} { + return [check_no_messages_and_pattern hard_dfp "!adddd3" assembly { + typedef float d64 __attribute__((mode(DD))); + d64 x, y, z; + void foo (void) { z = x + y; } + }] +} + +# Return 1 if string.h and wchar.h headers provide C++ requires overloads +# for strchr etc. functions. + +proc check_effective_target_correct_iso_cpp_string_wchar_protos { } { + return [check_no_compiler_messages correct_iso_cpp_string_wchar_protos assembly { + #include + #include + #if !defined(__cplusplus) \ + || !defined(__CORRECT_ISO_CPP_STRING_H_PROTO) \ + || !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO) + ISO C++ correct string.h and wchar.h protos not supported. + #else + int i; + #endif + }] +} + +# Return 1 if GNU as is used. + +proc check_effective_target_gas { } { + global use_gas_saved + global tool + + if {![info exists use_gas_saved]} { + # Check if the as used by gcc is GNU as. + set options [list "additional_flags=-print-prog-name=as"] + set gcc_as [lindex [${tool}_target_compile "" "" "none" $options] 0] + # Provide /dev/null as input, otherwise gas times out reading from + # stdin. + set status [remote_exec host "$gcc_as" "-v /dev/null"] + set as_output [lindex $status 1] + if { [ string first "GNU" $as_output ] >= 0 } { + # Some Darwin versions have an assembler which is based on an old + # version of GAS (and reports GNU assembler in its -v output) but + # but doesn't support many of the modern GAS features. + if { [ string first "cctools" $as_output ] >= 0 } { + set use_gas_saved 0 + } else { + set use_gas_saved 1 + } + } else { + set use_gas_saved 0 + } + } + return $use_gas_saved +} + +# Return 1 if GNU ld is used. + +proc check_effective_target_gld { } { + global use_gld_saved + global tool + + if {![info exists use_gld_saved]} { + # Check if the ld used by gcc is GNU ld. + set options [list "additional_flags=-print-prog-name=ld"] + set gcc_ld [lindex [${tool}_target_compile "" "" "none" $options] 0] + set status [remote_exec host "$gcc_ld" "--version"] + set ld_output [lindex $status 1] + if { [ string first "GNU" $ld_output ] >= 0 } { + set use_gld_saved 1 + } else { + set use_gld_saved 0 + } + } + return $use_gld_saved +} + +# Return 1 if the compiler has been configure with link-time optimization +# (LTO) support. + +proc check_effective_target_lto { } { + if { [istarget *-*-vxworks*] } { + # No LTO on VxWorks, with kernel modules + # built with partial links + return 0 + } + if { [istarget nvptx-*-*] + || [istarget amdgcn-*-*] } { + return 0; + } + return [check_no_compiler_messages lto object { + void foo (void) { } + } "-flto"] +} + +# Return 1 if the compiler and linker support incremental link-time +# optimization. + +proc check_effective_target_lto_incremental { } { + if ![check_effective_target_lto] { + return 0 + } + return [check_no_compiler_messages lto_incremental executable { + int main () { return 0; } + } "-flto -r -nostdlib"] +} + +# Return 1 if the compiler has been configured with analyzer support. + +proc check_effective_target_analyzer { } { + return [check_no_compiler_messages analyzer object { + void foo (void) { } + } "-fanalyzer"] +} + +# Return 1 if -mx32 -maddress-mode=short can compile, 0 otherwise. + +proc check_effective_target_maybe_x32 { } { + return [check_no_compiler_messages maybe_x32 object { + void foo (void) {} + } "-mx32 -maddress-mode=short"] +} + +# Return 1 if this target supports the -fsplit-stack option, 0 +# otherwise. + +proc check_effective_target_split_stack {} { + return [check_no_compiler_messages split_stack object { + void foo (void) { } + } "-fsplit-stack"] +} + +# Return 1 if this target supports the -masm=intel option, 0 +# otherwise + +proc check_effective_target_masm_intel {} { + return [check_no_compiler_messages masm_intel object { + extern void abort (void); + } "-masm=intel"] +} + +# Return 1 if the language for the compiler under test is C. + +proc check_effective_target_c { } { + global tool + if [string match $tool "gcc"] { + return 1 + } + return 0 +} + +# Return 1 if the language for the compiler under test is C++. + +proc check_effective_target_c++ { } { + global tool + if { [string match $tool "g++"] || [string match $tool "libstdc++"] } { + return 1 + } + return 0 +} + +set cxx_default "c++17" +# Check whether the current active language standard supports the features +# of C++11/C++14 by checking for the presence of one of the -std flags. +# This assumes that the default for the compiler is $cxx_default, and that +# there will never be multiple -std= arguments on the command line. +proc check_effective_target_c++11_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++0x -std=gnu++0x -std=c++11 -std=gnu++11 } }] { + return 1 + } + if { $cxx_default == "c++11" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} +proc check_effective_target_c++11 { } { + if [check_effective_target_c++11_only] { + return 1 + } + return [check_effective_target_c++14] +} +proc check_effective_target_c++11_down { } { + if ![check_effective_target_c++] { + return 0 + } + return [expr ![check_effective_target_c++14] ] +} + +proc check_effective_target_c++14_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++14 -std=gnu++14 -std=c++14 -std=gnu++14 } }] { + return 1 + } + if { $cxx_default == "c++14" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} + +proc check_effective_target_c++14 { } { + if [check_effective_target_c++14_only] { + return 1 + } + return [check_effective_target_c++17] +} +proc check_effective_target_c++14_down { } { + if ![check_effective_target_c++] { + return 0 + } + return [expr ![check_effective_target_c++17] ] +} + +proc check_effective_target_c++98_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++98 -std=gnu++98 -std=c++03 -std=gnu++03 } }] { + return 1 + } + if { $cxx_default == "c++98" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} + +proc check_effective_target_c++17_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++17 -std=gnu++17 -std=c++1z -std=gnu++1z } }] { + return 1 + } + if { $cxx_default == "c++17" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} + +proc check_effective_target_c++17 { } { + if [check_effective_target_c++17_only] { + return 1 + } + return [check_effective_target_c++2a] +} +proc check_effective_target_c++17_down { } { + if ![check_effective_target_c++] { + return 0 + } + return [expr ![check_effective_target_c++2a] ] +} + +proc check_effective_target_c++2a_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++2a -std=gnu++2a -std=c++20 -std=gnu++20 } }] { + return 1 + } + if { $cxx_default == "c++20" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} +proc check_effective_target_c++2a { } { + if [check_effective_target_c++2a_only] { + return 1 + } + return [check_effective_target_c++23] +} + +proc check_effective_target_c++20_only { } { + return [check_effective_target_c++2a_only] +} + +proc check_effective_target_c++20 { } { + return [check_effective_target_c++2a] +} +proc check_effective_target_c++20_down { } { + if ![check_effective_target_c++] { + return 0 + } + return [expr ![check_effective_target_c++23] ] +} + +proc check_effective_target_c++23_only { } { + global cxx_default + if ![check_effective_target_c++] { + return 0 + } + if [check-flags { { } { } { -std=c++23 -std=gnu++23 -std=c++2b -std=gnu++2b } }] { + return 1 + } + if { $cxx_default == "c++23" && [check-flags { { } { } { } { -std=* } }] } { + return 1 + } + return 0 +} +proc check_effective_target_c++23 { } { + return [check_effective_target_c++23_only] +} + +# Check for C++ Concepts support, i.e. -fconcepts flag. +proc check_effective_target_concepts { } { + if [check_effective_target_c++2a] { + return 1 + } + return [check-flags { "" { } { -fconcepts } }] +} + +proc check_effective_target_implicit_constexpr { } { + return [check-flags { "" { } { -fimplicit-constexpr } }] +} + +# Return 1 if expensive testcases should be run. + +proc check_effective_target_run_expensive_tests { } { + if { [getenv GCC_TEST_RUN_EXPENSIVE] != "" } { + return 1 + } + return 0 +} + +# Returns 1 if "mempcpy" is available on the target system. + +proc check_effective_target_mempcpy {} { + if { [istarget *-*-vxworks*] } { + # VxWorks doesn't have mempcpy but our way to test fails + # to detect as we're doing partial links for kernel modules. + return 0 + } + return [check_function_available "mempcpy"] +} + +# Returns 1 if "stpcpy" is available on the target system. + +proc check_effective_target_stpcpy {} { + return [check_function_available "stpcpy"] +} + +# Returns 1 if "sigsetjmp" is available on the target system. +# Also check if "__sigsetjmp" is defined since that's what glibc +# uses. + +proc check_effective_target_sigsetjmp {} { + if { [check_function_available "sigsetjmp"] + || [check_function_available "__sigsetjmp"] } { + return 1 + } + return 0 +} + +# Check whether the vectorizer tests are supported by the target and +# append additional target-dependent compile flags to DEFAULT_VECTCFLAGS. +# If a port wants to execute the tests more than once it should append +# the supported target to EFFECTIVE_TARGETS instead, and the compile flags +# will be added by a call to add_options_for_. +# Set dg-do-what-default to either compile or run, depending on target +# capabilities. Do not set this if the supported target is appended to +# EFFECTIVE_TARGETS. Flags and this variable will be set by et-dg-runtest +# automatically. Return the number of effective targets if vectorizer tests +# are supported, 0 otherwise. + +proc check_vect_support_and_set_flags { } { + global DEFAULT_VECTCFLAGS + global dg-do-what-default + global EFFECTIVE_TARGETS + + if [istarget powerpc-*paired*] { + lappend DEFAULT_VECTCFLAGS "-mpaired" + if [check_750cl_hw_available] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget powerpc*-*-*] { + # Skip targets not supporting -maltivec. + if ![is-effective-target powerpc_altivec_ok] { + return 0 + } + + lappend DEFAULT_VECTCFLAGS "-maltivec" + if [check_p9vector_hw_available] { + lappend DEFAULT_VECTCFLAGS "-mpower9-vector" + } elseif [check_p8vector_hw_available] { + lappend DEFAULT_VECTCFLAGS "-mpower8-vector" + } elseif [check_vsx_hw_available] { + lappend DEFAULT_VECTCFLAGS "-mvsx" "-mno-allow-movmisalign" + } + + if [check_vmx_hw_available] { + set dg-do-what-default run + } else { + if [is-effective-target ilp32] { + # Specify a cpu that supports VMX for compile-only tests. + lappend DEFAULT_VECTCFLAGS "-mcpu=970" + } + set dg-do-what-default compile + } + } elseif { [istarget i?86-*-*] || [istarget x86_64-*-*] } { + lappend DEFAULT_VECTCFLAGS "-msse2" + if { [check_effective_target_sse2_runtime] } { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif { [istarget mips*-*-*] + && [check_effective_target_nomips16] } { + if { [check_effective_target_mpaired_single] } { + lappend EFFECTIVE_TARGETS mpaired_single + } + if { [check_effective_target_mips_loongson_mmi] } { + lappend EFFECTIVE_TARGETS mips_loongson_mmi + } + if { [check_effective_target_mips_msa] } { + lappend EFFECTIVE_TARGETS mips_msa + } + return [llength $EFFECTIVE_TARGETS] + } elseif [istarget sparc*-*-*] { + lappend DEFAULT_VECTCFLAGS "-mcpu=ultrasparc" "-mvis" + if [check_effective_target_ultrasparc_hw] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget alpha*-*-*] { + # Alpha's vectorization capabilities are extremely limited. + # It's more effort than its worth disabling all of the tests + # that it cannot pass. But if you actually want to see what + # does work, command out the return. + return 0 + + lappend DEFAULT_VECTCFLAGS "-mmax" + if [check_alpha_max_hw_available] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget ia64-*-*] { + set dg-do-what-default run + } elseif [is-effective-target arm_neon_ok] { + eval lappend DEFAULT_VECTCFLAGS [add_options_for_arm_neon ""] + # NEON does not support denormals, so is not used for vectorization by + # default to avoid loss of precision. We must pass -ffast-math to test + # vectorization of float operations. + lappend DEFAULT_VECTCFLAGS "-ffast-math" + if [is-effective-target arm_neon_hw] { + set dg-do-what-default run + } else { + set dg-do-what-default compile + } + } elseif [istarget "aarch64*-*-*"] { + set dg-do-what-default run + } elseif [istarget s390*-*-*] { + # The S/390 backend set a default of 2 for that value. + # Override it to have the same situation as with other + # targets. + lappend DEFAULT_VECTCFLAGS "--param" "min-vect-loop-bound=1" + lappend DEFAULT_VECTCFLAGS "--param" "max-unrolled-insns=200" + lappend DEFAULT_VECTCFLAGS "--param" "max-unroll-times=8" + lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peeled-insns=200" + lappend DEFAULT_VECTCFLAGS "--param" "max-completely-peel-times=16" + if [check_effective_target_s390_vxe2] { + lappend DEFAULT_VECTCFLAGS "-march=z15" "-mzarch" + set dg-do-what-default run + } elseif [check_effective_target_s390_vxe] { + lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch" + set dg-do-what-default run + } elseif [check_effective_target_s390_vx] { + lappend DEFAULT_VECTCFLAGS "-march=z13" "-mzarch" + set dg-do-what-default run + } else { + lappend DEFAULT_VECTCFLAGS "-march=z14" "-mzarch" + set dg-do-what-default compile + } + } elseif [istarget amdgcn-*-*] { + set dg-do-what-default run + } else { + return 0 + } + + return 1 +} + +# Return 1 if the target does *not* require strict alignment. + +proc check_effective_target_non_strict_align {} { + + # On ARM, the default is to use STRICT_ALIGNMENT, but there + # are interfaces defined for misaligned access and thus + # depending on the architecture levels unaligned access is + # available. + if [istarget "arm*-*-*"] { + return [check_effective_target_arm_unaligned] + } + + return [check_no_compiler_messages non_strict_align assembly { + char *y; + typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c; + c *z; + void foo(void) { z = (c *) y; } + } "-Wcast-align"] +} + +# Return 1 if the target has . + +proc check_effective_target_ucontext_h { } { + return [check_no_compiler_messages ucontext_h assembly { + #include + }] +} + +proc check_effective_target_aarch64_tiny { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_tiny object { + #ifdef __AARCH64_CMODEL_TINY__ + int dummy; + #else + #error target not AArch64 tiny code model + #endif + }] + } else { + return 0 + } +} + +# Create functions to check that the AArch64 assembler supports the +# various architecture extensions via the .arch_extension pseudo-op. + +foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve" + "i8mm" "f32mm" "f64mm" "bf16" "sb" "sve2" } { + eval [string map [list FUNC $aarch64_ext] { + proc check_effective_target_aarch64_asm_FUNC_ok { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_FUNC_assembler object { + __asm__ (".arch_extension FUNC"); + } "-march=armv8-a+FUNC"] + } else { + return 0 + } + } + }] +} + +proc check_effective_target_aarch64_small { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_small object { + #ifdef __AARCH64_CMODEL_SMALL__ + int dummy; + #else + #error target not AArch64 small code model + #endif + }] + } else { + return 0 + } +} + +proc check_effective_target_aarch64_large { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_large object { + #ifdef __AARCH64_CMODEL_LARGE__ + int dummy; + #else + #error target not AArch64 large code model + #endif + }] + } else { + return 0 + } +} + +# Return 1 if the assembler accepts the aarch64 .variant_pcs directive. + +proc check_effective_target_aarch64_variant_pcs { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_variant_pcs object { + __asm__ (".variant_pcs foo"); + }] + } else { + return 0 + } +} + +# Return 1 if this is a reduced AVR Tiny core. Such cores have different +# register set, instruction set, addressing capabilities and ABI. + +proc check_effective_target_avr_tiny { } { + if { [istarget avr*-*-*] } { + return [check_no_compiler_messages avr_tiny object { + #ifdef __AVR_TINY__ + int dummy; + #else + #error target not a reduced AVR Tiny core + #endif + }] + } else { + return 0 + } +} + +# Return 1 if is available. + +proc check_effective_target_fenv {} { + return [check_no_compiler_messages fenv object { + #include + } [add_options_for_ieee "-std=gnu99"]] +} + +# Return 1 if is available with all the standard IEEE +# exceptions and floating-point exceptions are raised by arithmetic +# operations. (If the target requires special options for "inexact" +# exceptions, those need to be specified in the testcases.) + +proc check_effective_target_fenv_exceptions {} { + return [check_runtime fenv_exceptions { + #include + #include + #ifndef FE_DIVBYZERO + # error Missing FE_DIVBYZERO + #endif + #ifndef FE_INEXACT + # error Missing FE_INEXACT + #endif + #ifndef FE_INVALID + # error Missing FE_INVALID + #endif + #ifndef FE_OVERFLOW + # error Missing FE_OVERFLOW + #endif + #ifndef FE_UNDERFLOW + # error Missing FE_UNDERFLOW + #endif + volatile float a = 0.0f, r; + int + main (void) + { + r = a / a; + if (fetestexcept (FE_INVALID)) + exit (0); + else + abort (); + } + } [add_options_for_ieee "-std=gnu99"]] +} + +# Return 1 if is available with all the standard IEEE +# exceptions and floating-point exceptions are raised by arithmetic +# operations for decimal floating point. (If the target requires +# special options for "inexact" exceptions, those need to be specified +# in the testcases.) + +proc check_effective_target_fenv_exceptions_dfp {} { + return [check_runtime fenv_exceptions_dfp { + #include + #include + #ifndef FE_DIVBYZERO + # error Missing FE_DIVBYZERO + #endif + #ifndef FE_INEXACT + # error Missing FE_INEXACT + #endif + #ifndef FE_INVALID + # error Missing FE_INVALID + #endif + #ifndef FE_OVERFLOW + # error Missing FE_OVERFLOW + #endif + #ifndef FE_UNDERFLOW + # error Missing FE_UNDERFLOW + #endif + volatile _Decimal64 a = 0.0DD, r; + int + main (void) + { + r = a / a; + if (fetestexcept (FE_INVALID)) + exit (0); + else + abort (); + } + } [add_options_for_ieee "-std=gnu99"]] +} + +# Return 1 if -fexceptions is supported. + +proc check_effective_target_exceptions {} { + if { [istarget amdgcn*-*-*] } { + return 0 + } + return 1 +} + +# Used to check if the testing configuration supports exceptions. +# Returns 0 if exceptions are unsupported or disabled (e.g. by passing +# -fno-exceptions). Returns 1 if exceptions are enabled. +proc check_effective_target_exceptions_enabled {} { + return [check_cached_effective_target exceptions_enabled { + if { [check_effective_target_exceptions] } { + return [check_no_compiler_messages exceptions_enabled assembly { + // C++ + void foo (void) + { + throw 1; + } + }] + } else { + # If exceptions aren't supported, then they're not enabled. + return 0 + } + }] +} + +proc check_effective_target_tiny {} { + return [check_cached_effective_target tiny { + if { [istarget aarch64*-*-*] + && [check_effective_target_aarch64_tiny] } { + return 1 + } + if { [istarget avr-*-*] + && [check_effective_target_avr_tiny] } { + return 1 + } + # PRU Program Counter is 16-bits, and trampolines are not supported. + # Hence directly declare as a tiny target. + if [istarget pru-*-*] { + return 1 + } + return 0 + }] +} + +# Return 1 if the target supports -mbranch-cost=N option. + +proc check_effective_target_branch_cost {} { + if { [ istarget arm*-*-*] + || [istarget avr*-*-*] + || [istarget csky*-*-*] + || [istarget epiphany*-*-*] + || [istarget frv*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] + || [istarget loongarch*-*-*] + || [istarget mips*-*-*] + || [istarget s390*-*-*] + || [istarget riscv*-*-*] + || [istarget sh*-*-*] } { + return 1 + } + return 0 +} + +# Record that dg-final test TEST requires convential compilation. + +proc force_conventional_output_for { test } { + if { [info proc $test] == "" } { + perror "$test does not exist" + exit 1 + } + proc ${test}_required_options {} { + global gcc_force_conventional_output + upvar 1 extra_tool_flags extra_tool_flags + if {[regexp -- "^scan-assembler" [info level 0]] + && ![string match "*-fident*" $extra_tool_flags]} { + # Do not let .ident confuse assembler scan tests + return [list $gcc_force_conventional_output "-fno-ident"] + } + return $gcc_force_conventional_output + } +} + +# Record that dg-final test scan-ltrans-tree-dump* requires -flto-partition=one +# in order to force a single partition, allowing scan-ltrans-tree-dump* to scan +# a dump file *.exe.ltrans0.*. + +proc scan-ltrans-tree-dump_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-times_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-not_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-dem_required_options {} { + return "-flto-partition=one" +} +proc scan-ltrans-tree-dump-dem-not_required_options {} { + return "-flto-partition=one" +} + +# Return 1 if the x86-64 target supports PIE with copy reloc, 0 +# otherwise. Cache the result. + +proc check_effective_target_pie_copyreloc { } { + global tool + global GCC_UNDER_TEST + + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target pie_copyreloc { + # Set up and compile to see if linker supports PIE with copy + # reloc. Include the current process ID in the file names to + # prevent conflicts with invocations for multiple testsuites. + + 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_LD_PIE_COPYRELOC == 0" + puts $f "# error Linker does not support PIE with copy reloc." + puts $f "#endif" + close $f + + verbose "check_effective_target_pie_copyreloc 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_pie_copyreloc testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_pie_copyreloc testfile compilation failed" 2 + return 0 + } + }] +} + +# Return 1 if the x86 target supports R_386_GOT32X relocation, 0 +# otherwise. Cache the result. + +proc check_effective_target_got32x_reloc { } { + global tool + global GCC_UNDER_TEST + + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target got32x_reloc { + # Include the current process ID in the file names to prevent + # conflicts with invocations for multiple testsuites. + + set src got32x[pid].c + set obj got32x[pid].o + + set f [open $src "w"] + puts $f "#include \"../../auto-host.h\"" + puts $f "#if HAVE_AS_IX86_GOT32X == 0" + puts $f "# error Assembler does not support R_386_GOT32X." + puts $f "#endif" + close $f + + verbose "check_effective_target_got32x_reloc 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_got32x_reloc testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_got32x_reloc testfile compilation failed" 2 + return 0 + } + }] + + return $got32x_reloc_available_saved +} + +# Return 1 if the x86 target supports calling ___tls_get_addr via GOT, +# 0 otherwise. Cache the result. + +proc check_effective_target_tls_get_addr_via_got { } { + global tool + global GCC_UNDER_TEST + + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target tls_get_addr_via_got { + # Include the current process ID in the file names to prevent + # conflicts with invocations for multiple testsuites. + + set src tls_get_addr_via_got[pid].c + set obj tls_get_addr_via_got[pid].o + + set f [open $src "w"] + puts $f "#include \"../../auto-host.h\"" + puts $f "#if HAVE_AS_IX86_TLS_GET_ADDR_GOT == 0" + puts $f "# error Assembler/linker do not support calling ___tls_get_addr via GOT." + puts $f "#endif" + close $f + + verbose "check_effective_target_tls_get_addr_via_got 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_tls_get_addr_via_got testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_tls_get_addr_via_got testfile compilation failed" 2 + return 0 + } + }] +} + +# Return 1 if the target uses comdat groups. + +proc check_effective_target_comdat_group {} { + return [check_no_messages_and_pattern comdat_group "\.section\[^\n\r]*,comdat|\.group\[^\n\r]*,#comdat" assembly { + // C++ + inline int foo () { return 1; } + int (*fn) () = foo; + }] +} + +# Return 1 if target supports __builtin_eh_return +proc check_effective_target_builtin_eh_return { } { + return [check_no_compiler_messages builtin_eh_return object { + void test (long l, void *p) + { + __builtin_eh_return (l, p); + } + } "" ] +} + +# Return 1 if the target supports max reduction for vectors. + +proc check_effective_target_vect_max_reduc { } { + if { [istarget aarch64*-*-*] || [is-effective-target arm_neon] } { + return 1 + } + return 0 +} + +# Return 1 if the compiler has been configured with nvptx offloading. + +proc check_effective_target_offload_nvptx { } { + return [check_no_compiler_messages offload_nvptx assembly { + int main () {return 0;} + } "-foffload=nvptx-none" ] +} + +# Return 1 if the compiler has been configured with gcn offloading. + +proc check_effective_target_offload_gcn { } { + return [check_no_compiler_messages offload_gcn assembly { + int main () {return 0;} + } "-foffload=amdgcn-amdhsa" ] +} + +# Return 1 if the target support -fprofile-update=atomic +proc check_effective_target_profile_update_atomic {} { + return [check_no_compiler_messages profile_update_atomic assembly { + int main (void) { return 0; } + } "-fprofile-update=atomic -fprofile-generate"] +} + +# Return 1 if vector (va - vector add) instructions are understood by +# the assembler and can be executed. This also covers checking for +# the VX kernel feature. A kernel without that feature does not +# enable the vector facility and the following check will die with a +# signal. +proc check_effective_target_s390_vx { } { + if ![istarget s390*-*-*] then { + return 0; + } + + return [check_runtime s390_check_vx { + int main (void) + { + asm ("va %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28"); + return 0; + } + } "-march=z13 -mzarch" ] +} + +# Same as above but for the z14 vector enhancement facility. Test +# is performed with the vector nand instruction. +proc check_effective_target_s390_vxe { } { + if ![istarget s390*-*-*] then { + return 0; + } + + return [check_runtime s390_check_vxe { + int main (void) + { + asm ("vnn %%v24, %%v26, %%v28" : : : "v24", "v26", "v28"); + return 0; + } + } "-march=z14 -mzarch" ] +} + +# Same as above but for the arch13 vector enhancement facility. Test +# is performed with the vector shift left double by bit instruction. +proc check_effective_target_s390_vxe2 { } { + if ![istarget s390*-*-*] then { + return 0; + } + + return [check_runtime s390_check_vxe2 { + int main (void) + { + asm ("vsld %%v24, %%v26, %%v28, 3" : : : "v24", "v26", "v28"); + return 0; + } + } "-march=arch13 -mzarch" ] +} + +# Same as above but for the arch14 NNPA facility. +proc check_effective_target_s390_nnpa { } { + if ![istarget s390*-*-*] then { + return 0; + } + + return [check_runtime s390_check_nnpa { + int main (void) + { + asm ("vzero %%v24\n\t" + "vcrnf %%v24,%%v24,%%v24,0,2" : : : "v24"); + return 0; + } + } "-march=arch14 -mzarch" ] +} + +#For versions of ARM architectures that have hardware div insn, +#disable the divmod transform + +proc check_effective_target_arm_divmod_simode { } { + return [check_no_compiler_messages arm_divmod assembly { + #ifdef __ARM_ARCH_EXT_IDIV__ + #error has div insn + #endif + int i; + }] +} + +# Return 1 if target supports divmod hardware insn or divmod libcall. + +proc check_effective_target_divmod { } { + #TODO: Add checks for all targets that have either hardware divmod insn + # or define libfunc for divmod. + if { [istarget arm*-*-*] + || [istarget i?86-*-*] || [istarget x86_64-*-*] } { + return 1 + } + return 0 +} + +# Return 1 if target supports divmod for SImode. The reason for +# separating this from check_effective_target_divmod is that +# some versions of ARM architecture define div instruction +# only for simode, and for these archs, we do not want to enable +# divmod transform for simode. + +proc check_effective_target_divmod_simode { } { + if { [istarget arm*-*-*] } { + return [check_effective_target_arm_divmod_simode] + } + + return [check_effective_target_divmod] +} + +# Return 1 if store merging optimization is applicable for target. +# Store merging is not profitable for targets like the avr which +# can load/store only one byte at a time. Use int size as a proxy +# for the number of bytes the target can write, and skip for targets +# with a smallish (< 32) size. + +proc check_effective_target_store_merge { } { + if { [is-effective-target non_strict_align ] && [is-effective-target int32plus] } { + return 1 + } + + return 0 +} + +# Return 1 if we're able to assemble rdrand + +proc check_effective_target_rdrand { } { + return [check_no_compiler_messages_nocache rdrand object { + unsigned int + __foo(void) + { + unsigned int val; + __builtin_ia32_rdrand32_step(&val); + return val; + } + } "-mrdrnd" ] +} + +# Return 1 if the target supports coprocessor instructions: cdp, ldc, ldcl, +# stc, stcl, mcr and mrc. +proc check_effective_target_arm_coproc1_ok_nocache { } { + if { ![istarget arm*-*-*] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc1_ok assembly { + #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 4 + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc1_ok { } { + return [check_cached_effective_target arm_coproc1_ok \ + check_effective_target_arm_coproc1_ok_nocache] +} + +# Return 1 if the target supports all coprocessor instructions checked by +# check_effective_target_arm_coproc1_ok in addition to the following: cdp2, +# ldc2, ldc2l, stc2, stc2l, mcr2 and mrc2. +proc check_effective_target_arm_coproc2_ok_nocache { } { + if { ![check_effective_target_arm_coproc1_ok] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc2_ok assembly { + #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 5 + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc2_ok { } { + return [check_cached_effective_target arm_coproc2_ok \ + check_effective_target_arm_coproc2_ok_nocache] +} + +# Return 1 if the target supports all coprocessor instructions checked by +# check_effective_target_arm_coproc2_ok in addition the following: mcrr and +# mrrc. +proc check_effective_target_arm_coproc3_ok_nocache { } { + if { ![check_effective_target_arm_coproc2_ok] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc3_ok assembly { + #if (__thumb__ && !__thumb2__) \ + || (__ARM_ARCH < 6 && !defined (__ARM_ARCH_5TE__)) + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc3_ok { } { + return [check_cached_effective_target arm_coproc3_ok \ + check_effective_target_arm_coproc3_ok_nocache] +} + +# Return 1 if the target supports all coprocessor instructions checked by +# check_effective_target_arm_coproc3_ok in addition the following: mcrr2 and +# mrcc2. +proc check_effective_target_arm_coproc4_ok_nocache { } { + if { ![check_effective_target_arm_coproc3_ok] } { + return 0 + } + return [check_no_compiler_messages_nocache arm_coproc4_ok assembly { + #if (__thumb__ && !__thumb2__) || __ARM_ARCH < 6 + #error FOO + #endif + #include + }] +} + +proc check_effective_target_arm_coproc4_ok { } { + return [check_cached_effective_target arm_coproc4_ok \ + check_effective_target_arm_coproc4_ok_nocache] +} + +# Return 1 if the target supports the auto_inc_dec optimization pass. +proc check_effective_target_autoincdec { } { + if { ![check_no_compiler_messages auto_incdec assembly { void f () { } + } "-O2 -fdump-rtl-auto_inc_dec" ] } { + return 0 + } + + set dumpfile [glob -nocomplain "auto_incdec[pid].c.\[0-9\]\[0-9\]\[0-9\]r.auto_inc_dec"] + if { [file exists $dumpfile ] } { + file delete $dumpfile + return 1 + } + return 0 +} + +# Return 1 if the target has support for stack probing designed +# to avoid stack-clash style attacks. +# +# This is used to restrict the stack-clash mitigation tests to +# just those targets that have been explicitly supported. +# +# In addition to the prologue work on those targets, each target's +# properties should be described in the functions below so that +# tests do not become a mess of unreadable target conditions. +# +proc check_effective_target_supports_stack_clash_protection { } { + + if { [istarget x86_64-*-*] || [istarget i?86-*-*] + || [istarget powerpc*-*-*] || [istarget rs6000*-*-*] + || [istarget aarch64*-**] || [istarget s390*-*-*] } { + return 1 + } + return 0 +} + +# Return 1 if the target creates a frame pointer for non-leaf functions +# Note we ignore cases where we apply tail call optimization here. +proc check_effective_target_frame_pointer_for_non_leaf { } { + # Solaris/x86 defaults to -fno-omit-frame-pointer. + if { [istarget i?86-*-solaris*] || [istarget x86_64-*-solaris*] } { + return 1 + } + + return 0 +} + +# Return 1 if the target's calling sequence or its ABI +# create implicit stack probes at or prior to function entry. +proc check_effective_target_caller_implicit_probes { } { + + # On x86/x86_64 the call instruction itself pushes the return + # address onto the stack. That is an implicit probe of *sp. + if { [istarget x86_64-*-*] || [istarget i?86-*-*] } { + return 1 + } + + # On PPC, the ABI mandates that the address of the outer + # frame be stored at *sp. Thus each allocation of stack + # space is itself an implicit probe of *sp. + if { [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } { + return 1 + } + + # s390's ABI has a register save area allocated by the + # caller for use by the callee. The mere existence does + # not constitute a probe by the caller, but when the slots + # used by the callee those stores are implicit probes. + if { [istarget s390*-*-*] } { + return 1 + } + + # Not strictly true on aarch64, but we have agreed that we will + # consider any function that pushes SP more than 3kbytes into + # the guard page as broken. This essentially means that we can + # consider the aarch64 as having a caller implicit probe at + # *(sp + 1k). + if { [istarget aarch64*-*-*] } { + return 1; + } + + return 0 +} + +# Targets that potentially realign the stack pointer often cause residual +# stack allocations and make it difficult to elimination loops or residual +# allocations for dynamic stack allocations +proc check_effective_target_callee_realigns_stack { } { + if { [istarget x86_64-*-*] || [istarget i?86-*-*] } { + return 1 + } + return 0 +} + +# Return 1 if CET instructions can be compiled. +proc check_effective_target_cet { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages cet object { + void foo (void) + { + asm ("setssbsy"); + } + } "-O2 -fcf-protection" ] +} + +# Return 1 if target supports floating point "infinite" +proc check_effective_target_inf { } { + return [check_no_compiler_messages supports_inf assembly { + const double pinf = __builtin_inf (); + }] +} + +# Return 1 if target supports floating point "infinite" for float. +proc check_effective_target_inff { } { + return [check_no_compiler_messages supports_inff assembly { + const float pinf = __builtin_inff (); + }] +} + +# Return 1 if the target supports ARMv8.3 Adv.SIMD Complex instructions +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_3a_complex_neon_ok_nocache { } { + global et_arm_v8_3a_complex_neon_flags + set et_arm_v8_3a_complex_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=auto" "-mfloat-abi=hard -mfpu=auto"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_3a_complex_neon_ok assembly { + #if !defined (__ARM_FEATURE_COMPLEX) + #error "__ARM_FEATURE_COMPLEX not defined" + #endif + } "$flags -march=armv8.3-a"] } { + set et_arm_v8_3a_complex_neon_flags "$flags -march=armv8.3-a" + return 1; + } + } + + return 0; +} + +proc check_effective_target_arm_v8_3a_complex_neon_ok { } { + return [check_cached_effective_target arm_v8_3a_complex_neon_ok \ + check_effective_target_arm_v8_3a_complex_neon_ok_nocache] +} + +proc add_options_for_arm_v8_3a_complex_neon { flags } { + if { ! [check_effective_target_arm_v8_3a_complex_neon_ok] } { + return "$flags" + } + global et_arm_v8_3a_complex_neon_flags + return "$flags $et_arm_v8_3a_complex_neon_flags" +} + +# Return 1 if the target supports ARMv8.3 Adv.SIMD + FP16 Complex instructions +# instructions, 0 otherwise. The test is valid for ARM and for AArch64. +# Record the command line options needed. + +proc check_effective_target_arm_v8_3a_fp16_complex_neon_ok_nocache { } { + global et_arm_v8_3a_fp16_complex_neon_flags + set et_arm_v8_3a_fp16_complex_neon_flags "" + + if { ![istarget arm*-*-*] && ![istarget aarch64*-*-*] } { + return 0; + } + + # Iterate through sets of options to find the compiler flags that + # need to be added to the -march option. + foreach flags {"" "-mfloat-abi=softfp -mfpu=auto" "-mfloat-abi=hard -mfpu=auto"} { + if { [check_no_compiler_messages_nocache \ + arm_v8_3a_fp16_complex_neon_ok assembly { + #if !defined (__ARM_FEATURE_COMPLEX) + #error "__ARM_FEATURE_COMPLEX not defined" + #endif + } "$flags -march=armv8.3-a+fp16"] } { + set et_arm_v8_3a_fp16_complex_neon_flags \ + "$flags -march=armv8.3-a+fp16" + return 1; + } + } + + return 0; +} + +proc check_effective_target_arm_v8_3a_fp16_complex_neon_ok { } { + return [check_cached_effective_target arm_v8_3a_fp16_complex_neon_ok \ + check_effective_target_arm_v8_3a_fp16_complex_neon_ok_nocache] +} + +proc add_options_for_arm_v8_3a_fp16_complex_neon { flags } { + if { ! [check_effective_target_arm_v8_3a_fp16_complex_neon_ok] } { + return "$flags" + } + global et_arm_v8_3a_fp16_complex_neon_flags + return "$flags $et_arm_v8_3a_fp16_complex_neon_flags" +} + + +# Return 1 if the target supports executing AdvSIMD instructions from ARMv8.3 +# with the complex instruction extension, 0 otherwise. The test is valid for +# ARM and for AArch64. + +proc check_effective_target_arm_v8_3a_complex_neon_hw { } { + if { ![check_effective_target_arm_v8_3a_complex_neon_ok] } { + return 1; + } + return [check_runtime arm_v8_3a_complex_neon_hw_available { + #include "arm_neon.h" + int + main (void) + { + + float32x2_t results = {-4.0,5.0}; + float32x2_t a = {1.0,3.0}; + float32x2_t b = {2.0,5.0}; + + #ifdef __ARM_ARCH_ISA_A64 + asm ("fcadd %0.2s, %1.2s, %2.2s, #90" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + + #else + asm ("vcadd.f32 %P0, %P1, %P2, #90" + : "=w"(results) + : "w"(a), "w"(b) + : /* No clobbers. */); + #endif + + return (results[0] == 8 && results[1] == 24) ? 0 : 1; + } + } [add_options_for_arm_v8_3a_complex_neon ""]] +} + +# Return 1 if the assembler supports assembling the Armv8.3 pointer authentication B key directive +proc check_effective_target_arm_v8_3a_bkey_directive { } { + return [check_no_compiler_messages cet object { + int main(void) { + asm (".cfi_b_key_frame"); + return 0; + } + }] +} + +# Return 1 if the target supports executing the Armv8.1-M Mainline Low +# Overhead Loop, 0 otherwise. The test is valid for ARM. + +proc check_effective_target_arm_v8_1_lob_ok { } { + if { ![check_effective_target_arm_cortex_m] } { + return 0; + } else { + return [check_runtime arm_v8_1_lob_hw_available { + int + main (void) + { int i = 0; + asm ("movw r3, #10\n\t" /* movs? */ + "dls lr, r3" : : : "r3", "lr"); + loop: + i++; + asm goto ("le lr, %l0" : : : "lr" : loop); + return i != 10; + } + } "-march=armv8.1-m.main -mthumb" ] + } +} + +# Return 1 if this is an ARM target where Thumb-2 is used without +# options added by the test and the target does not support executing +# the Armv8.1-M Mainline Low Overhead Loop, 0 otherwise. The test is +# valid for ARM. + +proc check_effective_target_arm_thumb2_no_arm_v8_1_lob { } { + if { [check_effective_target_arm_thumb2] + && ![check_effective_target_arm_v8_1_lob_ok] } { + return 1 + } + return 0 +} + +# Return 1 if this is an ARM target where -mthumb causes Thumb-2 to be +# used and the target does not support executing the Armv8.1-M +# Mainline Low Overhead Loop, 0 otherwise. The test is valid for ARM. + +proc check_effective_target_arm_thumb2_ok_no_arm_v8_1_lob { } { + if { [check_effective_target_arm_thumb2_ok] + && ![check_effective_target_arm_v8_1_lob_ok] } { + return 1 + } + return 0 +} + +# Returns 1 if the target is using glibc, 0 otherwise. + +proc check_effective_target_glibc { } { + return [check_no_compiler_messages glibc_object assembly { + #include + #if !defined(__GLIBC__) + #error undefined + #endif + }] +} + +# Return 1 if the target plus current options supports a vector +# complex addition with rotate of half and single float modes, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +foreach N {hf sf} { + eval [string map [list N $N] { + proc check_effective_target_vect_complex_rot_N { } { + return [check_cached_effective_target_indexed vect_complex_rot_N { + expr { [istarget aarch64*-*-*] + || [istarget arm*-*-*] }}] + } + }] +} + +# Return 1 if the target plus current options supports a vector +# complex addition with rotate of double float modes, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +foreach N {df} { + eval [string map [list N $N] { + proc check_effective_target_vect_complex_rot_N { } { + return [check_cached_effective_target_indexed vect_complex_rot_N { + expr { [istarget aarch64*-*-*] }}] + } + }] +} + +# Return 1 if this target uses an LLVM assembler and/or linker +proc check_effective_target_llvm_binutils { } { + return [check_cached_effective_target llvm_binutils { + expr { [istarget amdgcn*-*-*] + || [check_effective_target_offload_gcn] }}] +} + +# Return 1 if the compiler supports '-mfentry'. + +proc check_effective_target_mfentry { } { + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + return [check_no_compiler_messages mfentry object { + void foo (void) { } + } "-mfentry"] +} + +# Return 1 if this target supports indirect calls +proc check_effective_target_indirect_calls { } { + if { [istarget bpf-*-*] } { + return 0 + } + return 1 +} + +# Return 1 if we can use the -lgccjit option, 0 otherwise. + +proc check_effective_target_lgccjit { } { + if { [info procs jit_target_compile] == "" } then { + global GCC_UNDER_TEST + if ![info exists GCC_UNDER_TEST] { + set GCC_UNDER_TEST "[find_gcc]" + } + proc jit_target_compile { source dest type options } [info body gcc_target_compile] + } + return [check_no_compiler_messages lgccjit executable { + int main() { return 0; } + } "-lgccjit"] +} + +# Return 1 if the MSP430 small memory model is in use. +proc check_effective_target_msp430_small {} { + return [check_no_compiler_messages msp430_small assembly { + #if (!defined __MSP430__ || defined __MSP430X_LARGE__) + #error !msp430 || __MSP430X_LARGE__ + #endif + } ""] +} + +# Return 1 if the MSP430 large memory model is in use. +proc check_effective_target_msp430_large {} { + return [check_no_compiler_messages msp430_large assembly { + #ifndef __MSP430X_LARGE__ + #error __MSP430X_LARGE__ + #endif + } ""] +} + +# Return 1 if GCC was configured with --with-tune=cortex-a76 +proc check_effective_target_tune_cortex_a76 { } { + return [check_configured_with "with-tune=cortex-a76"] +} + +# Return 1 if the target has an efficient means to encode large initializers +# in the assembly. + +proc check_effective_target_large_initializer { } { + if { [istarget nvptx*-*-*] } { + return 0 + } + + return 1 +} + +# Return 1 if the target allows function prototype mismatches +# in the assembly. + +proc check_effective_target_non_strict_prototype { } { + if { [istarget nvptx*-*-*] } { + return 0 + } + + return 1 +} + +# Returns 1 if the target toolchain supports extended +# syntax of .symver directive, 0 otherwise. + +proc check_symver_available { } { + return [check_no_compiler_messages symver_available object { + int foo(void) { return 0; } + int main (void) { + asm volatile (".symver foo,foo@VER_1, local"); + return 0; + } + }] +} + +# Return 1 if emitted assembly contains .ident directive. + +proc check_effective_target_ident_directive {} { + return [check_no_messages_and_pattern ident_directive \ + "(?n)^\[\t\]+\\.ident" assembly { + int i; + }] +} + +# Return 1 if we're able to assemble movdiri and movdir64b + +proc check_effective_target_movdir { } { + return [check_no_compiler_messages movdir object { + void + foo (unsigned int *d, unsigned int s) + { + __builtin_ia32_directstoreu_u32 (d, s); + } + void + bar (void *d, const void *s) + { + __builtin_ia32_movdir64b (d, s); + } + } "-mmovdiri -mmovdir64b" ] +} + +# Return 1 if the target does not support address sanitizer, 0 otherwise + +proc check_effective_target_no_fsanitize_address {} { + if ![check_no_compiler_messages fsanitize_address executable { + int main (void) { return 0; } + } "-fsanitize=address" ] { + return 1; + } + + return 0; +} + +# Return 1 if this target supports 'R' flag in .section directive, 0 +# otherwise. Cache the result. + +proc check_effective_target_R_flag_in_section { } { + 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 R_flag_in_section { + + 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_GAS_SHF_GNU_RETAIN == 0 || HAVE_INITFINI_ARRAY_SUPPORT == 0" + puts $f "# error Assembler does not support 'R' flag in .section directive." + puts $f "#endif" + close $f + + verbose "check_effective_target_R_flag_in_section compiling testfile $src" 2 + set lines [${tool}_target_compile $src $obj assembly ""] + + file delete $src + file delete $obj + + if [string match "" $lines] then { + verbose "check_effective_target_R_flag_in_section testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_R_flag_in_section testfile compilation failed" 2 + return 0 + } + }] +} + +# Return 1 if this target supports 'o' flag in .section directive, 0 +# otherwise. Cache the result. + +proc check_effective_target_o_flag_in_section { } { + 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 o_flag_in_section { + + 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_GAS_SECTION_LINK_ORDER == 0" + puts $f "# error Assembler does not support 'o' flag in .section directive." + puts $f "#endif" + close $f + + verbose "check_effective_target_o_flag_in_section 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_o_flag_in_section testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_o_flag_in_section testfile compilation failed" 2 + return 0 + } + }] +} + +# return 1 if LRA is supported. + +proc check_effective_target_lra { } { + if { [istarget hppa*-*-*] } { + return 0 + } + return 1 +} + +# Test whether optimizations are enabled ('__OPTIMIZE__') per the +# 'current_compiler_flags' (thus don't cache). + +proc check_effective_target___OPTIMIZE__ {} { + return [check_no_compiler_messages_nocache __OPTIMIZE__ assembly { + #ifndef __OPTIMIZE__ + # error nein + #endif + /* Avoid pedwarn about empty TU. */ + int dummy; + } [current_compiler_flags]] +} + +# Return 1 if python3 (>= 3.6) is available. + +proc check_effective_target_recent_python3 { } { + set result [remote_exec host "python3 -c \"import sys; assert sys.version_info >= (3, 6)\""] + set status [lindex $result 0] + if { $status == 0 } then { + return 1; + } else { + return 0; + } +} + +# Return 1 if python3 contains a module + +proc check_effective_target_python3_module { module } { + set result [remote_exec host "python3 -c \"import $module\""] + set status [lindex $result 0] + if { $status == 0 } then { + return 1; + } else { + return 0; + } +} + +# Return 1 if pytest module is available for python3. + +proc check_effective_target_pytest3 { } { + set result [remote_exec host "python3 -m pytest --color=no -rap -s --tb=no --version"] + set status [lindex $result 0] + if { $status == 0 } then { + return 1; + } else { + return 0; + } +} + +proc check_effective_target_property_1_needed { } { + return [check_no_compiler_messages property_1_needed executable { +/* Assembly code */ +#ifdef __LP64__ +# define __PROPERTY_ALIGN 3 +#else +# define __PROPERTY_ALIGN 2 +#endif + + .section ".note.gnu.property", "a" + .p2align __PROPERTY_ALIGN + .long 1f - 0f /* name length. */ + .long 4f - 1f /* data length. */ + /* NT_GNU_PROPERTY_TYPE_0. */ + .long 5 /* note type. */ +0: + .asciz "GNU" /* vendor name. */ +1: + .p2align __PROPERTY_ALIGN + /* GNU_PROPERTY_1_NEEDED. */ + .long 0xb0008000 /* pr_type. */ + .long 3f - 2f /* pr_datasz. */ +2: + /* GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. */ + .long 1 +3: + .p2align __PROPERTY_ALIGN +4: + .text + .globl main +main: + .byte 0 + } ""] +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-utils.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-utils.exp new file mode 100644 index 0000000000000000000000000000000000000000..2c209931565bef16bef3246b67df0070bbf2ddde --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/target-utils.exp @@ -0,0 +1,52 @@ +# Copyright (C) 2014-2022 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 +# . + +# +# ${tool}_check_unsupported_p -- Check the compiler(/assembler/linker) output +# for text indicating that the testcase should be marked as "unsupported" +# +# When dealing with a large number of tests, it's difficult to weed out the +# ones that are too big for a particular cpu (eg: 16 bit with a small amount +# of memory). There are various ways to deal with this. Here's one. +# Fortunately, all of the cases where this is likely to happen will be using +# gld so we can tell what the error text will look like. +# + +load_lib target-supports.exp + +proc ${tool}_check_unsupported_p { output } { + if [regexp "(^|\n)\[^\n\]*: region \[^\n\]* is full" $output] { + return "memory full" + } + if { [regexp "(^|\n)\[^\n\]*: relocation truncated to fit" $output] + && [check_effective_target_tiny] } { + return "memory full" + } + if { [regexp "(^|\n)\[^\n\]*: region \[^\n\]* overflowed" $output] + && [check_effective_target_tiny] } { + return "memory full" + } + + if { [string match "*error: function pointers not supported*" $output] + && ![check_effective_target_function_pointers] } { + return "function pointers not supported" + } + if { [string match "*error: large return values not supported*" $output] + && ![check_effective_target_large_return_values] } { + return "large return values not supported" + } + return "" +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/timeout-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/timeout-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..ad94b500da868c30e5042ffeb12416ae13f26cf6 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/timeout-dg.exp @@ -0,0 +1,49 @@ +# Copyright (C) 2008-2022 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 +# . + +# +# dg-timeout -- Set the timout limit, in seconds, for a particular test +# + +proc dg-timeout { args } { + global individual_timeout + + set args [lreplace $args 0 0] + if { [llength $args] > 1 } { + if { [dg-process-target [lindex $args 1]] == "S" } { + set individual_timeout [lindex $args 0] + } + } else { + set individual_timeout [lindex $args 0] + } +} + +# +# dg-timeout-factor -- Scale the timeout limit for a particular test +# + +proc dg-timeout-factor { args } { + global timeout_factor + + set args [lreplace $args 0 0] + if { [llength $args] > 1 } { + if { [dg-process-target [lindex $args 1]] == "S" } { + set timeout_factor [lindex $args 0] + } + } else { + set timeout_factor [lindex $args 0] + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/timeout.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/timeout.exp new file mode 100644 index 0000000000000000000000000000000000000000..6cc930f50168b82037876103a0b56a62b7cf0e76 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/timeout.exp @@ -0,0 +1,83 @@ +# Copyright (C) 2008-2022 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 +# . + +# +# unset_timeout_vars -- Unset variables used for timeouts +# + +proc unset_timeout_vars { args } { + global individual_timeout + global timeout_factor + + if [info exists individual_timeout] { + unset individual_timeout + } + if [info exists timeout_factor] { + unset timeout_factor + } +} + +# +# timeout_value -- Return the integer timeout value to use for this test +# + +proc timeout_value { args } { + global tool_timeout + global individual_timeout + global timeout_factor + + # Find the current timeout limit, in seconds. + if [info exists individual_timeout] { + set val $individual_timeout + } elseif [info exists tool_timeout] { + set val $tool_timeout + } elseif [target_info exists gcc,timeout] { + set val [target_info gcc,timeout] + } elseif [board_info target exists gcc,timeout] { + set val [board_info target gcc,timeout] + } else { + # This is really, REALLY ugly, but this is the default from + # remote.exp deep within DejaGnu. + set val 300 + } + + # If the test specified a timeout factor, adjust by that. + if [info exists timeout_factor] { + set val [expr int([expr $val * $timeout_factor])] + } + + return $val +} + +# +# standard_wait -- Set the timeout value used by DejaGnu +# + +# Override standard_wait from DejaGnu to use timeout value specified by +# by the user or by the target board, possibly multiplied by a factor +# for a particular test. + +if { [info procs standard_wait] != [list] \ + && [info procs saved_standard_wait] == [list] } { + rename standard_wait saved_standard_wait + proc standard_wait { dest timeout } { + set val [timeout_value] + if { $val != 0 } { + set timeout $val + } + saved_standard_wait $dest $timeout + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/torture-options.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/torture-options.exp new file mode 100644 index 0000000000000000000000000000000000000000..a63fb0784844832e56034b365c02dae7a5f0b48d --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/torture-options.exp @@ -0,0 +1,120 @@ +# Copyright (C) 2008-2022 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 +# . + +# Prepare to use a new set of torture options. +# +# Letting options leak from one set of tests to another can be confusing. +# Make sure variables are not set at the time we're called, because that +# would mean they were set without being cleared. +proc torture-init { args } { + global torture_without_loops global_with_loops + + if [info exists torture_without_loops] { + error "torture-init: torture_without_loops is not empty as expected" + } + if [info exists torture_with_loops] { + error "torture-init: torture_with_loops is not empty as expected" + } +} + +# Return 1 if torture options have already been set, 0 otherwise. +proc torture-options-exist { args } { + global torture_with_loops + return [info exists torture_with_loops] +} + +# Return 1 if compiler option ARG only affects loops, 0 otherwise. +proc contains-loop-option-p { arg } { + switch -glob -- $arg { + "*loop*" { return 1 } + default { return 0 } + } +} + +# Set torture options variables for tests with and without loops. +# +# Argument 0 is the list to use as torture options +# Argument 1 is the list to combine with the torture options. +# Argument 2 is the list to be appended to the torture options after +# combining argument 0 and 1. +proc set-torture-options { args } { + global torture_with_loops torture_without_loops + + set torture_list [lindex $args 0] + + if { [llength $args] > 1 } { + set other_list [lindex $args 1] + } else { + set other_list [list {}] + } + + set torture_with_loops "" + set torture_without_loops "" + foreach torture_opts $torture_list { + foreach other_opts $other_list { + # Remove trailing space[s] to match previous output. + set torture_opts [string trimright $torture_opts] + if ![contains-loop-option-p $torture_opts] { + lappend torture_without_loops "$torture_opts $other_opts" + } + lappend torture_with_loops "$torture_opts $other_opts" + } + } + + if { [llength $args] > 2 } { + set append_list [lindex $args 2] + append torture_with_loops " $append_list" + append torture_without_loops " $append_list" + } +} + +# Finish up after using a set of torture options. +# +# Letting options leak from one set of tests to another can be confusing. +# Make sure variables are set at the time we're called, and then unset +# them to prevent interference with other sets of tests. +proc torture-finish { args } { + global torture_without_loops torture_with_loops + + if [info exists torture_without_loops] { + unset torture_without_loops + } else { + error "torture-finish: torture_without_loops is not defined" + } + + if [info exists torture_with_loops] { + unset torture_with_loops + } else { + error "torture-finish: torture_with_loops is not defined" + } +} + +# Useful for debugging .exp files. +proc dump-torture-options { args } { + global torture_without_loops torture_with_loops + + if [info exists torture_without_loops] { + verbose "torture_without_loops = \"${torture_without_loops}\"" 1 + } else { + verbose "torture_without_loops is not defined" 1 + } + + if [info exists torture_with_loops] { + verbose "torture_with_loops = \"${torture_with_loops}\"" 1 + } else { + verbose "torture_with_loops is not defined" 1 + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/tsan-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/tsan-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..fcc20d057ddbd92b15617d5249b33a81dc1e0bae --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/tsan-dg.exp @@ -0,0 +1,158 @@ +# Copyright (C) 2013-2022 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 +# . + +# Return 1 if compilation with -fsanitize=thread is error-free for trivial +# code, 0 otherwise. Also set what to do by default here, depending on the +# result of a runtime test. + +proc check_effective_target_fsanitize_thread {} { + global individual_timeout + global dg-do-what-default + + if ![check_no_compiler_messages fsanitize_thread executable { + int main (void) { return 0; } + }] { + return 0 + } + + # Lower timeout value in case test does not terminate properly. + set individual_timeout 20 + if [check_runtime_nocache tsan_works { + int main () { return 0; } + }] { + set dg-do-what-default run + } else { + set dg-do-what-default link + } + unset individual_timeout + + return 1 +} + +# +# tsan_link_flags -- compute library path and flags to find libtsan. +# (originally from g++.exp) +# + +proc tsan_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + global tsan_saved_library_path + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + set tsan_saved_library_path $ld_library_path + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/tsan/.libs/libtsan.a"] + || [file exists "${gccpath}/libsanitizer/tsan/.libs/libtsan.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/tsan/ " + append flags " -L${gccpath}/libsanitizer/tsan/.libs " + append ld_library_path ":${gccpath}/libsanitizer/tsan/.libs" + } + } else { + global tool_root_dir + + set libtsan [lookfor_file ${tool_root_dir} libtsan] + if { $libtsan != "" } { + append flags "-L${libtsan} " + append ld_library_path ":${libtsan}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# tsan_init -- called at the start of each subdir of tests +# + +proc tsan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global tsan_saved_TEST_ALWAYS_FLAGS + global tsan_saved_ALWAYS_CXXFLAGS + global dg-do-what-default + global tsan_saved_dg-do-what-default + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[tsan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[tsan_link_flags [get_multilibs]]" + } + } + + if [info exists dg-do-what-default] { + set tsan_saved_dg-do-what-default ${dg-do-what-default} + } + if [info exists TEST_ALWAYS_FLAGS] { + set tsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set tsan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=thread -g}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=thread -g $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=thread -g" + } + } +} + +# +# tsan_finish -- called at the end of each subdir of tests +# + +proc tsan_finish { args } { + global TEST_ALWAYS_FLAGS + global tsan_saved_TEST_ALWAYS_FLAGS + global tsan_saved_ALWAYS_CXXFLAGS + global dg-do-what-default + global tsan_saved_dg-do-what-default + global tsan_saved_library_path + global ld_library_path + + if [info exists tsan_saved_ALWAYS_CXXFLAGS ] { + set ALWAYS_CXXFLAGS $tsan_saved_ALWAYS_CXXFLAGS + } else { + if [info exists tsan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $tsan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + + if [info exists tsan_saved_dg-do-what-default] { + set dg-do-what-default ${tsan_saved_dg-do-what-default} + } else { + unset dg-do-what-default + } + if [info exists tsan_saved_library_path ] { + set ld_library_path $tsan_saved_library_path + set_ld_library_path_env_vars + } + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/ubsan-dg.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/ubsan-dg.exp new file mode 100644 index 0000000000000000000000000000000000000000..1c617d89d99d735887fe958f83fce4206e542823 --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/ubsan-dg.exp @@ -0,0 +1,149 @@ +# Copyright (C) 2013-2022 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 +# . + +# Return 1 if compilation with -fsanitize=undefined is error-free for trivial +# code, 0 otherwise. + +set orig_ubsan_options_saved 0 +set orig_ubsan_options 0 + +proc check_effective_target_fsanitize_undefined {} { + return [check_runtime fsanitize_undefined { + int main (void) { return 0; } + } "-fsanitize=undefined"] +} + +# +# ubsan_link_flags -- compute library path and flags to find libubsan. +# (originally from g++.exp) +# + +proc ubsan_link_flags { paths } { + global srcdir + global ld_library_path + global shlib_ext + global ubsan_saved_library_path + + set gccpath ${paths} + set flags "" + + set shlib_ext [get_shlib_extension] + set ubsan_saved_library_path $ld_library_path + + if { $gccpath != "" } { + if { [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.a"] + || [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.${shlib_ext}"] } { + append flags " -B${gccpath}/libsanitizer/ " + append flags " -B${gccpath}/libsanitizer/ubsan/ " + append flags " -L${gccpath}/libsanitizer/ubsan/.libs" + append ld_library_path ":${gccpath}/libsanitizer/ubsan/.libs" + append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" + } + } else { + global tool_root_dir + + set libubsan [lookfor_file ${tool_root_dir} libubsan] + if { $libubsan != "" } { + append flags "-L${libubsan} " + append ld_library_path ":${libubsan}" + } + } + + set_ld_library_path_env_vars + + return "$flags" +} + +# +# ubsan_init -- called at the start of each subdir of tests +# + +proc ubsan_init { args } { + global TEST_ALWAYS_FLAGS + global ALWAYS_CXXFLAGS + global TOOL_OPTIONS + global ubsan_saved_TEST_ALWAYS_FLAGS + global ubsan_saved_ALWAYS_CXXFLAGS + global orig_ubsan_options_saved + global orig_ubsan_options + + if { $orig_ubsan_options_saved == 0 } { + # Save the original environment. + if [info exists env(UBSAN_OPTIONS)] { + set orig_ubsan_options "$env(UBSAN_OPTIONS)" + set orig_ubsan_options_saved 1 + } + } + setenv UBSAN_OPTIONS color=never + + set link_flags "" + if ![is_remote host] { + if [info exists TOOL_OPTIONS] { + set link_flags "[ubsan_link_flags [get_multilibs ${TOOL_OPTIONS}]]" + } else { + set link_flags "[ubsan_link_flags [get_multilibs]]" + } + } + + if [info exists TEST_ALWAYS_FLAGS] { + set ubsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS + } + if [info exists ALWAYS_CXXFLAGS] { + set ubsan_saved_ALWAYS_CXXFLAGS $ALWAYS_CXXFLAGS + set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS] + } else { + if [info exists TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS "$link_flags $TEST_ALWAYS_FLAGS" + } else { + set TEST_ALWAYS_FLAGS "$link_flags" + } + } +} + +# +# ubsan_finish -- called at the end of each subdir of tests +# + +proc ubsan_finish { args } { + global TEST_ALWAYS_FLAGS + global ubsan_saved_TEST_ALWAYS_FLAGS + global ubsan_saved_ALWAYS_CXXFLAGS + global ubsan_saved_library_path + global ld_library_path + global orig_ubsan_options_saved + global orig_ubsan_options + + if { $orig_ubsan_options_saved } { + setenv UBSAN_OPTIONS "$orig_ubsan_options" + } elseif [info exists env(UBSAN_OPTIONS)] { + unsetenv UBSAN_OPTIONS + } + + if [info exists ubsan_saved_ALWAYS_CXXFLAGS ] { + set ALWAYS_CXXFLAGS $ubsan_saved_ALWAYS_CXXFLAGS + } else { + if [info exists ubsan_saved_TEST_ALWAYS_FLAGS] { + set TEST_ALWAYS_FLAGS $ubsan_saved_TEST_ALWAYS_FLAGS + } else { + unset TEST_ALWAYS_FLAGS + } + } + if [info exists ubsan_saved_library_path ] { + set ld_library_path $ubsan_saved_library_path + set_ld_library_path_env_vars + } + clear_effective_target_cache +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/wrapper.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/wrapper.exp new file mode 100644 index 0000000000000000000000000000000000000000..5a601b269daad24d9091e1d9321465f700bec3af --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/lib/wrapper.exp @@ -0,0 +1,48 @@ +# Copyright (C) 2004-2022 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 +# . + +# This file contains GCC-specifics for status wrappers for test programs. + +# ${tool}_maybe_build_wrapper -- Build wrapper object if the target +# needs it. FILENAME is the path to the wrapper file. If there are +# additional arguments, they are command-line options to provide to +# the compiler when compiling FILENAME. + +proc ${tool}_maybe_build_wrapper { filename args } { + global gluefile wrap_flags + + if { [target_info needs_status_wrapper] != "" \ + && [target_info needs_status_wrapper] != "0" \ + && ![info exists gluefile] } { + set_ld_library_path_env_vars + set saved_wrap_compile_flags [target_info wrap_compile_flags] + set flags [join $args " "] + # The wrapper code may contain code that gcc objects on. This + # became true for dejagnu-1.4.4. The set of warnings and code + # that gcc objects on may change, so just make sure -w is always + # passed to turn off all warnings. + unset_currtarget_info wrap_compile_flags + set_currtarget_info wrap_compile_flags \ + "$saved_wrap_compile_flags -w $flags" + set result [build_wrapper $filename] + unset_currtarget_info wrap_compile_flags + set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags" + if { $result != "" } { + set gluefile [lindex $result 0] + set wrap_flags [lindex $result 1] + } + } +} diff --git a/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/site.exp b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/site.exp new file mode 100644 index 0000000000000000000000000000000000000000..435bd309e81e4406cfe277f305ab21f4356e30ea --- /dev/null +++ b/testcases/cli-test/gcc/oe_test_dejagnu/testsuite-gcc12/site.exp @@ -0,0 +1,22 @@ +## these variables are automatically generated by make ## +# Do not edit here. If you wish to override these values +# add them to the last section +set host_triplet aarch64-openEuler-linux-gnu +set build_triplet aarch64-openEuler-linux-gnu +set target_triplet aarch64-openEuler-linux-gnu +set target_alias aarch64-linux-gnu +set libiconv "" +set CFLAGS "" +set CXXFLAGS "" +set HOSTCC "gcc" +set HOSTCXX "g++" +set HOSTCFLAGS "-g -O2" +set HOSTCXXFLAGS "-g -O2" +set TEST_ALWAYS_FLAGS "" +set TESTING_IN_BUILD_TREE 1 +set HAVE_LIBSTDCXX_V3 1 +set ENABLE_PLUGIN 1 +set PLUGINCC "g++" +set PLUGINCFLAGS "-g " +set GMPINC "" +## All variables above are generated by configure. Do Not Edit ##