ro created this revision. ro added reviewers: brad, jyknight. ro added a project: clang. Herald added subscribers: Sanitizers, jfb, jrtc27, fedor.sergeev. Herald added a reviewer: jfb. Herald added a project: Sanitizers. ro requested review of this revision. Herald added a subscriber: dexonsmith.
As reported in Bug 42535, `clang` doesn't inline atomic ops on 32-bit Sparc, unlike `gcc` on Solaris. In a 1-stage build with `gcc`, only two testcases are affected (currently `XFAIL`ed), while in a 2-stage build more than 100 tests `FAIL` due to this issue. The reason for this `gcc`/`clang` difference is that `gcc` on 32-bitSolaris/SPARC defaults to `-mpcu=v9` where atomic ops are supported, unlike with `clang`'s default of `-mcpu=v8`. This patch changes `clang` to use `-mcpu=v9` on 32-bit Solaris/SPARC, too. Doing so uncovered two bugs: `clang -m32 -mcpu=v9` chokes with any Solaris system headers included: /usr/include/sys/isa_defs.h:461:2: error: "Both _ILP32 and _LP64 are defined" #error "Both _ILP32 and _LP64 are defined" While `clang` currently defines `__sparcv9` in a 32-bit `-mcpu=v9` compilation, neither `gcc` nor Studio `cc` do. In fact, the Studio 12.6 `cc(1)` man page clearly states: These predefinitions are valid in all modes: [...] __sparcv8 (SPARC) __sparcv9 (SPARC -m64) At the same time, the patch defines `__GCC_HAVE_SYNC_COMPARE_AND_SWAP_[1248]` for a 32-bit Sparc compilation with any V9 cpu. I've also changed `MaxAtomicInlineWidth` for V9, matching what `gcc` does and the Oracle Developer Studio 12.6: C User's Guide documents (Ch. 3, Support for Atomic Types, 3.1 Size and Alignment of Atomic C Types). The two testcases that had been `XFAIL`ed for Bug 42535 are un-`XFAIL`ed again. However, one of those and another testcase now `FAIL` due to Bug 42493 and are thus `XFAIL`ed. Tested on `sparcv9-sun-solaris2.11` and `amd64-pc-solaris2.11`. While the fix proper is trivial: just two lines in `lib/Driver/ToolChains/CommonArgs.cpp`, finding the right place has been nightmarishly difficult: I'd have expected handling of a Solaris/SPARC CPU default in either of Solaris or SPARC specific files, but not deeply hidden in common code. I've come across issues like this over and over again: configuration information in LLVM is spread all over the place, difficult to find or just to know that it exists. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D86621 Files: clang/lib/Basic/Targets/Sparc.cpp clang/lib/Basic/Targets/Sparc.h clang/lib/Driver/ToolChains/CommonArgs.cpp clang/test/Preprocessor/predefined-arch-macros.c compiler-rt/test/profile/Posix/instrprof-gcov-parallel.test compiler-rt/test/ubsan/TestCases/Float/cast-overflow.cpp compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp
Index: compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp =================================================================== --- compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp +++ compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp @@ -25,6 +25,9 @@ // FIXME: log_path is not supported on Windows yet. // XFAIL: windows-msvc +// Bug 42493 +// XFAIL: sparc-target-arch + #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { Index: compiler-rt/test/ubsan/TestCases/Float/cast-overflow.cpp =================================================================== --- compiler-rt/test/ubsan/TestCases/Float/cast-overflow.cpp +++ compiler-rt/test/ubsan/TestCases/Float/cast-overflow.cpp @@ -11,7 +11,7 @@ // FIXME: not %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK-8 // RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK-9 -// Bug 42535 +// Bug 42493 // XFAIL: sparc-target-arch // This test assumes float and double are IEEE-754 single- and double-precision. Index: compiler-rt/test/profile/Posix/instrprof-gcov-parallel.test =================================================================== --- compiler-rt/test/profile/Posix/instrprof-gcov-parallel.test +++ compiler-rt/test/profile/Posix/instrprof-gcov-parallel.test @@ -10,9 +10,6 @@ RUN: llvm-cov gcov instrprof-gcov-parallel.target.gcda RUN: FileCheck --input-file instrprof-gcov-parallel.target.c.gcov %s -# Bug 42535 -# XFAIL: sparc-target-arch - # Test if the .gcda file is correctly created from one of child processes # and counters of all processes are recorded correctly. # 707 = CHILDREN * COUNT Index: clang/test/Preprocessor/predefined-arch-macros.c =================================================================== --- clang/test/Preprocessor/predefined-arch-macros.c +++ clang/test/Preprocessor/predefined-arch-macros.c @@ -3232,10 +3232,26 @@ // RUN: %clang -mcpu=v9 -E -dM %s -o - 2>&1 \ // RUN: -target sparc-unknown-linux \ // RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC-V9 -// CHECK_SPARC-V9-NOT: #define __sparcv8 1 -// CHECK_SPARC-V9: #define __sparc_v9__ 1 -// CHECK_SPARC-V9: #define __sparcv9 1 -// CHECK_SPARC-V9-NOT: #define __sparcv8 1 +// CHECK_SPARC-V9: #define __sparcv8 1 +// CHECK_SPARC-V9: #define __sparcv8__ 1 +// CHECK_SPARC-V9-NOT: #define __sparc_v9__ 1 +// CHECK_SPARC-V9-NOT: #define __sparcv9 1 + +// RUN: %clang -E -dM %s -o - 2>&1 \ +// RUN: -target sparc-sun-solaris \ +// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC_SOLARIS_GCC_ATOMICS +// CHECK_SPARC_SOLARIS_GCC_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +// CHECK_SPARC_SOLARIS_GCC_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +// CHECK_SPARC_SOLARIS_GCC_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +// CHECK_SPARC_SOLARIS_GCC_ATOMICS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 + +// RUN: %clang -mcpu=v8 -E -dM %s -o - 2>&1 \ +// RUN: -target sparc-sun-solaris \ +// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SPARC_SOLARIS_GCC_ATOMICS-V8 +// CHECK_SPARC_SOLARIS_GCC_ATOMICS-V8-NOT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +// CHECK_SPARC_SOLARIS_GCC_ATOMICS-V8-NOT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +// CHECK_SPARC_SOLARIS_GCC_ATOMICS-V8-NOT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +// CHECK_SPARC_SOLARIS_GCC_ATOMICS-V8-NOT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 // RUN: %clang -E -dM %s -o - 2>&1 \ // RUN: -target sparcel-unknown-linux \ Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -347,6 +347,8 @@ case llvm::Triple::sparcv9: if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) return A->getValue(); + if (T.getArch() == llvm::Triple::sparc && T.isOSSolaris()) + return "v9"; return ""; case llvm::Triple::x86: Index: clang/lib/Basic/Targets/Sparc.h =================================================================== --- clang/lib/Basic/Targets/Sparc.h +++ clang/lib/Basic/Targets/Sparc.h @@ -166,10 +166,13 @@ PtrDiffType = SignedLong; break; } - // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops - // on up to 64 bits. + // Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're + // willing to do atomic ops on up to 64 bits. MaxAtomicPromoteWidth = 64; - MaxAtomicInlineWidth = 32; + if (getCPUGeneration(CPU) == CG_V9) + MaxAtomicInlineWidth = 64; + else + MaxAtomicInlineWidth = 32; } void getTargetDefines(const LangOptions &Opts, Index: clang/lib/Basic/Targets/Sparc.cpp =================================================================== --- clang/lib/Basic/Targets/Sparc.cpp +++ clang/lib/Basic/Targets/Sparc.cpp @@ -147,20 +147,9 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { SparcTargetInfo::getTargetDefines(Opts, Builder); - switch (getCPUGeneration(CPU)) { - case CG_V8: - Builder.defineMacro("__sparcv8"); - if (getTriple().getOS() != llvm::Triple::Solaris) - Builder.defineMacro("__sparcv8__"); - break; - case CG_V9: - Builder.defineMacro("__sparcv9"); - if (getTriple().getOS() != llvm::Triple::Solaris) { - Builder.defineMacro("__sparcv9__"); - Builder.defineMacro("__sparc_v9__"); - } - break; - } + Builder.defineMacro("__sparcv8"); + if (getTriple().getOS() != llvm::Triple::Solaris) + Builder.defineMacro("__sparcv8__"); if (getTriple().getVendor() == llvm::Triple::Myriad) { std::string MyriadArchValue, Myriad2Value; Builder.defineMacro("__sparc_v8__"); @@ -227,6 +216,12 @@ Builder.defineMacro("__myriad2__", Myriad2Value); Builder.defineMacro("__myriad2", Myriad2Value); } + if (getCPUGeneration(CPU) == CG_V9) { + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); + } } void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits