85 changes: 24 additions & 61 deletions clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3140,13 +3140,15 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
return TemplateDeductionResult::Success;
}

/// Perform template argument deduction to determine whether
/// the given template arguments match the given class template
/// partial specialization per C++ [temp.class.spec.match].
TemplateDeductionResult
Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
ArrayRef<TemplateArgument> TemplateArgs,
TemplateDeductionInfo &Info) {
/// Perform template argument deduction to determine whether the given template
/// arguments match the given class or variable template partial specialization
/// per C++ [temp.class.spec.match].
template <typename T>
static std::enable_if_t<IsPartialSpecialization<T>::value,
TemplateDeductionResult>
DeduceTemplateArguments(Sema &S, T *Partial,
ArrayRef<TemplateArgument> TemplateArgs,
TemplateDeductionInfo &Info) {
if (Partial->isInvalidDecl())
return TemplateDeductionResult::Invalid;

Expand All @@ -3158,90 +3160,51 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,

// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(
*this, Sema::ExpressionEvaluationContext::Unevaluated);
SFINAETrap Trap(*this);
S, Sema::ExpressionEvaluationContext::Unevaluated);
Sema::SFINAETrap Trap(S);

// This deduction has no relation to any outer instantiation we might be
// performing.
LocalInstantiationScope InstantiationScope(*this);
LocalInstantiationScope InstantiationScope(S);

SmallVector<DeducedTemplateArgument, 4> Deduced;
Deduced.resize(Partial->getTemplateParameters()->size());
if (TemplateDeductionResult Result = ::DeduceTemplateArguments(
*this, Partial->getTemplateParameters(),
S, Partial->getTemplateParameters(),
Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false);
Result != TemplateDeductionResult::Success)
return Result;

SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
Info);
Sema::InstantiatingTemplate Inst(S, Info.getLocation(), Partial, DeducedArgs,
Info);
if (Inst.isInvalid())
return TemplateDeductionResult::InstantiationDepth;

if (Trap.hasErrorOccurred())
return TemplateDeductionResult::SubstitutionFailure;

TemplateDeductionResult Result;
runWithSufficientStackSpace(Info.getLocation(), [&] {
Result = ::FinishTemplateArgumentDeduction(*this, Partial,
S.runWithSufficientStackSpace(Info.getLocation(), [&] {
Result = ::FinishTemplateArgumentDeduction(S, Partial,
/*IsPartialOrdering=*/false,
TemplateArgs, Deduced, Info);
});
return Result;
}

/// Perform template argument deduction to determine whether
/// the given template arguments match the given variable template
/// partial specialization per C++ [temp.class.spec.match].
TemplateDeductionResult
Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
ArrayRef<TemplateArgument> TemplateArgs,
TemplateDeductionInfo &Info) {
return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info);
}
TemplateDeductionResult
Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
ArrayRef<TemplateArgument> TemplateArgs,
TemplateDeductionInfo &Info) {
if (Partial->isInvalidDecl())
return TemplateDeductionResult::Invalid;

// C++ [temp.class.spec.match]p2:
// A partial specialization matches a given actual template
// argument list if the template arguments of the partial
// specialization can be deduced from the actual template argument
// list (14.8.2).

// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(
*this, Sema::ExpressionEvaluationContext::Unevaluated);
SFINAETrap Trap(*this);

// This deduction has no relation to any outer instantiation we might be
// performing.
LocalInstantiationScope InstantiationScope(*this);

SmallVector<DeducedTemplateArgument, 4> Deduced;
Deduced.resize(Partial->getTemplateParameters()->size());
if (TemplateDeductionResult Result = ::DeduceTemplateArguments(
*this, Partial->getTemplateParameters(),
Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false);
Result != TemplateDeductionResult::Success)
return Result;

SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
Info);
if (Inst.isInvalid())
return TemplateDeductionResult::InstantiationDepth;

if (Trap.hasErrorOccurred())
return TemplateDeductionResult::SubstitutionFailure;

TemplateDeductionResult Result;
runWithSufficientStackSpace(Info.getLocation(), [&] {
Result = ::FinishTemplateArgumentDeduction(*this, Partial,
/*IsPartialOrdering=*/false,
TemplateArgs, Deduced, Info);
});
return Result;
return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info);
}

/// Determine whether the given type T is a simple-template-id type.
Expand Down
75 changes: 75 additions & 0 deletions clang/test/C/C99/n717.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// RUN: %clang_cc1 -verify -std=c99 %s
// RUN: %clang_cc1 -verify -std=c99 -fno-dollars-in-identifiers %s

/* WG14 N717: Clang 17
* Extended identifiers
*/

// Used as a sink for UCNs.
#define M(arg)

// C99 6.4.3p1 specifies the grammar for UCNs. A \u must be followed by exactly
// four hex digits, and \U must be followed by exactly eight.
M(\u1) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\u12) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\u123) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\u1234) // Okay
M(\u12345)// Okay, two tokens (UCN followed by 5)

M(\U1) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\U12) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\U123) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\U1234) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}} \
expected-note {{did you mean to use '\u'?}}
M(\U12345) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\U123456) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\U1234567) // expected-warning {{incomplete universal character name; treating as '\' followed by identifier}}
M(\U12345678) // Okay
M(\U123456789) // Okay-ish, two tokens (valid-per-spec-but-actually-invalid UCN followed by 9)

// Now test the ones that should work. Note, these work in C17 and earlier but
// are part of the basic character set in C23 and thus should be diagnosed in
// that mode. They're valid in a character constant, but not valid in an
// identifier, except for U+0024 which is allowed if -fdollars-in-identifiers
// is enabled.
// FIXME: These three should be handled the same way, and should be accepted
// when dollar signs are allowed in identifiers, rather than rejected, see
// GH87106.
M(\u0024) // expected-error {{character '$' cannot be specified by a universal character name}}
M(\U00000024) // expected-error {{character '$' cannot be specified by a universal character name}}
M($)

// These should always be rejected because they're not valid identifier
// characters.
// FIXME: the diagnostic could be improved to make it clear this is an issue
// with forming an identifier rather than a UCN.
M(\u0040) // expected-error {{character '@' cannot be specified by a universal character name}}
M(\u0060) // expected-error {{character '`' cannot be specified by a universal character name}}
M(\U00000040) // expected-error {{character '@' cannot be specified by a universal character name}}
M(\U00000060) // expected-error {{character '`' cannot be specified by a universal character name}}

// UCNs outside of identifiers are handled in Phase 5 of translation, so we
// cannot use the macro expansion to test their behavior.

// This is outside of the range of values specified by ISO 10646.
const char *c1 = "\U00110000"; // expected-error {{invalid universal character}}
// This does not fall outside of the range
const char *c2 = "\U0010FFFF";

// These should always be accepted because they're a valid in a character
// constant.
int c3 = '\u0024';
int c4 = '\u0040';
int c5 = '\u0060';

int c6 = '\U00000024';
int c7 = '\U00000040';
int c8 = '\U00000060';

// Valid lone surrogates.
M(\uD799)
const char *c9 = "\U0000E000";

// Invalid lone surrogates, which are excluded explicitly by 6.4.3p2.
M(\uD800) // expected-error {{invalid universal character}}
const char *c10 = "\U0000DFFF"; // expected-error {{invalid universal character}}
59 changes: 59 additions & 0 deletions clang/test/SemaHLSL/literal_suffixes.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-library -fnative-half-type -Wconversion -verify %s

void literal_assignments() {
half h;

h = 2.0h; // No conversion, no diagnostic expected.

// Literal conversions that don't lose precision also don't cause diagnostics.
// Conversion from double (no diagnostic expected)
h = 2.0l;
h = 2.0;
h = 2.0f;

// Literal assignments with conversions that lose precision produce
// diagnostics under `-Wconversion`.

// Lose precision on assignment.
h = 3.1415926535897932384626433h; // No diagnostic expected because this isn't a conversion.

// Lose precision on assignment converting float to half.
h = 3.1415926535897932384626433f; // expected-warning {{implicit conversion loses floating-point precision: 'float' to 'half'}}

// Lose precision on assignment converting float to half.
h = 3.1415926535897932384626433f * 2.0f; // expected-warning {{implicit conversion loses floating-point precision: 'float' to 'half'}}

// Lose precision on assignment converting double to half.
h = 3.1415926535897932384626433l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}}

// Lose precision on assignment converting double to half.
h = 3.1415926535897932384626433l * 2.0l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}}

// Literal assinments of values out of the representable range produce
// warnings.

h = 66000.h; // expected-warning {{magnitude of floating-point constant too large for type 'half'; maximum is 65504}}
h = -66000.h; // expected-warning {{magnitude of floating-point constant too large for type 'half'; maximum is 65504}}

// The `h` suffix is invalid on integer literals.
h = 66000h; // expected-error {{invalid suffix 'h' on integer constant}}
}

template <typename T, typename U>
struct is_same {
static const bool value = false;
};

template <typename T>
struct is_same<T, T> {
static const bool value = true;
};

// The no-suffix behavior is currently wrong. The behavior in DXC is complicated
// and undocumented. We have a language change planned to address this, and an
// issue tracking: https://github.com/llvm/llvm-project/issues/85714.
_Static_assert(is_same<double, __decltype(1.0)>::value, "1.0f literal is double (should be float)");

_Static_assert(is_same<half, __decltype(1.0h)>::value, "1.0h literal is half");
_Static_assert(is_same<float, __decltype(1.0f)>::value, "1.0f literal is float");
_Static_assert(is_same<double, __decltype(1.0l)>::value, "1.0l literal is double");
59 changes: 59 additions & 0 deletions clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-library -Wconversion -verify %s

void literal_assignments() {
half h;

h = 2.0h; // No conversion, no diagnostic expected.

// Literal conversions that don't lose precision also don't cause diagnostics.
// Conversion from double (no diagnostic expected)
h = 2.0l;
h = 2.0;
h = 2.0f;

// Literal assignments with conversions that lose precision produce
// diagnostics under `-Wconversion`.

// Lose precision on assignment.
h = 3.1415926535897932384626433h; // No diagnostic expected because this isn't a conversion.

// Lose precision on assignment converting float to half.
h = 3.1415926535897932384626433f; // No diagnostic expected because half and float are the same size.

// Lose precision on assignment converting float to half.
h = 3.1415926535897932384626433f * 2.0f; // No diagnostic expected because half and float are the same size.

// Lose precision on assignment converting double to half.
h = 3.1415926535897932384626433l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}}

// Lose precision on assignment converting double to half.
h = 3.1415926535897932384626433l * 2.0l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}}

// Literal assinments of values out of the representable range produce
// warnings.

h = 66000.h; // No diagnostic expected because half is 32-bit.
h = -66000.h; // No diagnostic expected because half is 32-bit.

// The `h` suffix is invalid on integer literals.
h = 66000h; // expected-error {{invalid suffix 'h' on integer constant}}
}

template <typename T, typename U>
struct is_same {
static const bool value = false;
};

template <typename T>
struct is_same<T, T> {
static const bool value = true;
};

// The no-suffix behavior is currently wrong. The behavior in DXC is complicated
// and undocumented. We have a language change planned to address this, and an
// issue tracking: https://github.com/llvm/llvm-project/issues/85714.
_Static_assert(is_same<double, __decltype(1.0)>::value, "1.0f literal is double (should be float)");

_Static_assert(is_same<half, __decltype(1.0h)>::value, "1.0h literal is half");
_Static_assert(is_same<float, __decltype(1.0f)>::value, "1.0f literal is float");
_Static_assert(is_same<double, __decltype(1.0l)>::value, "1.0l literal is double");
12 changes: 12 additions & 0 deletions clang/test/SemaTemplate/deduction-guide.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,15 @@ G g = {1};
// CHECK: FunctionTemplateDecl
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for G> 'auto (T) -> G<T>' aggregate
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for G> 'auto (int) -> G<int>' implicit_instantiation aggregate

template<typename X>
using AG = G<X>;
AG ag = {1};
// Verify that the aggregate deduction guide for alias templates is built.
// CHECK-LABEL: Dumping <deduction guide for AG>
// CHECK: FunctionTemplateDecl
// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (type-parameter-0-0) -> G<type-parameter-0-0>'
// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G<int>' implicit_instantiation
// CHECK: |-TemplateArgument type 'int'
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'
2 changes: 1 addition & 1 deletion clang/www/c_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ <h2 id="c99">C99 implementation status</h2>
<tr>
<td>extended identifiers</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n717.htm">N717</a></td>
<td class="unknown" align="center">Unknown</td>
<td class="full" align="center">Clang 17</td>
</tr>
<tr>
<td>hexadecimal floating-point constants</td>
Expand Down
10 changes: 10 additions & 0 deletions flang/docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ Clang-like device linking pipeline.

The same set of CMake variables works for Flang in-tree build.

### Build options

One may provide optional CMake variables to customize the build. Available options:

* `-DFLANG_RUNTIME_F128_MATH_LIB=libquadmath`: enables build of
`FortranFloat128Math` library that provides `REAL(16)` math APIs
for intrinsics such as `SIN`, `COS`, etc. GCC `libquadmath`'s header file
`quadmath.h` must be available to the build compiler.
[More details](Real16MathSupport.md).

## Supported C++ compilers

Flang is written in C++17.
Expand Down
38 changes: 38 additions & 0 deletions flang/docs/Real16MathSupport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!--===- docs/Real16MathSupport.md
Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
See https://llvm.org/LICENSE.txt for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

# Flang support for REAL(16) math intrinsics

To support most `REAL(16)` (i.e. 128-bit float) math intrinsics Flang relies
on third-party libraries providing the implementation.

`-DFLANG_RUNTIME_F128_MATH_LIB=libquadmath` CMake option can be used
to build `FortranFloat128Math` library that has unresolved references
to GCC `libquadmath` library. A Flang driver built with this option
will automatically link `FortranFloat128Math` and `libquadmath` libraries
to any Fortran program. This implies that `libquadmath` library
has to be available in the standard library paths, so that linker
can find it. The `libquadmath` library installation into Flang project
distribution is not automatic in CMake currently.

Testing shows that `libquadmath` versions before GCC-9.3.0 have
accuracy issues, so it is recommended to distribute the Flang
package with later versions of `libquadmath`.

Care must be taken by the distributors of a Flang package built
with `REAL(16)` support via `libquadmath` because of its licensing
under the GNU Library General Public License. Moreover, static linking
of `libquadmath` to the Flang users' programs may imply some
restrictions/requirements. This document is not intended to give
any legal advice on distributing such a Flang compiler.

Flang compiler targeting systems with `LDBL_MANT_DIG == 113`
may provide `REAL(16)` math support without a `libquadmath`
dependency, using standard `libc` APIs for the `long double`
data type. It is not recommended to use the above CMake option
for building Flang compilers for such targets.
1 change: 1 addition & 0 deletions flang/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ on how to get in touch with us and to learn more about the current status.
Semantics
f2018-grammar.md
fstack-arrays
Real16MathSupport
```

# Indices and tables
Expand Down
6 changes: 5 additions & 1 deletion libc/config/gpu/api.td
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
SimpleMacroDef<"_IOLBF", "1">,
SimpleMacroDef<"_IONBF", "2">,
];
let Types = ["size_t", "FILE"];
let Types = [
"FILE",
"off_t",
"size_t",
];
}

def IntTypesAPI : PublicAPI<"inttypes.h"> {
Expand Down
12 changes: 10 additions & 2 deletions libc/config/linux/api.td
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ def CTypeAPI : PublicAPI<"ctype.h"> {
}

def FCntlAPI : PublicAPI<"fcntl.h"> {
let Types = ["mode_t"];
let Types = [
"mode_t",
"off_t",
];
}

def IntTypesAPI : PublicAPI<"inttypes.h"> {
Expand Down Expand Up @@ -77,7 +80,12 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
SimpleMacroDef<"_IOLBF", "1">,
SimpleMacroDef<"_IONBF", "2">,
];
let Types = ["size_t", "FILE", "cookie_io_functions_t"];
let Types = [
"FILE",
"cookie_io_functions_t",
"off_t",
"size_t",
];
}

def StdlibAPI : PublicAPI<"stdlib.h"> {
Expand Down
10 changes: 6 additions & 4 deletions libc/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ add_gen_header(
DEF_FILE fcntl.h.def
GEN_HDR fcntl.h
DEPENDS
.llvm_libc_common_h
.llvm-libc-macros.fcntl_macros
.llvm-libc-types.mode_t
.llvm-libc-types.off_t
.llvm_libc_common_h
)

add_gen_header(
Expand Down Expand Up @@ -264,13 +265,14 @@ add_gen_header(
DEF_FILE stdio.h.def
GEN_HDR stdio.h
DEPENDS
.llvm_libc_common_h
.llvm-libc-macros.file_seek_macros
.llvm-libc-macros.stdio_macros
.llvm-libc-types.size_t
.llvm-libc-types.ssize_t
.llvm-libc-types.FILE
.llvm-libc-types.cookie_io_functions_t
.llvm-libc-types.off_t
.llvm-libc-types.size_t
.llvm-libc-types.ssize_t
.llvm_libc_common_h
)

add_gen_header(
Expand Down
7 changes: 5 additions & 2 deletions libc/spec/posix.td
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,10 @@ def POSIX : StandardSpec<"POSIX"> {
HeaderSpec FCntl = HeaderSpec<
"fcntl.h",
[], // Macros
[ModeTType],
[
ModeTType,
OffTType,
],
[], // Enumerations
[
FunctionSpec<
Expand Down Expand Up @@ -1180,7 +1183,7 @@ def POSIX : StandardSpec<"POSIX"> {
HeaderSpec StdIO = HeaderSpec<
"stdio.h",
[], // Macros
[], // Types
[OffTType], // Types
[], // Enumerations
[
FunctionSpec<
Expand Down
1 change: 0 additions & 1 deletion libc/src/stdio/fseeko.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#define LLVM_LIBC_SRC_STDIO_FSEEKO_H

#include <stdio.h>
#include <unistd.h>

namespace LIBC_NAMESPACE {

Expand Down
1 change: 0 additions & 1 deletion libc/src/stdio/ftello.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#define LLVM_LIBC_SRC_STDIO_FTELLO_H

#include <stdio.h>
#include <unistd.h>

namespace LIBC_NAMESPACE {

Expand Down
4 changes: 4 additions & 0 deletions libcxx/docs/ReleaseNotes/19.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Implemented Papers
- P2819R2 - Add ``tuple`` protocol to ``complex``
- P2495R3 - Interfacing ``stringstream``\s with ``string_view``
- P2867R2 - Remove Deprecated ``strstream``\s From C++26
- P2872R3 - Remove ``wstring_convert`` From C++26
- P2302R4 - ``std::ranges::contains``
- P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``

Expand All @@ -57,6 +58,9 @@ Improvements and New Features

- The ``_LIBCPP_ENABLE_CXX26_REMOVED_STRSTREAM`` macro has been added to make the declarations in ``<strstream>`` available.

- The ``_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT`` macro has been added to make the declarations in ``<locale>``
available.

Deprecations and Removals
-------------------------

Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cPapers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"`P2875R4 <https://wg21.link/P2875R4>`__","LWG","Undeprecate ``polymorphic_allocator::destroy`` for C++26","Tokyo March 2024","|Complete|","15.0",""
"`P2867R2 <https://wg21.link/P2867R2>`__","LWG","Remove Deprecated ``strstreams`` From C++26","Tokyo March 2024","|Complete|","19.0",""
"`P2869R4 <https://wg21.link/P2869R4>`__","LWG","Remove Deprecated ``shared_ptr`` Atomic Access APIs from C++26","Tokyo March 2024","","",""
"`P2872R3 <https://wg21.link/P2872R3>`__","LWG","Remove ``wstring_convert`` From C++26","Tokyo March 2024","","",""
"`P2872R3 <https://wg21.link/P2872R3>`__","LWG","Remove ``wstring_convert`` From C++26","Tokyo March 2024","|Complete|","19.0",""
"`P3107R5 <https://wg21.link/P3107R5>`__","LWG","Permit an efficient implementation of ``std::print``","Tokyo March 2024","","","|format| |DR|"
"`P3142R0 <https://wg21.link/P3142R0>`__","LWG","Printing Blank Lines with ``println``","Tokyo March 2024","","","|format|"
"`P2845R8 <https://wg21.link/P2845R8>`__","LWG","Formatting of ``std::filesystem::path``","Tokyo March 2024","","","|format|"
Expand Down
8 changes: 6 additions & 2 deletions libcxx/docs/UsingLibcxx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ C++17 Specific Configuration Macros

C++20 Specific Configuration Macros
-----------------------------------
**_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE**
**_LIBCPP_ENABLE_CXX20_REMOVED_SHARED_PTR_UNIQUE**:
This macro is used to re-enable the function
``std::shared_ptr<...>::unique()``.

Expand Down Expand Up @@ -267,7 +267,7 @@ C++26 Specific Configuration Macros
**_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT**:
This macro is used to re-enable all named declarations in ``<codecvt>``.

**_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE**
**_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE**:
This macro is used to re-enable the function
``std::basic_string<...>::reserve()``.

Expand All @@ -277,6 +277,10 @@ C++26 Specific Configuration Macros
**_LIBCPP_ENABLE_CXX26_REMOVED_STRSTREAM**:
This macro is used to re-enable all named declarations in ``<strstream>``.

**_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT**:
This macro is used to re-enable the ``wstring_convert`` and ``wbuffer_convert``
in ``<locale>``.

Libc++ Extensions
=================

Expand Down
8 changes: 6 additions & 2 deletions libcxx/include/locale
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ template <class charT> charT tolower(charT c, const locale& loc);
template<class Codecvt, class Elem = wchar_t,
class Wide_alloc = allocator<Elem>,
class Byte_alloc = allocator<char>>
class wstring_convert
class wstring_convert // Removed in C++26
{
public:
typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string;
Expand Down Expand Up @@ -119,7 +119,7 @@ public:
};
template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>>
class wbuffer_convert
class wbuffer_convert // Removed in C++26
: public basic_streambuf<Elem, Tr>
{
public:
Expand Down Expand Up @@ -3107,6 +3107,8 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>;
#endif

#if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)

template <class _Codecvt,
class _Elem = wchar_t,
class _WideAlloc = allocator<_Elem>,
Expand Down Expand Up @@ -3712,6 +3714,8 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>* wbuffer_convert<_Codecvt, _Elem, _Tr>::__

_LIBCPP_SUPPRESS_DEPRECATED_POP

#endif // _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS
Expand Down
5 changes: 5 additions & 0 deletions libcxx/modules/std/locale.inc
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,15 @@ export namespace std {
using std::messages_base;
using std::messages_byname;

# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)

// [depr.conversions.buffer]
using std::wbuffer_convert;

// [depr.conversions.string]
using std::wstring_convert;

# endif // _LIBCPP_STD_VER < 26 || defined(_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT)

#endif // _LIBCPP_HAS_NO_LOCALIZATION
} // namespace std
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// UNSUPPORTED: no-wide-characters

// TODO: This should not be necessary
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

#include <fstream>
#include <cassert>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// UNSUPPORTED: no-wide-characters

// TODO: This should not be necessary
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

#include <fstream>
#include <cassert>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// UNSUPPORTED: no-wide-characters

// TODO: This should not be necessary
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

#include <fstream>
#include <cassert>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// UNSUPPORTED: no-wide-characters

// TODO: This should not be necessary
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS:-D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

#include <fstream>
#include <cassert>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

// UNSUPPORTED: c++03

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// <locale>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wbuffer_convert<Codecvt, Elem, Tr>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// UNSUPPORTED: c++03, c++11, c++14, c++26
// UNSUPPORTED: no-wide-characters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

// <locale>

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_CODECVT -D_LIBCPP_ENABLE_CXX26_REMOVED_WSTRING_CONVERT

// template<class Codecvt, class Elem = wchar_t,
// class Wide_alloc = allocator<Elem>,
Expand Down
86 changes: 86 additions & 0 deletions lld/test/ELF/aarch64-reloc-implicit-addend.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## Test certain REL relocation types generated by legacy armasm.
# RUN: yaml2obj %s -o %t.o
# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s

# CHECK-COUNT-17: internal linker error: cannot read addend

---
!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_AARCH64
Sections:
- Name: .abs
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Content: fffffefffffffdfffffffffffffffcffffffffffffff
- Name: .rel.abs
Type: SHT_REL
Link: .symtab
Info: .abs
Relocations:
- {Offset: 0, Symbol: abs, Type: R_AARCH64_ABS16}
- {Offset: 2, Symbol: abs, Type: R_AARCH64_ABS32}
- {Offset: 6, Symbol: abs, Type: R_AARCH64_ABS64}
- {Offset: 14, Symbol: abs, Type: R_AARCH64_ADD_ABS_LO12_NC}

- Name: .uabs
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
AddressAlign: 4
Content: 00ffffff00ffffff00ffffff00ffffff00ffffff00ffffff
- Name: .rel.uabs
Type: SHT_REL
Link: .symtab
Info: .uabs
Relocations:
- {Offset: 0, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G0}
- {Offset: 4, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G0_NC}
- {Offset: 8, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G1}
- {Offset: 12, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G1_NC}
- {Offset: 16, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G2}
- {Offset: 20, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G2_NC}

- Name: .prel
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
AddressAlign: 4
Content: 00ffffff00ffffff00ffffff00ffffff00ffffff00ffffff
- Name: .rel.prel
Type: SHT_REL
Link: .symtab
Info: .prel
Relocations:
- {Offset: 0, Symbol: .prel, Type: R_AARCH64_PREL64}
- {Offset: 4, Symbol: .prel, Type: R_AARCH64_PREL32}
- {Offset: 8, Symbol: .prel, Type: R_AARCH64_PREL16}
- {Offset: 12, Symbol: .prel, Type: R_AARCH64_LD_PREL_LO19}
- {Offset: 16, Symbol: .prel, Type: R_AARCH64_ADR_PREL_PG_HI21}
- {Offset: 20, Symbol: .prel, Type: R_AARCH64_ADR_PREL_PG_HI21_NC}

- Name: .branch
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
AddressAlign: 4
Content: f0fffffff0fffffff0fffffff0ffffff
- Name: .rel.branch
Type: SHT_REL
Link: .symtab
Info: .branch
Relocations:
- {Offset: 0, Symbol: .branch, Type: R_AARCH64_TSTBR14}
- {Offset: 4, Symbol: .branch, Type: R_AARCH64_CONDBR19}
- {Offset: 8, Symbol: .branch, Type: R_AARCH64_CALL26}
- {Offset: 12, Symbol: .branch, Type: R_AARCH64_JUMP26}

Symbols:
- Name: .branch
Section: .branch
- Name: .prel
Section: .prel
- Name: abs
Index: SHN_ABS
Value: 42
Binding: STB_GLOBAL
100 changes: 50 additions & 50 deletions lld/test/ELF/pack-dyn-relocs.s
Original file line number Diff line number Diff line change
Expand Up @@ -198,34 +198,34 @@
// RUN: llvm-readobj -r %t2.a64 | FileCheck --check-prefix=UNPACKED64 %s

// UNPACKED64: Section ({{.+}}) .rela.dyn {
// UNPACKED64-NEXT: 0x30690 R_AARCH64_RELATIVE - 0x0
// UNPACKED64-NEXT: 0x30698 R_AARCH64_RELATIVE - 0x1
// UNPACKED64-NEXT: 0x30690 R_AARCH64_RELATIVE - 0x30690
// UNPACKED64-NEXT: 0x30698 R_AARCH64_RELATIVE - 0x30691
// UNPACKED64-NEXT: 0x306A0 R_AARCH64_RELATIVE - 0x2
// UNPACKED64-NEXT: 0x306A8 R_AARCH64_RELATIVE - 0xFFFFFFFFFFFFFFFF
// UNPACKED64-NEXT: 0x306B0 R_AARCH64_RELATIVE - 0x80000000
// UNPACKED64-NEXT: 0x306B8 R_AARCH64_RELATIVE - 0x6
// UNPACKED64-NEXT: 0x306C0 R_AARCH64_RELATIVE - 0x7
// UNPACKED64-NEXT: 0x306C8 R_AARCH64_RELATIVE - 0x8
// UNPACKED64-NEXT: 0x306C8 R_AARCH64_RELATIVE - 0x30698

// UNPACKED64-NEXT: 0x306D8 R_AARCH64_RELATIVE - 0x1
// UNPACKED64-NEXT: 0x306D8 R_AARCH64_RELATIVE - 0x30691
// UNPACKED64-NEXT: 0x306E0 R_AARCH64_RELATIVE - 0x2
// UNPACKED64-NEXT: 0x306E8 R_AARCH64_RELATIVE - 0x3
// UNPACKED64-NEXT: 0x306F0 R_AARCH64_RELATIVE - 0x4
// UNPACKED64-NEXT: 0x306F8 R_AARCH64_RELATIVE - 0x5
// UNPACKED64-NEXT: 0x30700 R_AARCH64_RELATIVE - 0x6
// UNPACKED64-NEXT: 0x30708 R_AARCH64_RELATIVE - 0x7
// UNPACKED64-NEXT: 0x30708 R_AARCH64_RELATIVE - 0x30697

// UNPACKED64-NEXT: 0x30720 R_AARCH64_RELATIVE - 0x1
// UNPACKED64-NEXT: 0x30720 R_AARCH64_RELATIVE - 0x30691
// UNPACKED64-NEXT: 0x30728 R_AARCH64_RELATIVE - 0x2
// UNPACKED64-NEXT: 0x30730 R_AARCH64_RELATIVE - 0x3
// UNPACKED64-NEXT: 0x30738 R_AARCH64_RELATIVE - 0x4
// UNPACKED64-NEXT: 0x30740 R_AARCH64_RELATIVE - 0x5
// UNPACKED64-NEXT: 0x30748 R_AARCH64_RELATIVE - 0x6
// UNPACKED64-NEXT: 0x30750 R_AARCH64_RELATIVE - 0x7
// UNPACKED64-NEXT: 0x30758 R_AARCH64_RELATIVE - 0x8
// UNPACKED64-NEXT: 0x30760 R_AARCH64_RELATIVE - 0x9
// UNPACKED64-NEXT: 0x30760 R_AARCH64_RELATIVE - 0x30699

// UNPACKED64-NEXT: 0x30769 R_AARCH64_RELATIVE - 0xA
// UNPACKED64-NEXT: 0x30769 R_AARCH64_RELATIVE - 0x3069A

// UNPACKED64-NEXT: 0x306D0 R_AARCH64_ABS64 bar2 0x1
// UNPACKED64-NEXT: 0x30718 R_AARCH64_ABS64 bar2 0x0
Expand All @@ -247,47 +247,47 @@

// ANDROID64: (DEBUG) 0x0
// ANDROID64-NEXT: (ANDROID_RELA) 0x[[#ANDROID]]
// ANDROID64-NEXT: (ANDROID_RELASZ) 122 (bytes)
// ANDROID64-NEXT: (ANDROID_RELASZ) 136 (bytes)
// ANDROID64-NEXT: (RELAENT) 24 (bytes)

// ANDROID64-HEADERS: 0x0000000060000011 ANDROID_RELA [[ADDR]]
// ANDROID64-HEADERS: 0x0000000060000012 ANDROID_RELASZ [[SIZE]]

// ANDROID64: Relocation section '.rela.dyn' at offset {{.*}} contains 33 entries:
// ANDROID64-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
// ANDROID64-NEXT: 00000000000303e8 0000000000000403 R_AARCH64_RELATIVE 0
// ANDROID64-NEXT: 00000000000303f0 0000000000000403 R_AARCH64_RELATIVE 1
// ANDROID64-NEXT: 00000000000303f8 0000000000000403 R_AARCH64_RELATIVE 2
// ANDROID64-NEXT: 0000000000030400 0000000000000403 R_AARCH64_RELATIVE ffffffffffffffff
// ANDROID64-NEXT: 0000000000030408 0000000000000403 R_AARCH64_RELATIVE 80000000
// ANDROID64-NEXT: 0000000000030410 0000000000000403 R_AARCH64_RELATIVE 6
// ANDROID64-NEXT: 0000000000030418 0000000000000403 R_AARCH64_RELATIVE 7
// ANDROID64-NEXT: 0000000000030420 0000000000000403 R_AARCH64_RELATIVE 8
// ANDROID64-NEXT: 0000000000030478 0000000000000403 R_AARCH64_RELATIVE 1
// ANDROID64-NEXT: 0000000000030480 0000000000000403 R_AARCH64_RELATIVE 2
// ANDROID64-NEXT: 0000000000030488 0000000000000403 R_AARCH64_RELATIVE 3
// ANDROID64-NEXT: 0000000000030490 0000000000000403 R_AARCH64_RELATIVE 4
// ANDROID64-NEXT: 0000000000030498 0000000000000403 R_AARCH64_RELATIVE 5
// ANDROID64-NEXT: 00000000000304a0 0000000000000403 R_AARCH64_RELATIVE 6
// ANDROID64-NEXT: 00000000000304a8 0000000000000403 R_AARCH64_RELATIVE 7
// ANDROID64-NEXT: 00000000000304b0 0000000000000403 R_AARCH64_RELATIVE 8
// ANDROID64-NEXT: 00000000000304b8 0000000000000403 R_AARCH64_RELATIVE 9
// ANDROID64-NEXT: 0000000000030430 0000000000000403 R_AARCH64_RELATIVE 1
// ANDROID64-NEXT: 0000000000030438 0000000000000403 R_AARCH64_RELATIVE 2
// ANDROID64-NEXT: 0000000000030440 0000000000000403 R_AARCH64_RELATIVE 3
// ANDROID64-NEXT: 0000000000030448 0000000000000403 R_AARCH64_RELATIVE 4
// ANDROID64-NEXT: 0000000000030450 0000000000000403 R_AARCH64_RELATIVE 5
// ANDROID64-NEXT: 0000000000030458 0000000000000403 R_AARCH64_RELATIVE 6
// ANDROID64-NEXT: 0000000000030460 0000000000000403 R_AARCH64_RELATIVE 7
// ANDROID64-NEXT: 00000000000304c1 0000000000000403 R_AARCH64_RELATIVE a
// ANDROID64-NEXT: 0000000000030470 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// ANDROID64-NEXT: 00000000000304c9 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// ANDROID64-NEXT: 00000000000303f0 0000000000000403 R_AARCH64_RELATIVE 303f0
// ANDROID64-NEXT: 00000000000303f8 0000000000000403 R_AARCH64_RELATIVE 303f1
// ANDROID64-NEXT: 0000000000030400 0000000000000403 R_AARCH64_RELATIVE 2
// ANDROID64-NEXT: 0000000000030408 0000000000000403 R_AARCH64_RELATIVE ffffffffffffffff
// ANDROID64-NEXT: 0000000000030410 0000000000000403 R_AARCH64_RELATIVE 80000000
// ANDROID64-NEXT: 0000000000030418 0000000000000403 R_AARCH64_RELATIVE 6
// ANDROID64-NEXT: 0000000000030420 0000000000000403 R_AARCH64_RELATIVE 7
// ANDROID64-NEXT: 0000000000030428 0000000000000403 R_AARCH64_RELATIVE 303f8
// ANDROID64-NEXT: 0000000000030480 0000000000000403 R_AARCH64_RELATIVE 303f1
// ANDROID64-NEXT: 0000000000030488 0000000000000403 R_AARCH64_RELATIVE 2
// ANDROID64-NEXT: 0000000000030490 0000000000000403 R_AARCH64_RELATIVE 3
// ANDROID64-NEXT: 0000000000030498 0000000000000403 R_AARCH64_RELATIVE 4
// ANDROID64-NEXT: 00000000000304a0 0000000000000403 R_AARCH64_RELATIVE 5
// ANDROID64-NEXT: 00000000000304a8 0000000000000403 R_AARCH64_RELATIVE 6
// ANDROID64-NEXT: 00000000000304b0 0000000000000403 R_AARCH64_RELATIVE 7
// ANDROID64-NEXT: 00000000000304b8 0000000000000403 R_AARCH64_RELATIVE 8
// ANDROID64-NEXT: 00000000000304c0 0000000000000403 R_AARCH64_RELATIVE 303f9
// ANDROID64-NEXT: 0000000000030438 0000000000000403 R_AARCH64_RELATIVE 303f1
// ANDROID64-NEXT: 0000000000030440 0000000000000403 R_AARCH64_RELATIVE 2
// ANDROID64-NEXT: 0000000000030448 0000000000000403 R_AARCH64_RELATIVE 3
// ANDROID64-NEXT: 0000000000030450 0000000000000403 R_AARCH64_RELATIVE 4
// ANDROID64-NEXT: 0000000000030458 0000000000000403 R_AARCH64_RELATIVE 5
// ANDROID64-NEXT: 0000000000030460 0000000000000403 R_AARCH64_RELATIVE 6
// ANDROID64-NEXT: 0000000000030468 0000000000000403 R_AARCH64_RELATIVE 303f7
// ANDROID64-NEXT: 00000000000304c9 0000000000000403 R_AARCH64_RELATIVE 303fa
// ANDROID64-NEXT: 0000000000030478 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// ANDROID64-NEXT: 00000000000304d1 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// ANDROID64-NEXT: 00000000000304e9 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// ANDROID64-NEXT: 0000000000030428 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 1
// ANDROID64-NEXT: 0000000000030468 0000000200000101 R_AARCH64_ABS64 0000000000000000 zed2 + 0
// ANDROID64-NEXT: 00000000000304d9 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 1
// ANDROID64-NEXT: 00000000000304d9 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// ANDROID64-NEXT: 00000000000304f1 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// ANDROID64-NEXT: 0000000000030430 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 1
// ANDROID64-NEXT: 0000000000030470 0000000200000101 R_AARCH64_ABS64 0000000000000000 zed2 + 0
// ANDROID64-NEXT: 00000000000304e1 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 1
// ANDROID64-NEXT: 00000000000304e9 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 1
// ANDROID64-EMPTY:

// RUN: ld.lld -pie --pack-dyn-relocs=relr %t.a64.o %t.a64.so -o %t4.a64
Expand Down Expand Up @@ -317,7 +317,7 @@
/// Any relative relocations with odd offset stay in SHT_RELA.
// RELR64: Relocation section '.rela.dyn' at offset {{.*}} contains 9 entries:
// RELR64-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
// RELR64-NEXT: 0000000000030569 0000000000000403 R_AARCH64_RELATIVE a
// RELR64-NEXT: 0000000000030569 0000000000000403 R_AARCH64_RELATIVE 3049a
// RELR64-NEXT: 00000000000304d0 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 1
// RELR64-NEXT: 0000000000030518 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
// RELR64-NEXT: 0000000000030571 0000000100000101 R_AARCH64_ABS64 0000000000000000 bar2 + 0
Expand Down Expand Up @@ -355,43 +355,43 @@
// RELR64-NEXT: 0000000000030560 0000000000000403 R_AARCH64_RELATIVE
// RELR64-EMPTY:
// RELR64-NEXT: Hex dump of section '.data':
// RELR64-NEXT: 0x00030490 00000000 00000000 01000000 00000000 .
// RELR64-NEXT: 0x00030490 90040300 00000000 91040300 00000000 .
// RELR64-NEXT: 0x000304a0 02000000 00000000 ffffffff ffffffff .
// RELR64-NEXT: 0x000304b0 00000080 00000000 06000000 00000000 .

.data
.balign 2
.dc.a __ehdr_start
.dc.a __ehdr_start + 1
.dc.a .data
.dc.a .data + 1
.dc.a __ehdr_start + 2
.dc.a __ehdr_start - 1
.dc.a __ehdr_start + 0x80000000
.dc.a __ehdr_start + 6
.dc.a __ehdr_start + 7
.dc.a __ehdr_start + 8
.dc.a .data + 8
.dc.a bar2 + 1

.dc.a __ehdr_start + 1
.dc.a .data + 1
.dc.a __ehdr_start + 2
.dc.a __ehdr_start + 3
.dc.a __ehdr_start + 4
.dc.a __ehdr_start + 5
.dc.a __ehdr_start + 6
.dc.a __ehdr_start + 7
.dc.a .data + 7
.dc.a zed2
.dc.a bar2

.dc.a __ehdr_start + 1
.dc.a .data + 1
.dc.a __ehdr_start + 2
.dc.a __ehdr_start + 3
.dc.a __ehdr_start + 4
.dc.a __ehdr_start + 5
.dc.a __ehdr_start + 6
.dc.a __ehdr_start + 7
.dc.a __ehdr_start + 8
.dc.a __ehdr_start + 9
.dc.a .data + 9
.byte 00
.dc.a __ehdr_start + 10
.dc.a .data + 10
.dc.a bar2
.dc.a bar2
.dc.a bar2 + 1
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Support/Windows/Path.inc
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ std::string getMainExecutable(const char *argv0, void *MainExecAddr) {

SmallString<256> RealPath;
sys::fs::real_path(PathNameUTF8, RealPath);
return std::string(RealPath);
if (RealPath.size())
return std::string(RealPath);
return std::string(PathNameUTF8.data());
}

UniqueID file_status::getUniqueID() const {
Expand Down
42 changes: 8 additions & 34 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1716,40 +1716,14 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
setMaxAtomicSizeInBitsSupported(128);

if (Subtarget->isWindowsArm64EC()) {
// FIXME: are there other intrinsics we need to add here?
setLibcallName(RTLIB::MEMCPY, "#memcpy");
setLibcallName(RTLIB::MEMSET, "#memset");
setLibcallName(RTLIB::MEMMOVE, "#memmove");
setLibcallName(RTLIB::REM_F32, "#fmodf");
setLibcallName(RTLIB::REM_F64, "#fmod");
setLibcallName(RTLIB::FMA_F32, "#fmaf");
setLibcallName(RTLIB::FMA_F64, "#fma");
setLibcallName(RTLIB::SQRT_F32, "#sqrtf");
setLibcallName(RTLIB::SQRT_F64, "#sqrt");
setLibcallName(RTLIB::CBRT_F32, "#cbrtf");
setLibcallName(RTLIB::CBRT_F64, "#cbrt");
setLibcallName(RTLIB::LOG_F32, "#logf");
setLibcallName(RTLIB::LOG_F64, "#log");
setLibcallName(RTLIB::LOG2_F32, "#log2f");
setLibcallName(RTLIB::LOG2_F64, "#log2");
setLibcallName(RTLIB::LOG10_F32, "#log10f");
setLibcallName(RTLIB::LOG10_F64, "#log10");
setLibcallName(RTLIB::EXP_F32, "#expf");
setLibcallName(RTLIB::EXP_F64, "#exp");
setLibcallName(RTLIB::EXP2_F32, "#exp2f");
setLibcallName(RTLIB::EXP2_F64, "#exp2");
setLibcallName(RTLIB::EXP10_F32, "#exp10f");
setLibcallName(RTLIB::EXP10_F64, "#exp10");
setLibcallName(RTLIB::SIN_F32, "#sinf");
setLibcallName(RTLIB::SIN_F64, "#sin");
setLibcallName(RTLIB::COS_F32, "#cosf");
setLibcallName(RTLIB::COS_F64, "#cos");
setLibcallName(RTLIB::POW_F32, "#powf");
setLibcallName(RTLIB::POW_F64, "#pow");
setLibcallName(RTLIB::LDEXP_F32, "#ldexpf");
setLibcallName(RTLIB::LDEXP_F64, "#ldexp");
setLibcallName(RTLIB::FREXP_F32, "#frexpf");
setLibcallName(RTLIB::FREXP_F64, "#frexp");
// FIXME: are there intrinsics we need to exclude from this?
for (int i = 0; i < RTLIB::UNKNOWN_LIBCALL; ++i) {
auto code = static_cast<RTLIB::Libcall>(i);
auto libcallName = getLibcallName(code);
if ((libcallName != nullptr) && (libcallName[0] != '#')) {
setLibcallName(code, Saver.save(Twine("#") + libcallName).data());
}
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,9 @@ class AArch64TargetLowering : public TargetLowering {
/// make the right decision when generating code for different targets.
const AArch64Subtarget *Subtarget;

llvm::BumpPtrAllocator BumpAlloc;
llvm::StringSaver Saver{BumpAlloc};

bool isExtFreeImpl(const Instruction *Ext) const override;

void addTypeForNEON(MVT VT);
Expand Down
102 changes: 88 additions & 14 deletions llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7056,19 +7056,16 @@ bool BoUpSLP::areAllUsersVectorized(

static std::pair<InstructionCost, InstructionCost>
getVectorCallCosts(CallInst *CI, FixedVectorType *VecTy,
TargetTransformInfo *TTI, TargetLibraryInfo *TLI) {
TargetTransformInfo *TTI, TargetLibraryInfo *TLI,
ArrayRef<Type *> ArgTys) {
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);

// Calculate the cost of the scalar and vector calls.
SmallVector<Type *, 4> VecTys;
for (Use &Arg : CI->args())
VecTys.push_back(
FixedVectorType::get(Arg->getType(), VecTy->getNumElements()));
FastMathFlags FMF;
if (auto *FPCI = dyn_cast<FPMathOperator>(CI))
FMF = FPCI->getFastMathFlags();
SmallVector<const Value *> Arguments(CI->args());
IntrinsicCostAttributes CostAttrs(ID, VecTy, Arguments, VecTys, FMF,
IntrinsicCostAttributes CostAttrs(ID, VecTy, Arguments, ArgTys, FMF,
dyn_cast<IntrinsicInst>(CI));
auto IntrinsicCost =
TTI->getIntrinsicInstrCost(CostAttrs, TTI::TCK_RecipThroughput);
Expand All @@ -7081,8 +7078,8 @@ getVectorCallCosts(CallInst *CI, FixedVectorType *VecTy,
if (!CI->isNoBuiltin() && VecFunc) {
// Calculate the cost of the vector library call.
// If the corresponding vector call is cheaper, return its cost.
LibCost = TTI->getCallInstrCost(nullptr, VecTy, VecTys,
TTI::TCK_RecipThroughput);
LibCost =
TTI->getCallInstrCost(nullptr, VecTy, ArgTys, TTI::TCK_RecipThroughput);
}
return {IntrinsicCost, LibCost};
}
Expand Down Expand Up @@ -8508,6 +8505,30 @@ TTI::CastContextHint BoUpSLP::getCastContextHint(const TreeEntry &TE) const {
return TTI::CastContextHint::None;
}

/// Builds the arguments types vector for the given call instruction with the
/// given \p ID for the specified vector factor.
static SmallVector<Type *> buildIntrinsicArgTypes(const CallInst *CI,
const Intrinsic::ID ID,
const unsigned VF,
unsigned MinBW) {
SmallVector<Type *> ArgTys;
for (auto [Idx, Arg] : enumerate(CI->args())) {
if (ID != Intrinsic::not_intrinsic) {
if (isVectorIntrinsicWithScalarOpAtArg(ID, Idx)) {
ArgTys.push_back(Arg->getType());
continue;
}
if (MinBW > 0) {
ArgTys.push_back(FixedVectorType::get(
IntegerType::get(CI->getContext(), MinBW), VF));
continue;
}
}
ArgTys.push_back(FixedVectorType::get(Arg->getType(), VF));
}
return ArgTys;
}

InstructionCost
BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
SmallPtrSetImpl<Value *> &CheckedExtracts) {
Expand Down Expand Up @@ -9074,7 +9095,11 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
};
auto GetVectorCost = [=](InstructionCost CommonCost) {
auto *CI = cast<CallInst>(VL0);
auto VecCallCosts = getVectorCallCosts(CI, VecTy, TTI, TLI);
Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);
SmallVector<Type *> ArgTys =
buildIntrinsicArgTypes(CI, ID, VecTy->getNumElements(),
It != MinBWs.end() ? It->second.first : 0);
auto VecCallCosts = getVectorCallCosts(CI, VecTy, TTI, TLI, ArgTys);
return std::min(VecCallCosts.first, VecCallCosts.second) + CommonCost;
};
return GetCostDiff(GetScalarCost, GetVectorCost);
Expand Down Expand Up @@ -12546,7 +12571,10 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {

Intrinsic::ID ID = getVectorIntrinsicIDForCall(CI, TLI);

auto VecCallCosts = getVectorCallCosts(CI, VecTy, TTI, TLI);
SmallVector<Type *> ArgTys =
buildIntrinsicArgTypes(CI, ID, VecTy->getNumElements(),
It != MinBWs.end() ? It->second.first : 0);
auto VecCallCosts = getVectorCallCosts(CI, VecTy, TTI, TLI, ArgTys);
bool UseIntrinsic = ID != Intrinsic::not_intrinsic &&
VecCallCosts.first <= VecCallCosts.second;

Expand All @@ -12555,16 +12583,20 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
SmallVector<Type *, 2> TysForDecl;
// Add return type if intrinsic is overloaded on it.
if (UseIntrinsic && isVectorIntrinsicWithOverloadTypeAtArg(ID, -1))
TysForDecl.push_back(
FixedVectorType::get(CI->getType(), E->Scalars.size()));
TysForDecl.push_back(VecTy);
auto *CEI = cast<CallInst>(VL0);
for (unsigned I : seq<unsigned>(0, CI->arg_size())) {
ValueList OpVL;
// Some intrinsics have scalar arguments. This argument should not be
// vectorized.
if (UseIntrinsic && isVectorIntrinsicWithScalarOpAtArg(ID, I)) {
ScalarArg = CEI->getArgOperand(I);
OpVecs.push_back(CEI->getArgOperand(I));
// if decided to reduce bitwidth of abs intrinsic, it second argument
// must be set false (do not return poison, if value issigned min).
if (ID == Intrinsic::abs && It != MinBWs.end() &&
It->second.first < DL->getTypeSizeInBits(CEI->getType()))
ScalarArg = Builder.getFalse();
OpVecs.push_back(ScalarArg);
if (isVectorIntrinsicWithOverloadTypeAtArg(ID, I))
TysForDecl.push_back(ScalarArg->getType());
continue;
Expand All @@ -12577,10 +12609,13 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
}
ScalarArg = CEI->getArgOperand(I);
if (cast<VectorType>(OpVec->getType())->getElementType() !=
ScalarArg->getType()) {
ScalarArg->getType() &&
It == MinBWs.end()) {
auto *CastTy = FixedVectorType::get(ScalarArg->getType(),
VecTy->getNumElements());
OpVec = Builder.CreateIntCast(OpVec, CastTy, GetOperandSignedness(I));
} else if (It != MinBWs.end()) {
OpVec = Builder.CreateIntCast(OpVec, VecTy, GetOperandSignedness(I));
}
LLVM_DEBUG(dbgs() << "SLP: OpVec[" << I << "]: " << *OpVec << "\n");
OpVecs.push_back(OpVec);
Expand Down Expand Up @@ -14324,6 +14359,45 @@ bool BoUpSLP::collectValuesToDemote(
return TryProcessInstruction(I, *ITE, BitWidth, Ops);
}

case Instruction::Call: {
auto *IC = dyn_cast<IntrinsicInst>(I);
if (!IC)
break;
Intrinsic::ID ID = getVectorIntrinsicIDForCall(IC, TLI);
if (ID != Intrinsic::abs && ID != Intrinsic::smin &&
ID != Intrinsic::smax && ID != Intrinsic::umin && ID != Intrinsic::umax)
break;
SmallVector<Value *> Operands(1, I->getOperand(0));
End = 1;
if (ID != Intrinsic::abs) {
Operands.push_back(I->getOperand(1));
End = 2;
}
InstructionCost BestCost =
std::numeric_limits<InstructionCost::CostType>::max();
unsigned BestBitWidth = BitWidth;
unsigned VF = ITE->Scalars.size();
// Choose the best bitwidth based on cost estimations.
auto Checker = [&](unsigned BitWidth, unsigned) {
unsigned MinBW = PowerOf2Ceil(BitWidth);
SmallVector<Type *> ArgTys = buildIntrinsicArgTypes(IC, ID, VF, MinBW);
auto VecCallCosts = getVectorCallCosts(
IC,
FixedVectorType::get(IntegerType::get(IC->getContext(), MinBW), VF),
TTI, TLI, ArgTys);
InstructionCost Cost = std::min(VecCallCosts.first, VecCallCosts.second);
if (Cost < BestCost) {
BestCost = Cost;
BestBitWidth = BitWidth;
}
return false;
};
[[maybe_unused]] bool NeedToExit;
(void)AttemptCheckBitwidth(Checker, NeedToExit);
BitWidth = BestBitWidth;
return TryProcessInstruction(I, *ITE, BitWidth, Operands);
}

// Otherwise, conservatively give up.
default:
break;
Expand Down
191 changes: 191 additions & 0 deletions llvm/test/Analysis/CostModel/AArch64/shuffle-other.ll

Large diffs are not rendered by default.

20 changes: 15 additions & 5 deletions llvm/test/CodeGen/RISCV/compress-opt-branch.ll
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,14 @@ if.end:

; constant is big and do not fit in 12 bit (imm), fit in i32
; RV32IFDC-LABEL: <f_big_ledge_pos>:
; RV32IFDC-NOT: RESBROPT
; RV32IFDC: c.li [[REG:.*]], 0x1
; RV32IFDC: c.slli [[REG]], 0xb
; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
; --- no compress extension
; nothing to check.
; RV32IFD-LABEL: <f_big_ledge_pos>:
; RV32IFD: addi [[REG1:.*]], zero, 0x1
; RV32IFD: slli [[REG2:.*]], [[REG1]], 0xb
; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG2]], [[PLACE:.*]]
define i32 @f_big_ledge_pos(i32 %in0) minsize {
%cmp = icmp CMPCOND i32 %in0, 2048
br i1 %cmp, label %if.then, label %if.else
Expand All @@ -290,11 +295,16 @@ if.end:

; constant is big and do not fit in 12 bit (imm), fit in i32
; RV32IFDC-LABEL: <f_big_ledge_neg>:
; RV32IFDC-NOT: c.beqz
; RV32IFDC: c.lui [[REG1:.*]], 0xfffff
; RV32IFDC: addi [[REG2:.*]], [[REG1]], 0x7ff
; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
; --- no compress extension
; nothing to check.
; RV32IFD-LABEL: <f_big_ledge_neg>:
; RV32IFD: lui [[REG1:.*]], 0xfffff
; RV32IFD: addi [[REG2:.*]], [[REG1]], 0x7ff
; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG2]], [[PLACE:.*]]
define i32 @f_big_ledge_neg(i32 %in0) minsize {
%cmp = icmp CMPCOND i32 %in0, -2048
%cmp = icmp CMPCOND i32 %in0, -2049
br i1 %cmp, label %if.then, label %if.else
if.then:
%call = shl i32 %in0, 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ define void @test(ptr %0, i8 %1, i1 %cmp12.i) {
; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <8 x i8> [[TMP4]], <8 x i8> poison, <8 x i32> zeroinitializer
; CHECK-NEXT: br label [[PRE:%.*]]
; CHECK: pre:
; CHECK-NEXT: [[TMP6:%.*]] = zext <8 x i8> [[TMP5]] to <8 x i32>
; CHECK-NEXT: [[TMP7:%.*]] = call <8 x i32> @llvm.umax.v8i32(<8 x i32> [[TMP6]], <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>)
; CHECK-NEXT: [[TMP8:%.*]] = trunc <8 x i32> [[TMP7]] to <8 x i8>
; CHECK-NEXT: [[TMP8:%.*]] = call <8 x i8> @llvm.umax.v8i8(<8 x i8> [[TMP5]], <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
; CHECK-NEXT: [[TMP9:%.*]] = add <8 x i8> [[TMP8]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
; CHECK-NEXT: [[TMP10:%.*]] = select <8 x i1> [[TMP3]], <8 x i8> [[TMP9]], <8 x i8> [[TMP5]]
; CHECK-NEXT: store <8 x i8> [[TMP10]], ptr [[TMP0]], align 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ define void @test() {
; CHECK-LABEL: define void @test(
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> zeroinitializer, <2 x i32> zeroinitializer)
; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> zeroinitializer, <2 x i32> zeroinitializer, <2 x i32> [[TMP0]]
; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], zeroinitializer
; CHECK-NEXT: [[ADD:%.*]] = extractelement <2 x i32> [[TMP2]], i32 1
; CHECK-NEXT: [[TMP0:%.*]] = call <2 x i2> @llvm.smin.v2i2(<2 x i2> zeroinitializer, <2 x i2> zeroinitializer)
; CHECK-NEXT: [[TMP1:%.*]] = select <2 x i1> zeroinitializer, <2 x i2> zeroinitializer, <2 x i2> [[TMP0]]
; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i2> [[TMP1]], zeroinitializer
; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i2> [[TMP2]], i32 1
; CHECK-NEXT: [[ADD:%.*]] = zext i2 [[TMP3]] to i32
; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[ADD]], 0
; CHECK-NEXT: [[ADD45:%.*]] = extractelement <2 x i32> [[TMP2]], i32 0
; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i2> [[TMP2]], i32 0
; CHECK-NEXT: [[ADD45:%.*]] = zext i2 [[TMP5]] to i32
; CHECK-NEXT: [[ADD152:%.*]] = or i32 [[ADD45]], [[ADD]]
; CHECK-NEXT: [[IDXPROM153:%.*]] = sext i32 [[ADD152]] to i64
; CHECK-NEXT: [[ARRAYIDX154:%.*]] = getelementptr i8, ptr null, i64 [[IDXPROM153]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ define i32 @test(ptr noalias %in, ptr noalias %inn, ptr %out) {
; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <2 x i8> [[TMP3]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <2 x i8> [[TMP2]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: [[TMP7:%.*]] = shufflevector <4 x i8> [[TMP5]], <4 x i8> [[TMP6]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
; CHECK-NEXT: [[TMP8:%.*]] = sext <4 x i8> [[TMP7]] to <4 x i32>
; CHECK-NEXT: [[TMP8:%.*]] = sext <4 x i8> [[TMP7]] to <4 x i16>
; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <2 x i8> [[TMP1]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: [[TMP10:%.*]] = shufflevector <2 x i8> [[TMP4]], <2 x i8> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
; CHECK-NEXT: [[TMP11:%.*]] = shufflevector <4 x i8> [[TMP9]], <4 x i8> [[TMP10]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
; CHECK-NEXT: [[TMP12:%.*]] = sext <4 x i8> [[TMP11]] to <4 x i32>
; CHECK-NEXT: [[TMP13:%.*]] = sub <4 x i32> [[TMP12]], [[TMP8]]
; CHECK-NEXT: [[TMP14:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[TMP13]], i1 true)
; CHECK-NEXT: [[TMP15:%.*]] = trunc <4 x i32> [[TMP14]] to <4 x i16>
; CHECK-NEXT: [[TMP12:%.*]] = sext <4 x i8> [[TMP11]] to <4 x i16>
; CHECK-NEXT: [[TMP13:%.*]] = sub <4 x i16> [[TMP12]], [[TMP8]]
; CHECK-NEXT: [[TMP15:%.*]] = call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[TMP13]], i1 false)
; CHECK-NEXT: store <4 x i16> [[TMP15]], ptr [[OUT:%.*]], align 2
; CHECK-NEXT: ret i32 undef
;
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/clang/lib/AST/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ static_library("AST") {
"ODRDiagsEmitter.cpp",
"ODRHash.cpp",
"OSLog.cpp",
"OpenACCClause.cpp",
"OpenMPClause.cpp",
"ParentMap.cpp",
"ParentMapContext.cpp",
Expand Down
2 changes: 1 addition & 1 deletion llvm/utils/gn/secondary/libcxx/include/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ if (current_toolchain == default_toolchain) {
"__type_traits/datasizeof.h",
"__type_traits/decay.h",
"__type_traits/dependent_type.h",
"__type_traits/desugars_to.h",
"__type_traits/disjunction.h",
"__type_traits/enable_if.h",
"__type_traits/extent.h",
Expand Down Expand Up @@ -891,7 +892,6 @@ if (current_toolchain == default_toolchain) {
"__type_traits/nat.h",
"__type_traits/negation.h",
"__type_traits/noexcept_move_assign_container.h",
"__type_traits/operation_traits.h",
"__type_traits/promote.h",
"__type_traits/rank.h",
"__type_traits/remove_all_extents.h",
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ write_cmake_config("config") {
"HOST_LINK_VERSION=",
"LIBPFM_HAS_FIELD_CYCLES=",
"LLVM_TARGET_TRIPLE_ENV=",
"LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG=1",
"LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO=1",
"LLVM_WINDOWS_PREFER_FORWARD_SLASH=",
"PACKAGE_BUGREPORT=https://github.com/llvm/llvm-project/issues/",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
static_library("BinaryReader") {
output_name = "LLVMTextAPIBinaryReader"
deps = [
"//llvm/lib/DebugInfo/DWARF",
"//llvm/lib/Object",
"//llvm/lib/Support",
"//llvm/lib/TargetParser",
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ unittest("ADTTests") {
"ImmutableMapTest.cpp",
"ImmutableSetTest.cpp",
"IntEqClassesTest.cpp",
"Interleave.cpp",
"IntervalMapTest.cpp",
"IntervalTreeTest.cpp",
"IntrusiveRefCntPtrTest.cpp",
Expand Down