wxiao3 created this revision. wxiao3 added reviewers: annita.zhang, LuoYuanke, smaslov, craig.topper, hjl.tools, rnk, andreadb, gbedwell, rjmccall, krytarowski, mgorny, joerg, RKSimon, hans, thakis. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The System V i386 bug fix (https://reviews.llvm.org/D59744) makes it impossible for 32-bit Linux Chromium to write an assembly function that works with both trunk clang and clang 8.0.0, which makes it difficult to update compilers independent of changing the code (more details: https://bugs.chromium.org/p/chromium/issues/detail?id=974542#c5). This patch aims to provide a solution for such situation. Repository: rC Clang https://reviews.llvm.org/D63473 Files: docs/ReleaseNotes.rst include/clang/Basic/LangOptions.h lib/CodeGen/TargetInfo.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/x86_32-m64.c Index: test/CodeGen/x86_32-m64.c =================================================================== --- test/CodeGen/x86_32-m64.c +++ test/CodeGen/x86_32-m64.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -w -O2 -fblocks -triple i386-apple-darwin9 -target-cpu yonah -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,DARWIN // RUN: %clang_cc1 -w -O2 -fblocks -triple i386-pc-elfiamcu -mfloat-abi soft -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,IAMCU // RUN: %clang_cc1 -w -O2 -fblocks -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WIN32 +// RUN: %clang_cc1 -w -O2 -fblocks -triple i386-pc-linux-gnu -target-cpu pentium4 -emit-llvm -fclang-abi-compat=8.0 -o - %s | FileCheck %s --check-prefixes=CHECK,OLDABI #include <mmintrin.h> __m64 m64; @@ -24,6 +25,8 @@ // WIN32-LABEL: define dso_local <1 x i64> @caller(i64 %__m1.coerce, i64 %__m2.coerce) // WIN32: call void @callee(i64 %__m2.coerce, i64 %__m1.coerce) // WIN32: ret <1 x i64> +// OLDABI: tail call void @callee(i64 %__m2.coerce, i64 %__m1.coerce) +// OLDABI: ret <1 x i64> callee(__m2, __m1); return m64; } Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -3104,6 +3104,8 @@ Opts.setClangABICompat(LangOptions::ClangABI::Ver6); else if (Major <= 7) Opts.setClangABICompat(LangOptions::ClangABI::Ver7); + else if (Major <= 8) + Opts.setClangABICompat(LangOptions::ClangABI::Ver8); } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -1088,6 +1088,11 @@ } bool isPassInMMXRegABI() const { + // Clang <= 8.0 did not do this for compatiblity with old behavior. + if (getContext().getLangOpts().getClangABICompat() <= + LangOptions::ClangABI::Ver8) + return false; + // The System V i386 psABI requires __m64 to be passed in MMX registers. // Clang historically had a bug where it failed to apply this rule, and // some platforms (e.g. Darwin, PS4, and FreeBSD) have opted to maintain Index: include/clang/Basic/LangOptions.h =================================================================== --- include/clang/Basic/LangOptions.h +++ include/clang/Basic/LangOptions.h @@ -138,6 +138,11 @@ /// rather than returning the required alignment. Ver7, + /// Attempt to be ABI-compatible with code generated by Clang 8.0.x + /// (https://reviews.llvm.org/D59744). This causes __m64 to be passed in + /// MMX register instead of integer register. + Ver8, + /// Conform to the underlying platform's C and C++ ABIs as closely /// as we can. Latest Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -142,6 +142,14 @@ ABI Changes in Clang -------------------- +- The System V i386 psABI requires __m64 to be passed in MMX registers. + Clang historically had a bug where it failed to apply this rule, and + some platforms (e.g. Darwin, PS4, and FreeBSD) have opted to maintain + compatibility with the old Clang behavior, so we only apply it on + platforms that have specifically requested it (currently just Linux and + NetBSD). You can switch back to old API behavior with flag: + -fclang-abi-compat=8.0. + - ... OpenMP Support in Clang
Index: test/CodeGen/x86_32-m64.c =================================================================== --- test/CodeGen/x86_32-m64.c +++ test/CodeGen/x86_32-m64.c @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -w -O2 -fblocks -triple i386-apple-darwin9 -target-cpu yonah -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,DARWIN // RUN: %clang_cc1 -w -O2 -fblocks -triple i386-pc-elfiamcu -mfloat-abi soft -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,IAMCU // RUN: %clang_cc1 -w -O2 -fblocks -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WIN32 +// RUN: %clang_cc1 -w -O2 -fblocks -triple i386-pc-linux-gnu -target-cpu pentium4 -emit-llvm -fclang-abi-compat=8.0 -o - %s | FileCheck %s --check-prefixes=CHECK,OLDABI #include <mmintrin.h> __m64 m64; @@ -24,6 +25,8 @@ // WIN32-LABEL: define dso_local <1 x i64> @caller(i64 %__m1.coerce, i64 %__m2.coerce) // WIN32: call void @callee(i64 %__m2.coerce, i64 %__m1.coerce) // WIN32: ret <1 x i64> +// OLDABI: tail call void @callee(i64 %__m2.coerce, i64 %__m1.coerce) +// OLDABI: ret <1 x i64> callee(__m2, __m1); return m64; } Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -3104,6 +3104,8 @@ Opts.setClangABICompat(LangOptions::ClangABI::Ver6); else if (Major <= 7) Opts.setClangABICompat(LangOptions::ClangABI::Ver7); + else if (Major <= 8) + Opts.setClangABICompat(LangOptions::ClangABI::Ver8); } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -1088,6 +1088,11 @@ } bool isPassInMMXRegABI() const { + // Clang <= 8.0 did not do this for compatiblity with old behavior. + if (getContext().getLangOpts().getClangABICompat() <= + LangOptions::ClangABI::Ver8) + return false; + // The System V i386 psABI requires __m64 to be passed in MMX registers. // Clang historically had a bug where it failed to apply this rule, and // some platforms (e.g. Darwin, PS4, and FreeBSD) have opted to maintain Index: include/clang/Basic/LangOptions.h =================================================================== --- include/clang/Basic/LangOptions.h +++ include/clang/Basic/LangOptions.h @@ -138,6 +138,11 @@ /// rather than returning the required alignment. Ver7, + /// Attempt to be ABI-compatible with code generated by Clang 8.0.x + /// (https://reviews.llvm.org/D59744). This causes __m64 to be passed in + /// MMX register instead of integer register. + Ver8, + /// Conform to the underlying platform's C and C++ ABIs as closely /// as we can. Latest Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -142,6 +142,14 @@ ABI Changes in Clang -------------------- +- The System V i386 psABI requires __m64 to be passed in MMX registers. + Clang historically had a bug where it failed to apply this rule, and + some platforms (e.g. Darwin, PS4, and FreeBSD) have opted to maintain + compatibility with the old Clang behavior, so we only apply it on + platforms that have specifically requested it (currently just Linux and + NetBSD). You can switch back to old API behavior with flag: + -fclang-abi-compat=8.0. + - ... OpenMP Support in Clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits