237 changes: 237 additions & 0 deletions clang/test/CXX/temp/temp.names/p3-23.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
// RUN: %clang_cc1 -std=c++23 -Wno-unused %s -verify

namespace FoundNothing {
template<typename T>
void f0(T &t) {
t.x<0;
t.x<0>; // expected-error {{expected expression}}
t.x<0>1;
}

template<typename T>
struct A {
void f1() {
this->x<0; // expected-error {{no member named 'x' in 'A<T>'}}
this->x<0>; // expected-error {{no member named 'x' in 'A<T>'}}
// expected-error@-1 {{expected expression}}
this->x<0>1; // expected-error {{no member named 'x' in 'A<T>'}}
}
};
} // namespace FoundNothing

namespace FoundSingleNonTemplate {
void f0();

struct A0;

template<typename T>
void g0(T &t) {
t.f0<0;
t.f0<0>; // expected-error {{expected expression}}
t.f0<0>1;

t.A0<0;
t.A0<0>; // expected-error {{expected expression}}
t.A0<0>1;
}

template<typename T>
struct B {
void f1();

struct A1; // expected-note 3{{member 'A1' declared here}}

void g1() {
this->f0<0; // expected-error {{no member named 'f0' in 'B<T>'}}
this->f0<0>; // expected-error {{no member named 'f0' in 'B<T>'}}
// expected-error@-1 {{expected expression}}
this->f0<0>1; // expected-error {{no member named 'f0' in 'B<T>'}}

this->A0<0; // expected-error {{no member named 'A0' in 'B<T>'}}
this->A0<0>; // expected-error {{no member named 'A0' in 'B<T>'}}
// expected-error@-1 {{expected expression}}
this->A0<0>1; // expected-error {{no member named 'A0' in 'B<T>'}}

this->f1<0; // expected-error {{reference to non-static member function must be called}}
this->f1<0>; // expected-error {{reference to non-static member function must be called}}
// expected-error@-1 {{expected expression}}
this->f1<0>1; // expected-error {{reference to non-static member function must be called}}

this->A1<0; // expected-error {{cannot refer to type member 'A1' in 'B<T>' with '->'}}
this->A1<0>; // expected-error {{cannot refer to type member 'A1' in 'B<T>' with '->'}}
// expected-error@-1 {{expected expression}}
this->A1<0>1; // expected-error {{cannot refer to type member 'A1' in 'B<T>' with '->'}}
}
};
} // namespace FoundSingleNonTemplate

namespace FoundSingleTemplate {
template<int I>
void f0();

template<int I>
struct A0;

template<typename T>
void g0(T &t) {
t.f0<0;
t.f0<0>; // expected-error {{expected expression}}
t.f0<0>1;

t.A0<0;
t.A0<0>; // expected-error {{expected expression}}
t.A0<0>1;
}

template<typename T>
struct B {
template<int I>
void f1(); // expected-note 2{{possible target for call}}

template<int I>
struct A1; // expected-note 2{{member 'A1' declared here}}

void g1() {
this->f0<0; // expected-error {{no member named 'f0' in 'B<T>'}}
this->f0<0>; // expected-error {{no member named 'f0' in 'B<T>'}}
this->f0<0>1; // expected-error {{no member named 'f0' in 'B<T>'}}
// expected-error@-1 {{expected ';' after expression}}

this->A0<0; // expected-error {{no member named 'A0' in 'B<T>'}}
this->A0<0>; // expected-error {{no member named 'A0' in 'B<T>'}}
this->A0<0>1; // expected-error {{no member named 'A0' in 'B<T>'}}
// expected-error@-1 {{expected ';' after expression}}


this->f1<0; // expected-error {{expected '>'}}
// expected-note@-1 {{to match this '<'}}
this->f1<0>; // expected-error {{reference to non-static member function must be called}}
this->f1<0>1; // expected-error {{reference to non-static member function must be called}}
// expected-error@-1 {{expected ';' after expression}}

this->A1<0; // expected-error {{expected '>'}}
// expected-note@-1 {{to match this '<'}}
this->A1<0>; // expected-error {{cannot refer to member 'A1' in 'B<T>' with '->'}}
this->A1<0>1; // expected-error {{cannot refer to member 'A1' in 'B<T>' with '->'}}
// expected-error@-1 {{expected ';' after expression}}
}
};
} // namespace FoundSingleTemplate

namespace FoundAmbiguousNonTemplate {
inline namespace N {
int f0;

struct A0;
} // namespace N

void f0();

struct A0;

template<typename T>
void g0(T &t) {
t.f0<0;
t.f0<0>; // expected-error {{expected expression}}
t.f0<0>1;

t.A0<0;
t.A0<0>; // expected-error {{expected expression}}
t.A0<0>1;
}

template<typename T>
struct B {
void f1();

struct A1; // expected-note 3{{member 'A1' declared here}}

void g1() {
this->f0<0; // expected-error {{no member named 'f0' in 'B<T>'}}
this->f0<0>; // expected-error {{no member named 'f0' in 'B<T>'}}
// expected-error@-1 {{expected expression}}
this->f0<0>1; // expected-error {{no member named 'f0' in 'B<T>'}}

this->A0<0; // expected-error {{no member named 'A0' in 'B<T>'}}
this->A0<0>; // expected-error {{no member named 'A0' in 'B<T>'}}
// expected-error@-1 {{expected expression}}
this->A0<0>1; // expected-error {{no member named 'A0' in 'B<T>'}}

this->f1<0; // expected-error {{reference to non-static member function must be called}}
this->f1<0>; // expected-error {{reference to non-static member function must be called}}
// expected-error@-1 {{expected expression}}
this->f1<0>1; // expected-error {{reference to non-static member function must be called}}

this->A1<0; // expected-error {{cannot refer to type member 'A1' in 'B<T>' with '->'}}
this->A1<0>; // expected-error {{cannot refer to type member 'A1' in 'B<T>' with '->'}}
// expected-error@-1 {{expected expression}}
this->A1<0>1; // expected-error {{cannot refer to type member 'A1' in 'B<T>' with '->'}}
}
};
} // namespace FoundAmbiguousNonTemplates

namespace FoundAmbiguousTemplate {
inline namespace N {
template<int I>
int f0; // expected-note 3{{candidate found by name lookup is 'FoundAmbiguousTemplate::N::f0'}}

template<int I>
struct A0; // expected-note 3{{candidate found by name lookup is 'FoundAmbiguousTemplate::N::A0'}}
} // namespace N

template<int I>
void f0(); // expected-note 3{{candidate found by name lookup is 'FoundAmbiguousTemplate::f0'}}

template<int I>
struct A0; // expected-note 3{{candidate found by name lookup is 'FoundAmbiguousTemplate::A0'}}

template<typename T>
void g0(T &t) {
t.f0<0;
t.f0<0>; // expected-error {{expected expression}}
t.f0<0>1;

t.A0<0;
t.A0<0>; // expected-error {{expected expression}}
t.A0<0>1;
}

template<typename T>
struct B {
template<int I>
void f1(); // expected-note 2{{possible target for call}}

template<int I>
struct A1; // expected-note 2{{member 'A1' declared here}}

void g1() {
this->f0<0; // expected-error {{no member named 'f0' in 'B<T>'}}
// expected-error@-1 {{reference to 'f0' is ambiguous}}
this->f0<0>; // expected-error {{no member named 'f0' in 'B<T>'}}
// expected-error@-1 {{reference to 'f0' is ambiguous}}
this->f0<0>1; // expected-error {{no member named 'f0' in 'B<T>'}}
// expected-error@-1 {{expected ';' after expression}}
// expected-error@-2 {{reference to 'f0' is ambiguous}}

this->A0<0; // expected-error {{no member named 'A0' in 'B<T>'}}
// expected-error@-1 {{reference to 'A0' is ambiguous}}
this->A0<0>; // expected-error {{no member named 'A0' in 'B<T>'}}
// expected-error@-1 {{reference to 'A0' is ambiguous}}
this->A0<0>1; // expected-error {{no member named 'A0' in 'B<T>'}}
// expected-error@-1 {{expected ';' after expression}}
// expected-error@-2 {{reference to 'A0' is ambiguous}}

this->f1<0; // expected-error {{expected '>'}}
// expected-note@-1 {{to match this '<'}}
this->f1<0>; // expected-error {{reference to non-static member function must be called}}
this->f1<0>1; // expected-error {{reference to non-static member function must be called}}
// expected-error@-1 {{expected ';' after expression}}

this->A1<0; // expected-error {{expected '>'}}
// expected-note@-1 {{to match this '<'}}
this->A1<0>; // expected-error {{cannot refer to member 'A1' in 'B<T>' with '->'}}
this->A1<0>1; // expected-error {{cannot refer to member 'A1' in 'B<T>' with '->'}}
// expected-error@-1 {{expected ';' after expression}}
}
};
} // namespace FoundAmbiguousTemplate
2 changes: 1 addition & 1 deletion clang/test/CXX/temp/temp.res/p3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ template<typename T> int A<T>::template C<int>::*f5() {} // expected-error {{has
template<typename T> template<typename U> struct A<T>::B {
friend A<T>::C<T> f6(); // ok, same as 'friend T f6();'

friend A<U>::C<T> f7(); // expected-error {{use 'template' keyword to treat 'C' as a dependent template name}} expected-warning {{missing 'typename'}}
friend A<U>::C<T> f7(); // expected-warning {{use 'template' keyword to treat 'C' as a dependent template name}} expected-warning {{missing 'typename'}}
friend A<U>::template C<T> f8(); // expected-warning {{missing 'typename'}}
};
130 changes: 130 additions & 0 deletions clang/test/CodeGenHLSL/loops/unroll.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s

/*** for ***/
void for_count()
{
// CHECK-LABEL: for_count
[unroll(8)]
for( int i = 0; i < 1000; ++i);
// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_DISTINCT:.*]]
}

void for_disable()
{
// CHECK-LABEL: for_disable
[loop]
for( int i = 0; i < 1000; ++i);
// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_DISABLE:.*]]
}

void for_enable()
{
// CHECK-LABEL: for_enable
[unroll]
for( int i = 0; i < 1000; ++i);
// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_ENABLE:.*]]
}

void for_nested_one_unroll_enable()
{
// CHECK-LABEL: for_nested_one_unroll_enable
int s = 0;
[unroll]
for( int i = 0; i < 1000; ++i) {
for( int j = 0; j < 10; ++j)
s += i + j;
}
// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_NESTED_ENABLE:.*]]
// CHECK-NOT: br label %{{.*}}, !llvm.loop ![[FOR_NESTED_1_ENABLE:.*]]
}

void for_nested_two_unroll_enable()
{
// CHECK-LABEL: for_nested_two_unroll_enable
int s = 0;
[unroll]
for( int i = 0; i < 1000; ++i) {
[unroll]
for( int j = 0; j < 10; ++j)
s += i + j;
}
// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_NESTED2_ENABLE:.*]]
// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_NESTED2_1_ENABLE:.*]]
}


/*** while ***/
void while_count()
{
// CHECK-LABEL: while_count
int i = 1000;
[unroll(4)]
while(i-->0);
// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_DISTINCT:.*]]
}

void while_disable()
{
// CHECK-LABEL: while_disable
int i = 1000;
[loop]
while(i-->0);
// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_DISABLE:.*]]
}

void while_enable()
{
// CHECK-LABEL: while_enable
int i = 1000;
[unroll]
while(i-->0);
// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_ENABLE:.*]]
}

/*** do ***/
void do_count()
{
// CHECK-LABEL: do_count
int i = 1000;
[unroll(16)]
do {} while(i--> 0);
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop ![[DO_DISTINCT:.*]]
}

void do_disable()
{
// CHECK-LABEL: do_disable
int i = 1000;
[loop]
do {} while(i--> 0);
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop ![[DO_DISABLE:.*]]
}

void do_enable()
{
// CHECK-LABEL: do_enable
int i = 1000;
[unroll]
do {} while(i--> 0);
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop ![[DO_ENABLE:.*]]
}


// CHECK: ![[FOR_DISTINCT]] = distinct !{![[FOR_DISTINCT]], ![[FOR_COUNT:.*]]}
// CHECK: ![[FOR_COUNT]] = !{!"llvm.loop.unroll.count", i32 8}
// CHECK: ![[FOR_DISABLE]] = distinct !{![[FOR_DISABLE]], ![[DISABLE:.*]]}
// CHECK: ![[DISABLE]] = !{!"llvm.loop.unroll.disable"}
// CHECK: ![[FOR_ENABLE]] = distinct !{![[FOR_ENABLE]], ![[ENABLE:.*]]}
// CHECK: ![[ENABLE]] = !{!"llvm.loop.unroll.enable"}
// CHECK: ![[FOR_NESTED_ENABLE]] = distinct !{![[FOR_NESTED_ENABLE]], ![[ENABLE]]}
// CHECK: ![[FOR_NESTED2_ENABLE]] = distinct !{![[FOR_NESTED2_ENABLE]], ![[ENABLE]]}
// CHECK: ![[FOR_NESTED2_1_ENABLE]] = distinct !{![[FOR_NESTED2_1_ENABLE]], ![[ENABLE]]}
// CHECK: ![[WHILE_DISTINCT]] = distinct !{![[WHILE_DISTINCT]], ![[WHILE_COUNT:.*]]}
// CHECK: ![[WHILE_COUNT]] = !{!"llvm.loop.unroll.count", i32 4}
// CHECK: ![[WHILE_DISABLE]] = distinct !{![[WHILE_DISABLE]], ![[DISABLE]]}
// CHECK: ![[WHILE_ENABLE]] = distinct !{![[WHILE_ENABLE]], ![[ENABLE]]}
// CHECK: ![[DO_DISTINCT]] = distinct !{![[DO_DISTINCT]], ![[DO_COUNT:.*]]}
// CHECK: ![[DO_COUNT]] = !{!"llvm.loop.unroll.count", i32 16}
// CHECK: ![[DO_DISABLE]] = distinct !{![[DO_DISABLE]], ![[DISABLE]]}
// CHECK: ![[DO_ENABLE]] = distinct !{![[DO_ENABLE]], ![[ENABLE]]}
4 changes: 2 additions & 2 deletions clang/test/FixIt/fixit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,12 @@ class F1 {

template<class T>
class F2 {
typename F1<T>:: /*template*/ Iterator<0> Mypos; // expected-error {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
typename F1<T>:: /*template*/ Iterator<0> Mypos; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
};

template <class T>
void f(){
typename F1<T>:: /*template*/ Iterator<0> Mypos; // expected-error {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
typename F1<T>:: /*template*/ Iterator<0> Mypos; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
}

// Tests for &/* fixits
Expand Down
22 changes: 22 additions & 0 deletions clang/test/Headers/__cpuidex_conflict.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Make sure that __cpuidex in cpuid.h doesn't conflict with the MS
// extensions built in by ensuring compilation succeeds:
// RUN: %clang_cc1 %s -ffreestanding -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -triple x86_64-pc-windows-msvc -emit-llvm -o -
// %clang_cc1 %s -ffreestanding -triple x86_64-w64-windows-gnu -fms-extensions -emit-llvm -o -
// RUN: %clang_cc1 %s -ffreestanding -fopenmp -fopenmp-is-target-device -aux-triple x86_64-unknown-linux-gnu

typedef __SIZE_TYPE__ size_t;

// We declare __cpuidex here as where the buitlin should be exposed (MSVC), the
// declaration is in <intrin.h>, but <intrin.h> is not available from all the
// targets that are being tested here.
void __cpuidex (int[4], int, int);

#include <cpuid.h>

int cpuid_info[4];

void test_cpuidex(unsigned level, unsigned count) {
__cpuidex(cpuid_info, level, count);
}

5 changes: 5 additions & 0 deletions clang/test/Headers/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@

// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm " xchgq %rbx,${1:q}\0A cpuid\0A xchgq %rbx,${1:q}", "={ax},=r,={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}})
// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm " xchgq %rbx,${1:q}\0A cpuid\0A xchgq %rbx,${1:q}", "={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}})
// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm " xchgq %rbx,${1:q}\0A cpuid\0A xchgq %rbx,${1:q}", "={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}})

// CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}})
// CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}})
// CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}})

unsigned eax0, ebx0, ecx0, edx0;
unsigned eax1, ebx1, ecx1, edx1;

int cpuid_info[4];

void test_cpuid(unsigned level, unsigned count) {
__cpuid(level, eax1, ebx1, ecx1, edx1);
__cpuid_count(level, count, eax0, ebx0, ecx0, edx0);
__cpuidex(cpuid_info, level, count);
}
2 changes: 1 addition & 1 deletion clang/test/Misc/warning-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The list of warnings below should NEVER grow. It should gradually shrink to 0.
CHECK: Warnings without flags (65):

CHECK-NEXT: ext_expected_semi_decl_list
CHECK-NEXT: ext_missing_dependent_template_keyword
CHECK-NEXT: ext_missing_whitespace_after_macro_name
CHECK-NEXT: ext_new_paren_array_nonconst
CHECK-NEXT: ext_plain_complex
Expand Down Expand Up @@ -61,7 +62,6 @@ CHECK-NEXT: warn_invalid_cpu_supports
CHECK-NEXT: warn_maynot_respond
CHECK-NEXT: warn_method_param_redefinition
CHECK-NEXT: warn_missing_case_for_condition
CHECK-NEXT: warn_missing_dependent_template_keyword
CHECK-NEXT: warn_missing_whitespace_after_macro_name
CHECK-NEXT: warn_mt_message
CHECK-NEXT: warn_no_constructor_for_refconst
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Parser/cxx2a-concepts-requires-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ bool r22 = requires { typename s::~s; };

template<typename T>
bool r23 = requires { typename identity<T>::temp<T>; };
// expected-error@-1 {{use 'template' keyword to treat 'temp' as a dependent template name}}
// expected-warning@-1 {{use 'template' keyword to treat 'temp' as a dependent template name}}

template<typename T>
bool r24 = requires {
Expand Down
6 changes: 3 additions & 3 deletions clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,22 @@ void f1() {
// `dependent` should be type-dependent because the noexcept-expression should be value-dependent
// (it is true if T is int*, false if T is Polymorphic<false, false>* for example)
dependent.f<void>(); // This should need to be `.template f` to parse as a template
// expected-error@-1 {{use 'template' keyword to treat 'f' as a dependent template name}}
// expected-warning@-1 {{use 'template' keyword to treat 'f' as a dependent template name}}
}
template<typename... T>
void f2() {
X<noexcept(typeid(*((static_cast<Polymorphic<false, false>*>(nullptr) && ... && T{}))))> dependent;
// X<true> when T...[0] is a type with some operator&& which returns int*
// X<false> when sizeof...(T) == 0
dependent.f<void>();
// expected-error@-1 {{use 'template' keyword to treat 'f' as a dependent template name}}
// expected-warning@-1 {{use 'template' keyword to treat 'f' as a dependent template name}}
}
template<typename T>
void f3() {
X<noexcept(typeid(*static_cast<T*>(nullptr)))> dependent;
// X<true> when T is int, X<false> when T is Polymorphic<false, false>
dependent.f<void>();
// expected-error@-1 {{use 'template' keyword to treat 'f' as a dependent template name}}
// expected-warning@-1 {{use 'template' keyword to treat 'f' as a dependent template name}}
}
template<typename T>
void f4() {
Expand Down
18 changes: 9 additions & 9 deletions clang/test/SemaCXX/pseudo-destructors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ void cv_test(const volatile T* cvt) {
void f(A* a, Foo *f, int *i, double *d, int ii) {
a->~A();
a->A::~A();

a->~foo(); // expected-error{{undeclared identifier 'foo' in destructor name}}

a->~Bar(); // expected-error{{destructor type 'Bar' (aka 'Foo') in object destruction expression does not match the type 'A' of the object being destroyed}}

f->~Bar();
f->~Foo();
i->~Bar(); // expected-error{{does not match}}

g().~Bar(); // expected-error{{non-scalar}}

f->::~Bar(); // expected-error {{not a structure or union}}
f->::Bar::~Bar();
f->N::~Wibble(); // expected-error{{'N' does not refer to a type}} expected-error{{'Wibble' does not refer to a type}}

f->Bar::~Bar(17, 42); // expected-error{{cannot have any arguments}}

i->~Integer();
Expand Down Expand Up @@ -148,12 +148,12 @@ namespace TwoPhaseLookup {
namespace Template {
template<typename T> struct Y {};
template<class U> using G = Y<U>;
template<typename T> void f(T *p) { p->~G<int>(); } // expected-error {{no member named '~Y'}}
template<typename T> void f(T *p) { p->~G<int>(); } // expected-error {{no member named 'G'}}
void h1(Y<int> *p) { p->~G<int>(); }
void h2(Y<int> *p) { f(p); }
void h2(Y<int> *p) { f(p); } // expected-note {{instantiation of}}
namespace N { template<typename T> struct G {}; }
void h3(N::G<int> *p) { p->~G<int>(); }
void h4(N::G<int> *p) { f(p); } // expected-note {{instantiation of}}
void h4(N::G<int> *p) { f(p); }
}

namespace TemplateUndeclared {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/static-assert-cxx17.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void foo6() {
// expected-error@-1{{static assertion failed due to requirement 'static_cast<const X<int> *>(nullptr)'}}
static_assert((const X<typename T::T>[]){} == nullptr);
// expected-error@-1{{static assertion failed due to requirement '(const X<int>[0]){} == nullptr'}}
static_assert(sizeof(X<decltype(X<typename T::T>().X<typename T::T>::~X())>) == 0);
static_assert(sizeof(X<decltype(X<typename T::T>().template X<typename T::T>::~X())>) == 0);
// expected-error@-1{{static assertion failed due to requirement 'sizeof(X<void>) == 0'}} \
// expected-note@-1 {{evaluates to '8 == 0'}}
static_assert(constexpr_return_false<typename T::T, typename T::U>());
Expand Down
48 changes: 48 additions & 0 deletions clang/test/SemaHLSL/Loops/unroll.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// RUN: %clang_cc1 -O0 -finclude-default-header -fsyntax-only -triple dxil-pc-shadermodel6.6-library %s -verify
void unroll_no_vars() {
int I = 3;
[unroll(I)] // expected-error {{'unroll' attribute requires an integer constant}}
while (I--);
}

void unroll_arg_count() {
[unroll(2,4)] // expected-error {{'unroll' attribute takes no more than 1 argument}}
for(int i=0; i<100; i++);
}

void loop_arg_count() {
[loop(2)] // expected-error {{'loop' attribute takes no more than 0 argument}}
for(int i=0; i<100; i++);
}

void unroll_no_negative() {
[unroll(-1)] // expected-error {{invalid value '-1'; must be positive}}
for(int i=0; i<100; i++);
}

void unroll_no_zero() {
[unroll(0)] // expected-error {{invalid value '0'; must be positive}}
for(int i=0; i<100; i++);
}

void unroll_no_float() {
[unroll(2.1)] // expected-error {{invalid argument of type 'float'; expected an integer type}}
for(int i=0; i<100; i++);
}

void unroll_no_bool_false() {
[unroll(false)] // expected-error {{invalid argument of type 'bool'; expected an integer type}}
for(int i=0; i<100; i++);
}

void unroll_no_bool_true() {
[unroll(true)] // expected-error {{invalid argument of type 'bool'; expected an integer type}}
for(int i=0; i<100; i++);
}

void unroll_loop_enforcement() {
int x[10];
[unroll(4)] // expected-error {{'unroll' attribute only applies to 'for', 'while', and 'do' statements}}
if (x[0])
x[0] = 15;
}
20 changes: 10 additions & 10 deletions clang/test/SemaTemplate/dependent-base-classes.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s

template<typename T, typename U>
struct X0 : T::template apply<U> {
struct X0 : T::template apply<U> {
X0(U u) : T::template apply<U>(u) { }
};

template<typename T, typename U>
struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
struct X1 : T::apply<U> { }; // expected-warning{{use 'template' keyword to treat 'apply' as a dependent template name}}

template<typename T>
struct X2 : vector<T> { }; // expected-error{{no template named 'vector'}}
Expand Down Expand Up @@ -85,7 +85,7 @@ namespace PR6081 {
struct A { };

template<typename T>
class B : public A<T>
class B : public A<T>
{
public:
template< class X >
Expand All @@ -109,9 +109,9 @@ namespace PR6081 {

namespace PR6413 {
template <typename T> class Base_A { };

class Base_B { };

template <typename T>
class Derived
: public virtual Base_A<T>
Expand All @@ -120,12 +120,12 @@ namespace PR6413 {
}

namespace PR5812 {
template <class T> struct Base {
Base* p;
};
template <class T> struct Base {
Base* p;
};

template <class T> struct Derived: public Base<T> {
typename Derived::Base* p; // meaning Derived::Base<T>
template <class T> struct Derived: public Base<T> {
typename Derived::Base* p; // meaning Derived::Base<T>
};

Derived<int> di;
Expand Down
12 changes: 6 additions & 6 deletions clang/test/SemaTemplate/dependent-template-recover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
template<typename T, typename U, int N>
struct X {
void f(T* t) {
t->f0<U>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
t->f0<int>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
t->f0<U>(); // expected-warning{{use 'template' keyword to treat 'f0' as a dependent template name}}
t->f0<int>(); // expected-warning{{use 'template' keyword to treat 'f0' as a dependent template name}}

t->operator+<U const, 1>(1); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}}
t->f1<int const, 2>(1); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
t->operator+<U const, 1>(1); // expected-warning{{use 'template' keyword to treat 'operator +' as a dependent template name}}
t->f1<int const, 2>(1); // expected-warning{{use 'template' keyword to treat 'f1' as a dependent template name}}
t->f1<3, int const>(1); // expected-error{{missing 'template' keyword prior to dependent template name 'f1'}}

T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
T::getAs<U>(); // expected-warning{{use 'template' keyword to treat 'getAs' as a dependent template name}}
t->T::getAs<U>(); // expected-warning{{use 'template' keyword to treat 'getAs' as a dependent template name}}

(*t).f2<N>(); // expected-error{{missing 'template' keyword prior to dependent template name 'f2'}}
(*t).f2<0>(); // expected-error{{missing 'template' keyword prior to dependent template name 'f2'}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ namespace CopyCounting {
static_assert(f(X<A{}>()) == 0);

template<A a> struct Y { void f(); };
template<A a> void g(Y<a> y) { y.Y<a>::f(); }
template<A a> void g(Y<a> y) { y.template Y<a>::f(); }
void h() { constexpr A a; g<a>(Y<a>{}); }

template<A a> struct Z {
Expand Down
14 changes: 7 additions & 7 deletions clang/test/SemaTemplate/template-id-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ template<typename T>
struct X0 {
template<typename U>
void f1();

template<typename U>
void f2(U) {
f1<U>();
Expand All @@ -39,9 +39,9 @@ struct Y {
template<int I>
struct X {
X(int, int);
void f() {
Y<X<I> >(X<I>(0, 0));
Y<X<I> >(::X<I>(0, 0));
void f() {
Y<X<I> >(X<I>(0, 0));
Y<X<I> >(::X<I>(0, 0));
}
};

Expand Down Expand Up @@ -149,11 +149,11 @@ struct Y2 : Y1<T> {

int x;
x = Y1::f4(0);
x = Y1::f4<int>(0); // expected-error {{use 'template'}} expected-error {{assigning to 'int' from incompatible type 'void'}}
x = Y1::f4<int>(0); // expected-warning {{use 'template'}} expected-error {{assigning to 'int' from incompatible type 'void'}}
x = Y1::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}

x = p->f4(0);
x = p->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-error {{use 'template'}}
x = p->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-warning {{use 'template'}}
x = p->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
}
};
Expand Down Expand Up @@ -184,7 +184,7 @@ class E {
#if __cplusplus <= 199711L
// expected-warning@+2 {{extension}}
#endif
template<typename T> using D = int; // expected-note {{declared here}}
template<typename T> using D = int; // expected-note {{declared here}}
E<D> ed; // expected-note {{instantiation of}}

namespace non_functions {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaTemplate/typename-specifier-3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace PR12884_half_fixed {
typedef int arg;
};
struct C {
typedef typename B::X<typename B::arg> x; // expected-error {{use 'template'}} expected-error {{refers to non-type}}
typedef typename B::X<typename B::arg> x; // expected-warning {{use 'template'}} expected-error {{refers to non-type}}
};
};

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
${LOONGARCH64})
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64}
${HEXAGON} ${LOONGARCH64} ${SPARC} ${SPARCV9})
${HEXAGON} ${LOONGARCH64})
set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64}
${HEXAGON} ${LOONGARCH64})
set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/lib/hwasan/hwasan_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,6 @@ bool InitShadow() {
CHECK_GT(kLowShadowEnd, kLowShadowStart);
CHECK_GT(kLowShadowStart, kLowMemEnd);

if (Verbosity())
PrintAddressSpaceLayout();

// Reserve shadow memory.
ReserveShadowMemoryRange(kLowShadowStart, kLowShadowEnd, "low shadow");
ReserveShadowMemoryRange(kHighShadowStart, kHighShadowEnd, "high shadow");
Expand All @@ -267,6 +264,9 @@ bool InitShadow() {
if (kHighShadowEnd + 1 < kHighMemStart)
ProtectGap(kHighShadowEnd + 1, kHighMemStart - kHighShadowEnd - 1);

if (Verbosity())
PrintAddressSpaceLayout();

return true;
}

Expand Down
5 changes: 3 additions & 2 deletions compiler-rt/lib/safestack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ foreach(arch ${SAFESTACK_SUPPORTED_ARCH})
ARCHS ${arch}
SOURCES ${SAFESTACK_SOURCES}
$<TARGET_OBJECTS:RTInterception.${arch}>
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
# Intentionally does not deppend on sanitizer_common,
# to keep runtime trivial, and acceptable for security
# sensitive applications.
CFLAGS ${SAFESTACK_CFLAGS}
PARENT_TARGET safestack)
endforeach()
11 changes: 0 additions & 11 deletions compiler-rt/lib/safestack/safestack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,6 @@ INTERCEPTOR(int, pthread_create, pthread_t *thread,
pthread_attr_destroy(&tmpattr);
}

#if SANITIZER_SOLARIS
// Solaris pthread_attr_init initializes stacksize to 0 (the default), so
// hardcode the actual values as documented in pthread_create(3C).
if (size == 0)
# if defined(_LP64)
size = 2 * 1024 * 1024;
# else
size = 1024 * 1024;
# endif
#endif

SFS_CHECK(size);
size = RoundUpTo(size, kStackAlign);

Expand Down
35 changes: 7 additions & 28 deletions compiler-rt/lib/safestack/safestack_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "sanitizer_common/sanitizer_platform.h"

#include <dlfcn.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -69,24 +68,6 @@ static void *GetRealLibcAddress(const char *symbol) {
SFS_CHECK(real_##func);
#endif

#if SANITIZER_SOLARIS
# define _REAL(func) _##func
# define DEFINE__REAL(ret_type, func, ...) \
extern "C" ret_type _REAL(func)(__VA_ARGS__)

# if !defined(_LP64) && _FILE_OFFSET_BITS == 64
# define _REAL64(func) _##func##64
# else
# define _REAL64(func) _REAL(func)
# endif
# define DEFINE__REAL64(ret_type, func, ...) \
extern "C" ret_type _REAL64(func)(__VA_ARGS__)

DEFINE__REAL64(void *, mmap, void *a, size_t b, int c, int d, int e, off_t f);
DEFINE__REAL(int, munmap, void *a, size_t b);
DEFINE__REAL(int, mprotect, void *a, size_t b, int c);
#endif

using ThreadId = uint64_t;

inline ThreadId GetTid() {
Expand All @@ -110,10 +91,11 @@ inline int TgKill(pid_t pid, ThreadId tid, int sig) {
(void)pid;
return _REAL(_lwp_kill, tid, sig);
#elif SANITIZER_SOLARIS
(void)pid;
errno = thr_kill(tid, sig);
// TgKill is expected to return -1 on error, not an errno.
return errno != 0 ? -1 : 0;
# ifdef SYS_lwp_kill
return syscall(SYS_lwp_kill, tid, sig);
# else
return -1;
# endif
#elif SANITIZER_FREEBSD
return syscall(SYS_thr_kill2, pid, tid, sig);
#else
Expand All @@ -128,7 +110,8 @@ inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd,
#elif SANITIZER_FREEBSD && (defined(__aarch64__) || defined(__x86_64__))
return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
#elif SANITIZER_SOLARIS
return _REAL64(mmap)(addr, length, prot, flags, fd, offset);
return (void *)(uintptr_t)syscall(SYS_mmap, addr, length, prot, flags, fd,
offset);
#else
return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
#endif
Expand All @@ -138,8 +121,6 @@ inline int Munmap(void *addr, size_t length) {
#if SANITIZER_NETBSD
DEFINE__REAL(int, munmap, void *a, size_t b);
return _REAL(munmap, addr, length);
#elif SANITIZER_SOLARIS
return _REAL(munmap)(addr, length);
#else
return syscall(SYS_munmap, addr, length);
#endif
Expand All @@ -149,8 +130,6 @@ inline int Mprotect(void *addr, size_t length, int prot) {
#if SANITIZER_NETBSD
DEFINE__REAL(int, mprotect, void *a, size_t b, int c);
return _REAL(mprotect, addr, length, prot);
#elif SANITIZER_SOLARIS
return _REAL(mprotect)(addr, length, prot);
#else
return syscall(SYS_mprotect, addr, length, prot);
#endif
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/safestack/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@
)
)

if config.host_os not in ["Linux", "FreeBSD", "NetBSD", "SunOS"]:
if config.host_os not in ["Linux", "FreeBSD", "NetBSD"]:
config.unsupported = True
9 changes: 9 additions & 0 deletions flang/include/flang/Frontend/CompilerInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class CompilerInvocation : public CompilerInvocationBase {
std::string moduleFileSuffix = ".mod";

bool debugModuleDir = false;
bool hermeticModuleFileOutput = false;

bool warnAsErr = false;

Expand Down Expand Up @@ -179,6 +180,11 @@ class CompilerInvocation : public CompilerInvocationBase {
bool &getDebugModuleDir() { return debugModuleDir; }
const bool &getDebugModuleDir() const { return debugModuleDir; }

bool &getHermeticModuleFileOutput() { return hermeticModuleFileOutput; }
const bool &getHermeticModuleFileOutput() const {
return hermeticModuleFileOutput;
}

bool &getWarnAsErr() { return warnAsErr; }
const bool &getWarnAsErr() const { return warnAsErr; }

Expand Down Expand Up @@ -244,6 +250,9 @@ class CompilerInvocation : public CompilerInvocationBase {
}

void setDebugModuleDir(bool flag) { debugModuleDir = flag; }
void setHermeticModuleFileOutput(bool flag) {
hermeticModuleFileOutput = flag;
}

void setWarnAsErr(bool flag) { warnAsErr = flag; }

Expand Down
10 changes: 6 additions & 4 deletions flang/include/flang/Semantics/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,11 @@ class SemanticsContext {

class Semantics {
public:
explicit Semantics(SemanticsContext &context, parser::Program &program,
bool debugModuleWriter = false)
: context_{context}, program_{program} {
context.set_debugModuleWriter(debugModuleWriter);
explicit Semantics(SemanticsContext &context, parser::Program &program)
: context_{context}, program_{program} {}
Semantics &set_hermeticModuleFileOutput(bool yes = true) {
hermeticModuleFileOutput_ = yes;
return *this;
}

SemanticsContext &context() const { return context_; }
Expand All @@ -326,6 +327,7 @@ class Semantics {
private:
SemanticsContext &context_;
parser::Program &program_;
bool hermeticModuleFileOutput_{false};
};

// Base class for semantics checkers.
Expand Down
5 changes: 5 additions & 0 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,11 @@ static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
res.setDebugModuleDir(true);
}

// -fhermetic-module-files option
if (args.hasArg(clang::driver::options::OPT_fhermetic_module_files)) {
res.setHermeticModuleFileOutput(true);
}

// -module-suffix
if (const auto *moduleSuffix =
args.getLastArg(clang::driver::options::OPT_module_suffix)) {
Expand Down
7 changes: 5 additions & 2 deletions flang/lib/Frontend/FrontendAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,14 @@ bool FrontendAction::runSemanticChecks() {
// so that they are merged and all printed in order.
auto &semanticsCtx{ci.getSemanticsContext()};
semanticsCtx.messages().Annex(std::move(ci.getParsing().messages()));
semanticsCtx.set_debugModuleWriter(ci.getInvocation().getDebugModuleDir());

// Prepare semantics
ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(
semanticsCtx, *parseTree, ci.getInvocation().getDebugModuleDir()));
ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(semanticsCtx,
*parseTree));
auto &semantics = ci.getSemantics();
semantics.set_hermeticModuleFileOutput(
ci.getInvocation().getHermeticModuleFileOutput());

// Run semantic checks
semantics.Perform();
Expand Down
9 changes: 7 additions & 2 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4296,8 +4296,13 @@ class FirConverter : public Fortran::lower::AbstractConverter {
auto [temp, cleanup] =
hlfir::createTempFromMold(loc, builder, entity);
auto needCleanup = fir::getIntIfConstant(cleanup);
if (needCleanup && *needCleanup)
temps.push_back(temp);
if (needCleanup && *needCleanup) {
if (auto declareOp =
mlir::dyn_cast<hlfir::DeclareOp>(temp.getDefiningOp()))
temps.push_back(declareOp.getMemref());
else
temps.push_back(temp);
}
addSymbol(sym,
hlfir::translateToExtendedValue(loc, builder, temp).first,
/*forced=*/true);
Expand Down
42 changes: 32 additions & 10 deletions flang/lib/Semantics/mod-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,26 @@ void ModFileWriter::Write(const Symbol &symbol) {
auto ancestorName{ancestor ? ancestor->GetName().value().ToString() : ""s};
auto path{context_.moduleDirectory() + '/' +
ModFileName(symbol.name(), ancestorName, context_.moduleFileSuffix())};
PutSymbols(DEREF(symbol.scope()));

UnorderedSymbolSet hermeticModules;
hermeticModules.insert(symbol);
UnorderedSymbolSet additionalModules;
PutSymbols(DEREF(symbol.scope()),
hermeticModuleFileOutput_ ? &additionalModules : nullptr);
auto asStr{GetAsString(symbol)};
while (!additionalModules.empty()) {
for (auto ref : UnorderedSymbolSet{std::move(additionalModules)}) {
if (hermeticModules.insert(*ref).second &&
!ref->owner().IsIntrinsicModules()) {
PutSymbols(DEREF(ref->scope()), &additionalModules);
asStr += GetAsString(*ref);
}
}
}

ModuleCheckSumType checkSum;
if (std::error_code error{WriteFile(
path, GetAsString(symbol), checkSum, context_.debugModuleWriter())}) {
if (std::error_code error{
WriteFile(path, asStr, checkSum, context_.debugModuleWriter())}) {
context_.Say(
symbol.name(), "Error writing %s: %s"_err_en_US, path, error.message());
}
Expand All @@ -157,7 +173,7 @@ void ModFileWriter::WriteClosure(llvm::raw_ostream &out, const Symbol &symbol,
!nonIntrinsicModulesWritten.insert(symbol).second) {
return;
}
PutSymbols(DEREF(symbol.scope()));
PutSymbols(DEREF(symbol.scope()), /*hermeticModules=*/nullptr);
needsBuf_.clear(); // omit module checksums
auto str{GetAsString(symbol)};
for (auto depRef : std::move(usedNonIntrinsicModules_)) {
Expand Down Expand Up @@ -338,7 +354,8 @@ void ModFileWriter::PrepareRenamings(const Scope &scope) {
}

// Put out the visible symbols from scope.
void ModFileWriter::PutSymbols(const Scope &scope) {
void ModFileWriter::PutSymbols(
const Scope &scope, UnorderedSymbolSet *hermeticModules) {
SymbolVector sorted;
SymbolVector uses;
auto &renamings{context_.moduleFileOutputRenamings()};
Expand All @@ -349,11 +366,16 @@ void ModFileWriter::PutSymbols(const Scope &scope) {
// Write module files for dependencies first so that their
// hashes are known.
for (auto ref : modules) {
Write(*ref);
needs_ << ModHeader::need
<< CheckSumString(ref->get<ModuleDetails>().moduleFileHash().value())
<< (ref->owner().IsIntrinsicModules() ? " i " : " n ")
<< ref->name().ToString() << '\n';
if (hermeticModules) {
hermeticModules->insert(*ref);
} else {
Write(*ref);
needs_ << ModHeader::need
<< CheckSumString(
ref->get<ModuleDetails>().moduleFileHash().value())
<< (ref->owner().IsIntrinsicModules() ? " i " : " n ")
<< ref->name().ToString() << '\n';
}
}
std::string buf; // stuff after CONTAINS in derived type
llvm::raw_string_ostream typeBindings{buf};
Expand Down
7 changes: 6 additions & 1 deletion flang/lib/Semantics/mod-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class ModFileWriter {
bool WriteAll();
void WriteClosure(llvm::raw_ostream &, const Symbol &,
UnorderedSymbolSet &nonIntrinsicModulesWritten);
ModFileWriter &set_hermeticModuleFileOutput(bool yes = true) {
hermeticModuleFileOutput_ = yes;
return *this;
}

private:
SemanticsContext &context_;
Expand All @@ -57,13 +61,14 @@ class ModFileWriter {
llvm::raw_string_ostream decls_{declsBuf_};
llvm::raw_string_ostream contains_{containsBuf_};
bool isSubmodule_{false};
bool hermeticModuleFileOutput_{false};

void WriteAll(const Scope &);
void WriteOne(const Scope &);
void Write(const Symbol &);
std::string GetAsString(const Symbol &);
void PrepareRenamings(const Scope &);
void PutSymbols(const Scope &);
void PutSymbols(const Scope &, UnorderedSymbolSet *hermetic);
// Returns true if a derived type with bindings and "contains" was emitted
bool PutComponents(const Symbol &);
void PutSymbol(llvm::raw_ostream &, const Symbol &);
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Semantics/semantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,9 @@ bool Semantics::Perform() {
CanonicalizeCUDA(program_) &&
CanonicalizeDirectives(context_.messages(), program_) &&
PerformStatementSemantics(context_, program_) &&
ModFileWriter{context_}.WriteAll();
ModFileWriter{context_}
.set_hermeticModuleFileOutput(hermeticModuleFileOutput_)
.WriteAll();
}

void Semantics::EmitMessages(llvm::raw_ostream &os) {
Expand Down
16 changes: 15 additions & 1 deletion flang/test/Lower/CUDA/cuda-data-transfer.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ end
! CHECK: cuf.data_transfer %[[ADEV]]#1 to %[[DECL_TEMP]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.array<10xi32>>, !fir.heap<!fir.array<10xi32>>
! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<10xi32>
! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[BHOST]]#0 : !hlfir.expr<10xi32>, !fir.ref<!fir.array<10xi32>>
! CHECK: fir.freemem %[[DECL_TEMP]]#0 : !fir.heap<!fir.array<10xi32>>
! CHECK: fir.freemem %[[TEMP]] : !fir.heap<!fir.array<10xi32>>

subroutine sub3()
use mod1
Expand Down Expand Up @@ -251,3 +251,17 @@ end subroutine
! CHECK: %{{.*}} = fir.call @_QMmod1Pdev1
! CHECK: hlfir.assign
! CHECK-NOT: cuf.data_transfer

subroutine sub13(a, b, n)
integer :: n
integer :: a(n)
integer, allocatable, device :: b(:)
integer :: res(10)

res = a + b
end subroutine

! CHECK-LABEL: func.func @_QPsub13
! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %14#1 {bindc_name = ".tmp", uniq_name = ""}
! CHECK: cuf.data_transfer
! CHECK: fir.freemem %[[TEMP]] : !fir.heap<!fir.array<?xi32>>
10 changes: 5 additions & 5 deletions flang/test/Lower/Intrinsics/atan_real16.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
function test_real16(x)
real(16) :: x, test_real16
test_real16 = atan(x)
end function real16
end function

! CHECK-LABEL: @_QPtest_real16
! CHECK: fir.call @_FortranAAtanF128({{.*}}){{.*}}: (f128) -> f128

function test_real16_2(y, x)
real(16) :: y, x, test_real16
test_real16 = atan(y, x)
end function real16_2
real(16) :: y, x, test_real16_2
test_real16_2 = atan(y, x)
end function

! CHECK-LABEL: @_QPtest_real16
! CHECK-LABEL: @_QPtest_real16_2
! CHECK: fir.call @_FortranAAtan2F128({{.*}}){{.*}}: (f128, f128) -> f128
53 changes: 53 additions & 0 deletions flang/test/Semantics/modfile65.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
! RUN: %python %S/test_modfile.py %s %flang_fc1 -fhermetic-module-files
module m1
integer, parameter :: n = 123
end

module m2
use m1
end

module m3
use m1, m => n
end

module m4
use m2
use m3
end

!Expect: m1.mod
!module m1
!integer(4),parameter::n=123_4
!end

!Expect: m2.mod
!module m2
!use m1,only:n
!end
!module m1
!integer(4),parameter::n=123_4
!end

!Expect: m3.mod
!module m3
!use m1,only:m=>n
!end
!module m1
!integer(4),parameter::n=123_4
!end

!Expect: m4.mod
!module m4
!use m2,only:n
!use m3,only:m
!end
!module m2
!use m1,only:n
!end
!module m3
!use m1,only:m=>n
!end
!module m1
!integer(4),parameter::n=123_4
!end
1 change: 1 addition & 0 deletions libc/include/llvm-libc-macros/math-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define MATH_ERREXCEPT 2

#define HUGE_VAL __builtin_huge_val()
#define HUGE_VALF __builtin_huge_valf()
#define INFINITY __builtin_inf()
#define NAN __builtin_nanf("")

Expand Down
5 changes: 4 additions & 1 deletion libc/newhdrgen/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def __str__(self):
content.append("")
for object in self.objects:
content.append(str(object))
content.append("__END_C_DECLS")
if self.objects:
content.append("\n__END_C_DECLS")
else:
content.append("__END_C_DECLS")

return "\n".join(content)
4 changes: 2 additions & 2 deletions libc/newhdrgen/tests/expected_output/test_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ enum {
__BEGIN_C_DECLS

#ifdef FUNC_A_16
void func_a()CONST_FUNC_A;
CONST_FUNC_A void func_a() __NOEXCEPT;
#endif // FUNC_A_16

#ifdef FUNC_B_16
int func_b(int, float)CONST_FUNC_B;
CONST_FUNC_B int func_b(int, float) __NOEXCEPT;
#endif // FUNC_B_16

extern obj object_1;
Expand Down
6 changes: 4 additions & 2 deletions libc/newhdrgen/tests/input/test_small.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ functions:
standards:
- stdc
guard: FUNC_A_16
attributes: CONST_FUNC_A
attributes:
- CONST_FUNC_A
- name: func_b
return_type: int
arguments:
Expand All @@ -33,4 +34,5 @@ functions:
standards:
- stdc
guard: FUNC_B_16
attributes: CONST_FUNC_B
attributes:
- CONST_FUNC_B
6 changes: 6 additions & 0 deletions libc/src/__support/macros/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define LIBC_HAS_FEATURE(f) 0
#endif

#ifdef __clang__
// Declare a LIBC_NAMESPACE with hidden visibility. `namespace
// LIBC_NAMESPACE_DECL {` should be used around all declarations and definitions
// for libc internals as opposed to just `namespace LIBC_NAMESPACE {`. This
Expand All @@ -37,5 +38,10 @@
// dynamic relocations. This does not affect the public C symbols which are
// controlled independently via `LLVM_LIBC_FUNCTION_ATTR`.
#define LIBC_NAMESPACE_DECL [[gnu::visibility("hidden")]] LIBC_NAMESPACE
#else
// TODO(#98548): GCC emits a warning when using the visibility attribute which
// needs to be diagnosed and addressed.
#define LIBC_NAMESPACE_DECL LIBC_NAMESPACE
#endif

#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H
13 changes: 11 additions & 2 deletions libc/src/stdlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -497,15 +497,24 @@ add_entrypoint_object(
.exit_handler
)

list(APPEND exit_deps
libc.src.__support.OSUtil.osutil
._Exit
)
if (NOT LIBC_TARGET_OS_IS_BAREMETAL)
list(APPEND exit_deps
.atexit
)
endif()

add_entrypoint_object(
exit
SRCS
exit.cpp
HDRS
exit.h
DEPENDS
._Exit
libc.src.__support.OSUtil.osutil
${exit_deps}
)

add_entrypoint_object(
Expand Down
1 change: 1 addition & 0 deletions libc/test/src/math/performance_testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ add_library(
Timer.cpp
Timer.h
)
add_dependencies(libc_diff_test_utils libc.src.__support.macros.config)

# A convenience target to build all performance tests.
add_custom_target(libc-math-performance-tests)
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/regex
Original file line number Diff line number Diff line change
Expand Up @@ -4214,7 +4214,7 @@ public:
_LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return str().compare(__s); }

_LIBCPP_HIDE_FROM_ABI void swap(sub_match& __s) _NOEXCEPT_(__is_nothrow_swappable_v<_BidirectionalIterator>) {
this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s);
this->template pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s);
std::swap(matched, __s.matched);
}
};
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Arch/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,8 @@ void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
continue;
case R_RELAX_TLS_GD_TO_LE:
// See the comment in handleTlsRelocation. For TLSDESC=>IE,
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12,CALL} also reach here. If isToIe is
// true, this is actually TLSDESC=>IE optimization.
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12,CALL} also reach here. If isToLe is
// false, this is actually TLSDESC=>IE optimization.
if (rel.type == R_RISCV_TLSDESC_HI20) {
tlsdescVal = val;
isToLe = true;
Expand Down
5 changes: 5 additions & 0 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,11 @@ static int64_t getTlsTpOffset(const Symbol &s) {
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1)) - 0x7000;
case EM_LOONGARCH:
case EM_RISCV:
// See the comment in handleTlsRelocation. For TLSDESC=>IE,
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} also reach here. While
// `tls` may be null, the return value is ignored.
if (s.type != STT_TLS)
return 0;
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1));

// Variant 2.
Expand Down
4 changes: 2 additions & 2 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1399,8 +1399,8 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
// depending on the symbol being locally defined or not.
//
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference a non-preemptible
// label, so the LE optimization will be categorized as
// R_RELAX_TLS_GD_TO_LE. We fix the categorization in RISCV::relocateAlloc.
// label, so TLSDESC=>IE will be categorized as R_RELAX_TLS_GD_TO_LE. We fix
// the categorization in RISCV::relocateAlloc.
if (sym.isPreemptible) {
sym.setFlags(NEEDS_TLSGD_TO_IE);
c.addReloc({target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type,
Expand Down
2 changes: 1 addition & 1 deletion lld/test/ELF/basic-sparcv9.s
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ _start:
# CHECK-NEXT: Class: 64-bit (0x2)
# CHECK-NEXT: DataEncoding: BigEndian (0x2)
# CHECK-NEXT: FileVersion: 1
# CHECK-NEXT: OS/ABI: SystemV (0x0)
# CHECK-NEXT: OS/ABI: OpenBSD (0xC)
# CHECK-NEXT: ABIVersion: 0
# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
# CHECK-NEXT: }
Expand Down
25 changes: 25 additions & 0 deletions lld/test/ELF/riscv-tlsdesc.s
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
# RUN: llvm-mc -triple=riscv32 -filetype=obj d.s -o d.32.o --defsym ELF32=1
# RUN: ld.lld -shared -soname=d.32.so -o d.32.so d.32.o --fatal-warnings

## The output has a TLS reference but no TLS section.
# RUN: llvm-mc -filetype=obj -triple=riscv64 a1.s -o a1.64.o
# RUN: ld.lld -pie a1.64.o c.64.so -o a1.64
# RUN: llvm-objdump --no-show-raw-insn -M no-aliases -Rd a1.64 | FileCheck %s --check-prefix=IE64A

# GD64-RELA: .rela.dyn {
# GD64-RELA-NEXT: 0x2408 R_RISCV_TLSDESC - 0x7FF
# GD64-RELA-NEXT: 0x23E8 R_RISCV_TLSDESC a 0x0
Expand Down Expand Up @@ -164,6 +169,17 @@
# IE32-NEXT: lw a0, 0x80(a0)
# IE32-NEXT: add a0, a0, tp

# IE64A: OFFSET TYPE VALUE
# IE64A-NEXT: 0000000000002340 R_RISCV_TLS_TPREL64 c
# IE64A-EMPTY:
## &.got[c]-. = 0x2340 - 0x1258 = 0x10e8
# IE64A-LABEL: <.Ltlsdesc_hi2>:
# IE64A-NEXT: addi zero, zero, 0x0
# IE64A-NEXT: addi zero, zero, 0x0
# IE64A-NEXT: 1258: auipc a0, 0x1
# IE64A-NEXT: ld a0, 0xe8(a0)
# IE64A-NEXT: add a0, a0, tp

#--- a.s
.macro load dst, src
.ifdef ELF32
Expand Down Expand Up @@ -202,6 +218,15 @@ a:
b:
.zero 1

#--- a1.s
## a.s without TLS definitions.
.Ltlsdesc_hi2:
auipc a4, %tlsdesc_hi(c)
ld a5, %tlsdesc_load_lo(.Ltlsdesc_hi2)(a4)
addi a0, a4, %tlsdesc_add_lo(.Ltlsdesc_hi2)
jalr t0, 0(a5), %tlsdesc_call(.Ltlsdesc_hi2)
add a0, a0, tp

#--- c.s
.tbss
.globl c
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Test that we don't read objc class tables early in process startup."""


import time
import lldb
from lldbsuite.test.decorators import *
Expand Down Expand Up @@ -30,7 +29,14 @@ def test_early_process_launch(self):
###
### Use the types logging to detect the difference.

target, process, _, bkpt = lldbutil.run_to_name_breakpoint(self, "malloc")
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target.IsValid())
bkpt = target.BreakpointCreateByRegex("alloc", None)
self.assertTrue(bkpt.IsValid())
(target, process, thread, bkpt) = lldbutil.run_to_breakpoint_do_run(
self, target, bkpt
)

target.DisableAllBreakpoints()
target.BreakpointCreateByName("main")
Expand Down
7 changes: 5 additions & 2 deletions llvm/include/llvm/ADT/ArrayRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,11 @@ namespace llvm {

OwningArrayRef &operator=(OwningArrayRef &&Other) {
delete[] this->data();
this->MutableArrayRef<T>::operator=(Other);
Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>());
using Base = MutableArrayRef<T>;
// GCC versions prior to 11.1 incorrectly reject if the 'template' keyword
// is used prior to the nested-name-specifier here.
this->Base::operator=(Other);
Other.Base::operator=(Base());
return *this;
}

Expand Down
5 changes: 3 additions & 2 deletions llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,8 @@ enum GlobalValueSummarySymtabCodes {
// [valueid, n x stackidindex]
FS_PERMODULE_CALLSITE_INFO = 26,
// Summary of per-module allocation memprof metadata.
// [n x (alloc type, nummib, nummib x stackidindex)]
// [nummib, nummib x (alloc type, numstackids, numstackids x stackidindex),
// [nummib x total size]?]
FS_PERMODULE_ALLOC_INFO = 27,
// Summary of combined index memprof callsite metadata.
// [valueid, numstackindices, numver,
Expand All @@ -316,7 +317,7 @@ enum GlobalValueSummarySymtabCodes {
// Summary of combined index allocation memprof metadata.
// [nummib, numver,
// nummib x (alloc type, numstackids, numstackids x stackidindex),
// numver x version]
// numver x version, [nummib x total size]?]
FS_COMBINED_ALLOC_INFO = 29,
FS_STACK_IDS = 30,
};
Expand Down
16 changes: 15 additions & 1 deletion llvm/include/llvm/IR/ModuleSummaryIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ struct AllocInfo {
// Vector of MIBs in this memprof metadata.
std::vector<MIBInfo> MIBs;

// If requested, keep track of total profiled sizes for each MIB. This will be
// a vector of the same length and order as the MIBs vector, if non-empty.
std::vector<uint64_t> TotalSizes;

AllocInfo(std::vector<MIBInfo> MIBs) : MIBs(std::move(MIBs)) {
Versions.push_back(0);
}
Expand All @@ -423,6 +427,16 @@ inline raw_ostream &operator<<(raw_ostream &OS, const AllocInfo &AE) {
for (auto &M : AE.MIBs) {
OS << "\t\t" << M << "\n";
}
if (!AE.TotalSizes.empty()) {
OS << " TotalSizes per MIB:\n\t\t";
First = true;
for (uint64_t TS : AE.TotalSizes) {
if (!First)
OS << ", ";
First = false;
OS << TS << "\n";
}
}
return OS;
}

Expand Down Expand Up @@ -1431,7 +1445,7 @@ class ModuleSummaryIndex {
// in the way some record are interpreted, like flags for instance.
// Note that incrementing this may require changes in both BitcodeReader.cpp
// and BitcodeWriter.cpp.
static constexpr uint64_t BitcodeSummaryVersion = 9;
static constexpr uint64_t BitcodeSummaryVersion = 10;

// Regular LTO module name for ASM writer
static constexpr const char *getRegularLTOModuleName() {
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/MC/MCELFObjectWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class MCELFObjectTargetWriter : public MCObjectTargetWriter {
return ELF::ELFOSABI_FREEBSD;
case Triple::Solaris:
return ELF::ELFOSABI_SOLARIS;
case Triple::OpenBSD:
return ELF::ELFOSABI_OPENBSD;
default:
return ELF::ELFOSABI_NONE;
}
Expand Down
7 changes: 3 additions & 4 deletions llvm/include/llvm/ProfileData/InstrProf.h
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,8 @@ struct InstrProfValueSiteRecord {
std::vector<InstrProfValueData> ValueData;

InstrProfValueSiteRecord() = default;
template <class InputIterator>
InstrProfValueSiteRecord(InputIterator F, InputIterator L)
: ValueData(F, L) {}
InstrProfValueSiteRecord(std::vector<InstrProfValueData> &&VD)
: ValueData(VD) {}

/// Sort ValueData ascending by Value
void sortByTargetValues() {
Expand Down Expand Up @@ -870,7 +869,7 @@ struct InstrProfRecord {
/// Add ValueData for ValueKind at value Site. We do not support adding sites
/// out of order. Site must go up from 0 one by one.
void addValueData(uint32_t ValueKind, uint32_t Site,
InstrProfValueData *VData, uint32_t N,
ArrayRef<InstrProfValueData> VData,
InstrProfSymtab *SymTab);

/// Merge the counts in \p Other into this one.
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ extern cl::opt<bool> ScalePartialSampleProfileWorkingSetSize;

extern cl::opt<unsigned> MaxNumVTableAnnotations;

extern cl::opt<bool> MemProfReportHintedSizes;

// Walk through the operands of a given User via worklist iteration and populate
// the set of GlobalValue references encountered. Invoked either on an
// Instruction or a GlobalVariable (which walks its initializer).
Expand Down Expand Up @@ -517,6 +519,7 @@ static void computeFunctionSummary(
auto *MemProfMD = I.getMetadata(LLVMContext::MD_memprof);
if (MemProfMD) {
std::vector<MIBInfo> MIBs;
std::vector<uint64_t> TotalSizes;
for (auto &MDOp : MemProfMD->operands()) {
auto *MIBMD = cast<const MDNode>(MDOp);
MDNode *StackNode = getMIBStackNode(MIBMD);
Expand All @@ -536,8 +539,17 @@ static void computeFunctionSummary(
}
MIBs.push_back(
MIBInfo(getMIBAllocType(MIBMD), std::move(StackIdIndices)));
if (MemProfReportHintedSizes) {
auto TotalSize = getMIBTotalSize(MIBMD);
assert(TotalSize);
TotalSizes.push_back(TotalSize);
}
}
Allocs.push_back(AllocInfo(std::move(MIBs)));
if (MemProfReportHintedSizes) {
assert(Allocs.back().MIBs.size() == TotalSizes.size());
Allocs.back().TotalSizes = std::move(TotalSizes);
}
} else if (!InstCallsite.empty()) {
SmallVector<unsigned> StackIdIndices;
for (auto StackId : InstCallsite)
Expand Down
33 changes: 31 additions & 2 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4381,7 +4381,6 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
return error("Malformed partition, too large.");
NewGA->setPartition(
StringRef(Strtab.data() + Record[OpNum], Record[OpNum + 1]));
OpNum += 2;
}

ValueList.push_back(NewGA, getVirtualTypeID(NewGA->getType(), TypeID));
Expand Down Expand Up @@ -7994,7 +7993,12 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
case bitc::FS_PERMODULE_ALLOC_INFO: {
unsigned I = 0;
std::vector<MIBInfo> MIBs;
while (I < Record.size()) {
unsigned NumMIBs = 0;
if (Version >= 10)
NumMIBs = Record[I++];
unsigned MIBsRead = 0;
while ((Version >= 10 && MIBsRead++ < NumMIBs) ||
(Version < 10 && I < Record.size())) {
assert(Record.size() - I >= 2);
AllocationType AllocType = (AllocationType)Record[I++];
unsigned NumStackEntries = Record[I++];
Expand All @@ -8007,7 +8011,19 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
}
MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList)));
}
std::vector<uint64_t> TotalSizes;
// We either have no sizes or NumMIBs of them.
assert(I == Record.size() || Record.size() - I == NumMIBs);
if (I < Record.size()) {
MIBsRead = 0;
while (MIBsRead++ < NumMIBs)
TotalSizes.push_back(Record[I++]);
}
PendingAllocs.push_back(AllocInfo(std::move(MIBs)));
if (!TotalSizes.empty()) {
assert(PendingAllocs.back().MIBs.size() == TotalSizes.size());
PendingAllocs.back().TotalSizes = std::move(TotalSizes);
}
break;
}

Expand All @@ -8034,8 +8050,21 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
SmallVector<uint8_t> Versions;
for (unsigned J = 0; J < NumVersions; J++)
Versions.push_back(Record[I++]);
std::vector<uint64_t> TotalSizes;
// We either have no sizes or NumMIBs of them.
assert(I == Record.size() || Record.size() - I == NumMIBs);
if (I < Record.size()) {
MIBsRead = 0;
while (MIBsRead++ < NumMIBs) {
TotalSizes.push_back(Record[I++]);
}
}
PendingAllocs.push_back(
AllocInfo(std::move(Versions), std::move(MIBs)));
if (!TotalSizes.empty()) {
assert(PendingAllocs.back().MIBs.size() == TotalSizes.size());
PendingAllocs.back().TotalSizes = std::move(TotalSizes);
}
break;
}
}
Expand Down
19 changes: 14 additions & 5 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4189,10 +4189,9 @@ static void writeFunctionHeapProfileRecords(
// Per module alloc versions should always have a single entry of
// value 0.
assert(!PerModule || (AI.Versions.size() == 1 && AI.Versions[0] == 0));
if (!PerModule) {
Record.push_back(AI.MIBs.size());
Record.push_back(AI.MIBs.size());
if (!PerModule)
Record.push_back(AI.Versions.size());
}
for (auto &MIB : AI.MIBs) {
Record.push_back((uint8_t)MIB.AllocType);
Record.push_back(MIB.StackIdIndices.size());
Expand All @@ -4203,6 +4202,11 @@ static void writeFunctionHeapProfileRecords(
for (auto V : AI.Versions)
Record.push_back(V);
}
assert(AI.TotalSizes.empty() || AI.TotalSizes.size() == AI.MIBs.size());
if (!AI.TotalSizes.empty()) {
for (auto Size : AI.TotalSizes)
Record.push_back(Size);
}
Stream.EmitRecord(PerModule ? bitc::FS_PERMODULE_ALLOC_INFO
: bitc::FS_COMBINED_ALLOC_INFO,
Record, AllocAbbrev);
Expand Down Expand Up @@ -4432,7 +4436,9 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() {

Abbv = std::make_shared<BitCodeAbbrev>();
Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_ALLOC_INFO));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // nummib
// n x (alloc type, numstackids, numstackids x stackidindex)
// optional: nummib x total size
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv));
Expand Down Expand Up @@ -4576,6 +4582,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numver
// nummib x (alloc type, numstackids, numstackids x stackidindex),
// numver x version
// optional: nummib x total size
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv));
Expand Down Expand Up @@ -4675,7 +4682,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
writeFunctionHeapProfileRecords(
Stream, FS, CallsiteAbbrev, AllocAbbrev,
/*PerModule*/ false,
/*GetValueId*/ [&](const ValueInfo &VI) -> unsigned {
/*GetValueId*/
[&](const ValueInfo &VI) -> unsigned {
std::optional<unsigned> ValueID = GetValueId(VI);
// This can happen in shared index files for distributed ThinLTO if
// the callee function summary is not included. Record 0 which we
Expand All @@ -4685,7 +4693,8 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
return 0;
return *ValueID;
},
/*GetStackIndex*/ [&](unsigned I) {
/*GetStackIndex*/
[&](unsigned I) {
// Get the corresponding index into the list of StackIds actually
// being written for this combined index (which may be a subset in
// the case of distributed indexes).
Expand Down
17 changes: 8 additions & 9 deletions llvm/lib/CodeGen/TargetLoweringBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,17 @@ void TargetLoweringBase::InitLibcalls(const Triple &TT) {
}
break;
case Triple::IOS:
case Triple::TvOS:
case Triple::WatchOS:
case Triple::XROS:
if (!TT.isWatchOS() &&
(TT.isOSVersionLT(7, 0) || (TT.isOSVersionLT(9, 0) && TT.isX86()))) {
if (TT.isOSVersionLT(7, 0)) {
setLibcallName(RTLIB::EXP10_F32, nullptr);
setLibcallName(RTLIB::EXP10_F64, nullptr);
} else {
setLibcallName(RTLIB::EXP10_F32, "__exp10f");
setLibcallName(RTLIB::EXP10_F64, "__exp10");
break;
}

[[fallthrough]];
case Triple::TvOS:
case Triple::WatchOS:
case Triple::XROS:
setLibcallName(RTLIB::EXP10_F32, "__exp10f");
setLibcallName(RTLIB::EXP10_F64, "__exp10");
break;
default:
break;
Expand Down
21 changes: 13 additions & 8 deletions llvm/lib/ProfileData/InstrProf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -998,18 +998,22 @@ uint64_t InstrProfRecord::remapValue(uint64_t Value, uint32_t ValueKind,
}

void InstrProfRecord::addValueData(uint32_t ValueKind, uint32_t Site,
InstrProfValueData *VData, uint32_t N,
ArrayRef<InstrProfValueData> VData,
InstrProfSymtab *ValueMap) {
for (uint32_t I = 0; I < N; I++) {
VData[I].Value = remapValue(VData[I].Value, ValueKind, ValueMap);
// Remap values.
std::vector<InstrProfValueData> RemappedVD;
RemappedVD.reserve(VData.size());
for (const auto &V : VData) {
uint64_t NewValue = remapValue(V.Value, ValueKind, ValueMap);
RemappedVD.push_back({NewValue, V.Count});
}

std::vector<InstrProfValueSiteRecord> &ValueSites =
getOrCreateValueSitesForKind(ValueKind);
assert(ValueSites.size() == Site);
if (N == 0)
ValueSites.emplace_back();
else
ValueSites.emplace_back(VData, VData + N);

// Add a new value site with remapped value profiling data.
ValueSites.emplace_back(std::move(RemappedVD));
}

void TemporalProfTraceTy::createBPFunctionNodes(
Expand Down Expand Up @@ -1143,7 +1147,8 @@ void ValueProfRecord::deserializeTo(InstrProfRecord &Record,
InstrProfValueData *ValueData = getValueProfRecordValueData(this);
for (uint64_t VSite = 0; VSite < NumValueSites; ++VSite) {
uint8_t ValueDataCount = this->SiteCountArray[VSite];
Record.addValueData(Kind, VSite, ValueData, ValueDataCount, SymTab);
ArrayRef<InstrProfValueData> VDs(ValueData, ValueDataCount);
Record.addValueData(Kind, VSite, VDs, SymTab);
ValueData += ValueDataCount;
}
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/ProfileData/InstrProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,8 @@ TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
CurrentValues.push_back({Value, TakenCount});
Line++;
}
Record.addValueData(ValueKind, S, CurrentValues.data(), NumValueData,
nullptr);
assert(CurrentValues.size() == NumValueData);
Record.addValueData(ValueKind, S, CurrentValues, nullptr);
}
}
return success();
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17740,6 +17740,12 @@ AArch64TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
!(Divisor.isPowerOf2() || Divisor.isNegatedPowerOf2()))
return SDValue();

// If the divisor is 2 or -2, the default expansion is better. It will add
// (N->getValueType(0) >> (BitWidth - 1)) to it before shifting right.
if (Divisor == 2 ||
Divisor == APInt(Divisor.getBitWidth(), -2, /*isSigned*/ true))
return SDValue();

return TargetLowering::buildSDIVPow2WithCMov(N, Divisor, DAG, Created);
}

Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void AArch64PointerAuth::signLR(MachineFunction &MF,
auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
bool UseBKey = MFnI.shouldSignWithBKey();
bool EmitCFI = MFnI.needsDwarfUnwindInfo(MF);
bool EmitAsyncCFI = MFnI.needsAsyncDwarfUnwindInfo(MF);
bool NeedsWinCFI = MF.hasWinCFI();

MachineBasicBlock &MBB = *MBBI->getParent();
Expand Down Expand Up @@ -137,6 +138,18 @@ void AArch64PointerAuth::signLR(MachineFunction &MF,
}

if (EmitCFI) {
if (!EmitAsyncCFI) {
// Reduce the size of the generated call frame information for synchronous
// CFI by bundling the new CFI instruction with others in the prolog, so
// that no additional DW_CFA_advance_loc is needed.
for (auto I = MBBI; I != MBB.end(); ++I) {
if (I->getOpcode() == TargetOpcode::CFI_INSTRUCTION &&
I->getFlag(MachineInstr::FrameSetup)) {
MBBI = I;
break;
}
}
}
unsigned CFIIndex =
MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
Expand Down
59 changes: 17 additions & 42 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5321,67 +5321,42 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
return convertFromScalableVector(VT, Gather, DAG, Subtarget);
}

// By default we preserve the original operand order, and use a mask to
// select LHS as true and RHS as false. However, since RVV vector selects may
// feature splats but only on the LHS, we may choose to invert our mask and
// instead select between RHS and LHS.
bool SwapOps = DAG.isSplatValue(V2) && !DAG.isSplatValue(V1);

// Detect shuffles which can be re-expressed as vector selects; these are
// shuffles in which each element in the destination is taken from an element
// at the corresponding index in either source vectors.
bool IsSelect = all_of(enumerate(Mask), [&](const auto &MaskIdx) {
int MaskIndex = MaskIdx.value();
return MaskIndex < 0 || MaskIdx.index() == (unsigned)MaskIndex % NumElts;
});
if (IsSelect) {
// Now construct the mask that will be used by the vselect operation.
SmallVector<SDValue> MaskVals;
for (int MaskIndex : Mask) {
bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ SwapOps;
MaskVals.push_back(DAG.getConstant(SelectMaskVal, DL, XLenVT));
}

if (SwapOps)
std::swap(V1, V2);

assert(MaskVals.size() == NumElts && "Unexpected select-like shuffle");
MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
SDValue SelectMask = DAG.getBuildVector(MaskVT, DL, MaskVals);
return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, V1, V2);
}

// As a backup, shuffles can be lowered via a vrgather instruction, possibly
// merged with a second vrgather.
SmallVector<int> ShuffleMaskLHS, ShuffleMaskRHS;
SmallVector<SDValue> MaskVals;

// Now construct the mask that will be used by the blended vrgather operation.
// Cconstruct the appropriate indices into each vector.
// Construct the appropriate indices into each vector.
for (int MaskIndex : Mask) {
bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
MaskVals.push_back(DAG.getConstant(SelectMaskVal, DL, XLenVT));
bool IsLHSOrUndefIndex = MaskIndex < (int)NumElts;
ShuffleMaskLHS.push_back(IsLHSOrUndefIndex && MaskIndex >= 0
? MaskIndex : -1);
ShuffleMaskRHS.push_back(IsLHSOrUndefIndex ? -1 : (MaskIndex - NumElts));
}

if (SwapOps) {
std::swap(V1, V2);
std::swap(ShuffleMaskLHS, ShuffleMaskRHS);
}

assert(MaskVals.size() == NumElts && "Unexpected select-like shuffle");
MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
SDValue SelectMask = DAG.getBuildVector(MaskVT, DL, MaskVals);
// Try to pick a profitable operand order.
bool SwapOps = DAG.isSplatValue(V2) && !DAG.isSplatValue(V1);
SwapOps = SwapOps ^ ShuffleVectorInst::isIdentityMask(ShuffleMaskRHS, NumElts);

// Recursively invoke lowering for each operand if we had two
// independent single source shuffles, and then combine the result via a
// vselect. Note that the vselect will likely be folded back into the
// second permute (vrgather, or other) by the post-isel combine.
V1 = DAG.getVectorShuffle(VT, DL, V1, DAG.getUNDEF(VT), ShuffleMaskLHS);
V2 = DAG.getVectorShuffle(VT, DL, V2, DAG.getUNDEF(VT), ShuffleMaskRHS);

SmallVector<SDValue> MaskVals;
for (int MaskIndex : Mask) {
bool SelectMaskVal = (MaskIndex < (int)NumElts) ^ !SwapOps;
MaskVals.push_back(DAG.getConstant(SelectMaskVal, DL, XLenVT));
}

assert(MaskVals.size() == NumElts && "Unexpected select-like shuffle");
MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
SDValue SelectMask = DAG.getBuildVector(MaskVT, DL, MaskVals);

if (SwapOps)
return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, V1, V2);
return DAG.getNode(ISD::VSELECT, DL, VT, SelectMask, V2, V1);
}

Expand Down
83 changes: 68 additions & 15 deletions llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ cl::opt<bool> SupportsHotColdNew(
cl::desc("Linking with hot/cold operator new interfaces"));
} // namespace llvm

extern cl::opt<bool> MemProfReportHintedSizes;

namespace {
/// CRTP base for graphs built from either IR or ThinLTO summary index.
///
Expand Down Expand Up @@ -172,6 +174,7 @@ class CallsiteContextGraph {

void dump() const;
void print(raw_ostream &OS) const;
void printTotalSizes(raw_ostream &OS) const;

friend raw_ostream &operator<<(raw_ostream &OS,
const CallsiteContextGraph &CCG) {
Expand Down Expand Up @@ -439,7 +442,7 @@ class CallsiteContextGraph {
void addStackNodesForMIB(ContextNode *AllocNode,
CallStack<NodeT, IteratorT> &StackContext,
CallStack<NodeT, IteratorT> &CallsiteContext,
AllocationType AllocType);
AllocationType AllocType, uint64_t TotalSize);

/// Matches all callsite metadata (or summary) to the nodes created for
/// allocation memprof MIB metadata, synthesizing new nodes to reflect any
Expand Down Expand Up @@ -611,6 +614,10 @@ class CallsiteContextGraph {
/// Map from each context ID to the AllocationType assigned to that context.
DenseMap<uint32_t, AllocationType> ContextIdToAllocationType;

/// Map from each contextID to the profiled aggregate allocation size,
/// optionally populated when requested (via MemProfReportHintedSizes).
DenseMap<uint32_t, uint64_t> ContextIdToTotalSize;

/// Identifies the context node created for a stack id when adding the MIB
/// contexts to the graph. This is used to locate the context nodes when
/// trying to assign the corresponding callsites with those stack ids to these
Expand Down Expand Up @@ -1004,18 +1011,36 @@ CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::addAllocNode(
return AllocNode;
}

static std::string getAllocTypeString(uint8_t AllocTypes) {
if (!AllocTypes)
return "None";
std::string Str;
if (AllocTypes & (uint8_t)AllocationType::NotCold)
Str += "NotCold";
if (AllocTypes & (uint8_t)AllocationType::Cold)
Str += "Cold";
return Str;
}

template <typename DerivedCCG, typename FuncTy, typename CallTy>
template <class NodeT, class IteratorT>
void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::addStackNodesForMIB(
ContextNode *AllocNode, CallStack<NodeT, IteratorT> &StackContext,
CallStack<NodeT, IteratorT> &CallsiteContext, AllocationType AllocType) {
CallStack<NodeT, IteratorT> &CallsiteContext, AllocationType AllocType,
uint64_t TotalSize) {
assert(!MemProfReportHintedSizes || TotalSize > 0);
// Treating the hot alloc type as NotCold before the disambiguation for "hot"
// is done.
if (AllocType == AllocationType::Hot)
AllocType = AllocationType::NotCold;

ContextIdToAllocationType[++LastContextId] = AllocType;

if (MemProfReportHintedSizes) {
assert(TotalSize);
ContextIdToTotalSize[LastContextId] = TotalSize;
}

// Update alloc type and context ids for this MIB.
AllocNode->AllocTypes |= (uint8_t)AllocType;

Expand Down Expand Up @@ -1060,6 +1085,10 @@ CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::duplicateContextIds(
assert(ContextIdToAllocationType.count(OldId));
// The new context has the same allocation type as original.
ContextIdToAllocationType[LastContextId] = ContextIdToAllocationType[OldId];
// For now set this to 0 so we don't duplicate sizes. Not clear how to divvy
// up the size. Assume that if we are able to duplicate context ids that we
// will be able to disambiguate all copies.
ContextIdToTotalSize[LastContextId] = 0;
}
return NewContextIds;
}
Expand Down Expand Up @@ -1663,7 +1692,7 @@ ModuleCallsiteContextGraph::ModuleCallsiteContextGraph(
CallStack<MDNode, MDNode::op_iterator> StackContext(StackNode);
addStackNodesForMIB<MDNode, MDNode::op_iterator>(
AllocNode, StackContext, CallsiteContext,
getMIBAllocType(MIBMD));
getMIBAllocType(MIBMD), getMIBTotalSize(MIBMD));
}
assert(AllocNode->AllocTypes != (uint8_t)AllocationType::None);
// Memprof and callsite metadata on memory allocations no longer
Expand Down Expand Up @@ -1735,12 +1764,20 @@ IndexCallsiteContextGraph::IndexCallsiteContextGraph(
// stack ids on the allocation call during ModuleSummaryAnalysis.
CallStack<MIBInfo, SmallVector<unsigned>::const_iterator>
EmptyContext;
unsigned I = 0;
assert(!MemProfReportHintedSizes ||
AN.TotalSizes.size() == AN.MIBs.size());
// Now add all of the MIBs and their stack nodes.
for (auto &MIB : AN.MIBs) {
CallStack<MIBInfo, SmallVector<unsigned>::const_iterator>
StackContext(&MIB);
uint64_t TotalSize = 0;
if (MemProfReportHintedSizes)
TotalSize = AN.TotalSizes[I];
addStackNodesForMIB<MIBInfo, SmallVector<unsigned>::const_iterator>(
AllocNode, StackContext, EmptyContext, MIB.AllocType);
AllocNode, StackContext, EmptyContext, MIB.AllocType,
TotalSize);
I++;
}
assert(AllocNode->AllocTypes != (uint8_t)AllocationType::None);
// Initialize version 0 on the summary alloc node to the current alloc
Expand Down Expand Up @@ -2171,17 +2208,6 @@ bool IndexCallsiteContextGraph::calleeMatchesFunc(
return true;
}

static std::string getAllocTypeString(uint8_t AllocTypes) {
if (!AllocTypes)
return "None";
std::string Str;
if (AllocTypes & (uint8_t)AllocationType::NotCold)
Str += "NotCold";
if (AllocTypes & (uint8_t)AllocationType::Cold)
Str += "Cold";
return Str;
}

template <typename DerivedCCG, typename FuncTy, typename CallTy>
void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::ContextNode::dump()
const {
Expand Down Expand Up @@ -2261,6 +2287,30 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::print(
}
}

template <typename DerivedCCG, typename FuncTy, typename CallTy>
void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::printTotalSizes(
raw_ostream &OS) const {
using GraphType = const CallsiteContextGraph<DerivedCCG, FuncTy, CallTy> *;
for (const auto Node : nodes<GraphType>(this)) {
if (Node->isRemoved())
continue;
if (!Node->IsAllocation)
continue;
DenseSet<uint32_t> ContextIds = Node->getContextIds();
std::vector<uint32_t> SortedIds(ContextIds.begin(), ContextIds.end());
std::sort(SortedIds.begin(), SortedIds.end());
for (auto Id : SortedIds) {
auto SizeI = ContextIdToTotalSize.find(Id);
assert(SizeI != ContextIdToTotalSize.end());
auto TypeI = ContextIdToAllocationType.find(Id);
assert(TypeI != ContextIdToAllocationType.end());
OS << getAllocTypeString((uint8_t)TypeI->second) << " context " << Id
<< " with total size " << SizeI->second << " is "
<< getAllocTypeString(Node->AllocTypes) << " after cloning\n";
}
}
}

template <typename DerivedCCG, typename FuncTy, typename CallTy>
void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::check() const {
using GraphType = const CallsiteContextGraph<DerivedCCG, FuncTy, CallTy> *;
Expand Down Expand Up @@ -3797,6 +3847,9 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::process() {
if (ExportToDot)
exportToDot("clonefuncassign");

if (MemProfReportHintedSizes)
printTotalSizes(errs());

return Changed;
}

Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7332,8 +7332,9 @@ InstructionCost LoopVectorizationPlanner::cost(VPlan &Plan,
Cost += CostCtx.getLegacyCost(CondI, VF);
for (Value *Op : CondI->operands()) {
auto *OpI = dyn_cast<Instruction>(Op);
if (!OpI || any_of(OpI->users(), [&ExitInstrs](User *U) {
return !ExitInstrs.contains(cast<Instruction>(U));
if (!OpI || any_of(OpI->users(), [&ExitInstrs, this](User *U) {
return OrigLoop->contains(cast<Instruction>(U)->getParent()) &&
!ExitInstrs.contains(cast<Instruction>(U));
}))
continue;
ExitInstrs.insert(OpI);
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Bitcode/summary_version.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; RUN: opt -module-summary %s -o - | llvm-bcanalyzer -dump | FileCheck %s

; CHECK: <GLOBALVAL_SUMMARY_BLOCK
; CHECK: <VERSION op0=9/>
; CHECK: <VERSION op0=10/>



Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Bitcode/thinlto-func-summary-vtableref-pgo.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
; RUN: llvm-dis -o - %t.o | llvm-as -o - | llvm-dis -o - | FileCheck %s --check-prefix=DIS

; CHECK: <GLOBALVAL_SUMMARY_BLOCK
; CHECK-NEXT: <VERSION op0=9/>
; CHECK-NEXT: <VERSION op0=
; CHECK-NEXT: <FLAGS op0=0/>
; The `VALUE_GUID` below represents the "_ZTV4Base" referenced by the instruction
; that loads vtable pointers.
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/CodeGen/AArch64/aarch64-bit-gen.ll
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,8 @@ define <4 x i32> @test_bit_sink_operand(<4 x i32> %src, <4 x i32> %dst, <4 x i32
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: sub sp, sp, #32
; CHECK-SD-NEXT: .cfi_def_cfa_offset 32
; CHECK-SD-NEXT: cmp w0, #0
; CHECK-SD-NEXT: add w8, w0, w0, lsr #31
; CHECK-SD-NEXT: mov w9, wzr
; CHECK-SD-NEXT: cinc w8, w0, lt
; CHECK-SD-NEXT: asr w8, w8, #1
; CHECK-SD-NEXT: .LBB11_1: // %do.body
; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
Expand Down
5 changes: 3 additions & 2 deletions llvm/test/CodeGen/AArch64/exp10-libcall-names.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
; RUN: llc -mtriple=aarch64-apple-tvos7.0 < %s | FileCheck -check-prefix=APPLE %s
; RUN: llc -mtriple=aarch64-apple-watchos7.0 < %s | FileCheck -check-prefix=APPLE %s
; RUN: llc -mtriple=aarch64-apple-xros7.0 < %s | FileCheck -check-prefix=APPLE %s
; RUN: llc -mtriple=aarch64-apple-tvos6.0 < %s | FileCheck -check-prefix=APPLE %s
; RUN: llc -mtriple=aarch64-apple-xros6.0 < %s | FileCheck -check-prefix=APPLE %s
; RUN: llc -mtriple=aarch64-apple-xros1.0 < %s | FileCheck -check-prefix=APPLE %s

; RUN: not llc -mtriple=aarch64-apple-macos10.8 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
; RUN: not llc -mtriple=aarch64-apple-ios6.0 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
; RUN: not llc -mtriple=aarch64-apple-tvos6.0 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
; RUN: not llc -mtriple=aarch64-apple-xros6.0 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s

; Check exp10/exp10f is emitted as __exp10/__exp10f on assorted systems.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ define void @a() "sign-return-address"="all" "sign-return-address-key"="b_key" {
; CHECK-NEXT: .cfi_b_key_frame
; V8A-NEXT: hint #27
; V83A-NEXT: pacibsp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ define void @a() "sign-return-address"="all" {
; CHECK-LABEL: a: // @a
; V8A: hint #25
; V83A: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand Down Expand Up @@ -54,7 +55,8 @@ define void @c() "sign-return-address"="all" {
; CHECK-LABEL: c: // @c
; V8A: hint #25
; V83A: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ define i64 @a(i64 %x) "sign-return-address"="non-leaf" "sign-return-address-key"
; CHECK: .cfi_b_key_frame
; V8A-NEXT: hint #27
; V83A-NEXT: pacibsp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand All @@ -30,7 +31,8 @@ define i64 @b(i64 %x) "sign-return-address"="non-leaf" "sign-return-address-key"
; CHECK: .cfi_b_key_frame
; V8A-NEXT: hint #27
; V83A-NEXT: pacibsp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand All @@ -52,7 +54,8 @@ define i64 @c(i64 %x) "sign-return-address"="non-leaf" "sign-return-address-key"
; CHECK: .cfi_b_key_frame
; V8A-NEXT: hint #27
; V83A-NEXT: pacibsp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ body: |
# CHECK: bb.0:
# CHECK: frame-setup EMITBKEY
# CHECK-NEXT: frame-setup PACIBSP implicit-def $lr, implicit $lr, implicit $sp
# CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
# CHECK: frame-setup CFI_INSTRUCTION negate_ra_sign_state
# CHECK-NEXT: frame-setup CFI_INSTRUCTION
# CHECK-NOT: OUTLINED_FUNCTION_
# CHECK: bb.1:
# CHECK-NOT: OUTLINED_FUNCTION_
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ define void @a() "sign-return-address"="all" {
; CHECK-LABEL: a: // @a
; V8A: hint #25
; V83A: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand All @@ -31,7 +32,8 @@ define void @b() "sign-return-address"="all" "sign-return-address-key"="b_key" {
; CHECK: .cfi_b_key_frame
; V8A-NEXT: hint #27
; V83A-NEXT: pacibsp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand All @@ -55,7 +57,8 @@ define void @c() "sign-return-address"="all" {
; CHECK-LABEL: c: // @c
; V8A: hint #25
; V83A: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = alloca i32, align 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ define void @a() #0 {
; CHECK: // %bb.0:
; CHECK-NEXT: .cfi_b_key_frame
; CHECK-NEXT: pacibsp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
; CHECK-NOT: OUTLINED_FUNCTION_
%1 = alloca i32, align 4
%2 = alloca i32, align 4
Expand All @@ -34,7 +35,8 @@ define void @b() #0 {
; CHECK: // %bb.0:
; CHECK-NEXT: .cfi_b_key_frame
; CHECK-NEXT: pacibsp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
; CHECK-NOT: OUTLINED_FUNCTION_
%1 = alloca i32, align 4
%2 = alloca i32, align 4
Expand All @@ -58,7 +60,8 @@ define void @c() #1 {
; CHECK: // %bb.0:
; CHECK-NEXT: .cfi_b_key_frame
; CHECK-NEXT: hint #27
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
; CHECK-NOT: OUTLINED_FUNCTION_
%1 = alloca i32, align 4
%2 = alloca i32, align 4
Expand Down
12 changes: 8 additions & 4 deletions llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-thunk.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ define i32 @a() #0 {
; CHECK: // %bb.0: // %entry
; V8A-NEXT: hint #25
; V83A-NEXT: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
; V8A: hint #29
; V8A-NEXT: ret
; V83A: retaa
Expand All @@ -26,7 +27,8 @@ define i32 @b() #0 {
; CHECK: // %bb.0: // %entry
; V8A-NEXT: hint #25
; V83A-NEXT: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
; V8A: hint #29
; V8A-NEXT: ret
; V83A: retaa
Expand All @@ -41,7 +43,8 @@ define hidden i32 @c(ptr %fptr) #0 {
; CHECK: // %bb.0: // %entry
; V8A-NEXT: hint #25
; V83A-NEXT: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
; V8A: hint #29
; V8A-NEXT: ret
; V83A: retaa
Expand All @@ -56,7 +59,8 @@ define hidden i32 @d(ptr %fptr) #0 {
; CHECK: // %bb.0: // %entry
; V8A-NEXT: hint #25
; V83A-NEXT: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset
; V8A: hint #29
; V8A-NEXT: ret
; V83A: retaa
Expand Down
7 changes: 5 additions & 2 deletions llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ entry:
;; CHECK-LABEL: __llvm_gcov_writeout:
;; CHECK: .cfi_b_key_frame
;; CHECK-NEXT: pacibsp
;; CHECK-NEXT: .cfi_negate_ra_state
;; CHECK: .cfi_negate_ra_state
;; CHECK-NEXT: .cfi_def_cfa_offset

define internal void @__llvm_gcov_reset() unnamed_addr #2 {
entry:
Expand All @@ -55,7 +56,9 @@ entry:
;; CHECK-LABEL: __llvm_gcov_init:
;; CHECK: .cfi_b_key_frame
;; CHECK-NEXT: pacibsp
;; CHECK-NEXT: .cfi_negate_ra_state
;; CHECK-NEXT: .cfi_negate_ra_state
;; CHECK-NOT: .cfi_
;; CHECK: .cfi_endproc

attributes #0 = { norecurse nounwind readnone "sign-return-address"="all" "sign-return-address-key"="b_key" }
attributes #1 = { noinline "sign-return-address"="all" "sign-return-address-key"="b_key" }
Expand Down
9 changes: 3 additions & 6 deletions llvm/test/CodeGen/AArch64/sdivpow2.ll
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ define i64 @test7(i64 %x) {
define i64 @test8(i64 %x) {
; ISEL-LABEL: test8:
; ISEL: // %bb.0:
; ISEL-NEXT: cmp x0, #0
; ISEL-NEXT: cinc x8, x0, lt
; ISEL-NEXT: add x8, x0, x0, lsr #63
; ISEL-NEXT: asr x0, x8, #1
; ISEL-NEXT: ret
;
Expand All @@ -110,10 +109,8 @@ define i32 @sdiv_int(i32 %begin, i32 %first) #0 {
; ISEL-LABEL: sdiv_int:
; ISEL: // %bb.0:
; ISEL-NEXT: sub w8, w0, w1
; ISEL-NEXT: add w9, w8, #1
; ISEL-NEXT: add w10, w8, #2
; ISEL-NEXT: cmp w9, #0
; ISEL-NEXT: csinc w8, w10, w8, lt
; ISEL-NEXT: add w8, w8, #1
; ISEL-NEXT: add w8, w8, w8, lsr #31
; ISEL-NEXT: sub w0, w0, w8, asr #1
; ISEL-NEXT: ret
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ define dso_local i32 @_Z3fooi(i32 %x) #0 {
; CHECK-V8A-LABEL: _Z3fooi:
; CHECK-V8A: // %bb.0: // %entry
; CHECK-V8A-NEXT: hint #25
; CHECK-V8A-NEXT: .cfi_negate_ra_state
; CHECK-V8A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-V8A-NEXT: .cfi_negate_ra_state
; CHECK-V8A-NEXT: .cfi_def_cfa_offset 16
; CHECK-V8A-NEXT: .cfi_offset w30, -16
; CHECK-V8A-NEXT: str w0, [sp, #8]
Expand All @@ -28,8 +28,8 @@ define dso_local i32 @_Z3fooi(i32 %x) #0 {
; CHECK-V83A-LABEL: _Z3fooi:
; CHECK-V83A: // %bb.0: // %entry
; CHECK-V83A-NEXT: paciasp
; CHECK-V83A-NEXT: .cfi_negate_ra_state
; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-V83A-NEXT: .cfi_negate_ra_state
; CHECK-V83A-NEXT: .cfi_def_cfa_offset 16
; CHECK-V83A-NEXT: .cfi_offset w30, -16
; CHECK-V83A-NEXT: str w0, [sp, #8]
Expand Down Expand Up @@ -57,7 +57,8 @@ return: ; No predecessors!
}

; For asynchronous unwind tables, we need to flip the value of RA_SIGN_STATE
; before and after the tail call.
; before and after the tail call. In the prolog, RA_SIGN_STATE is updated right
; after the corresponding 'PACIASP' instruction.
define hidden noundef i32 @baz_async(i32 noundef %a) #0 uwtable(async) {
; CHECK-V8A-LABEL: baz_async:
; CHECK-V8A: // %bb.0: // %entry
Expand Down Expand Up @@ -137,12 +138,14 @@ return: ; preds = %if.else, %if.then
; around the tail call. The tail-called function might throw an exception, but
; at this point we are set up to return into baz's caller, so the unwinder will
; never see baz's unwind table for that exception.
; The '.cfi_negate_ra_state' instruction in the prolog can be bundled with other
; CFI instructions to avoid emitting superfluous DW_CFA_advance_loc.
define hidden noundef i32 @baz_sync(i32 noundef %a) #0 uwtable(sync) {
; CHECK-V8A-LABEL: baz_sync:
; CHECK-V8A: // %bb.0: // %entry
; CHECK-V8A-NEXT: hint #25
; CHECK-V8A-NEXT: .cfi_negate_ra_state
; CHECK-V8A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-V8A-NEXT: .cfi_negate_ra_state
; CHECK-V8A-NEXT: .cfi_def_cfa_offset 16
; CHECK-V8A-NEXT: .cfi_offset w30, -16
; CHECK-V8A-NEXT: cbz w0, .LBB2_2
Expand All @@ -162,8 +165,8 @@ define hidden noundef i32 @baz_sync(i32 noundef %a) #0 uwtable(sync) {
; CHECK-V83A-LABEL: baz_sync:
; CHECK-V83A: // %bb.0: // %entry
; CHECK-V83A-NEXT: paciasp
; CHECK-V83A-NEXT: .cfi_negate_ra_state
; CHECK-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-V83A-NEXT: .cfi_negate_ra_state
; CHECK-V83A-NEXT: .cfi_def_cfa_offset 16
; CHECK-V83A-NEXT: .cfi_offset w30, -16
; CHECK-V83A-NEXT: cbz w0, .LBB2_2
Expand Down
28 changes: 14 additions & 14 deletions llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-a
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: .Ltmp1:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: //APP
Expand All @@ -111,8 +111,8 @@ define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-a
; V83A-NEXT: hint #39
; V83A-NEXT: .Ltmp1:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: //APP
Expand All @@ -127,8 +127,8 @@ define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-a
; PAUTHLR: // %bb.0:
; PAUTHLR-NEXT: .Ltmp1:
; PAUTHLR-NEXT: paciasppc
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: .cfi_def_cfa_offset 16
; PAUTHLR-NEXT: .cfi_offset w30, -16
; PAUTHLR-NEXT: //APP
Expand All @@ -148,8 +148,8 @@ define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: .Ltmp2:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: bl foo
Expand All @@ -164,8 +164,8 @@ define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-
; V83A-NEXT: hint #39
; V83A-NEXT: .Ltmp2:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: bl foo
Expand All @@ -178,8 +178,8 @@ define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-
; PAUTHLR: // %bb.0:
; PAUTHLR-NEXT: .Ltmp2:
; PAUTHLR-NEXT: paciasppc
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: .cfi_def_cfa_offset 16
; PAUTHLR-NEXT: .cfi_offset w30, -16
; PAUTHLR-NEXT: bl foo
Expand All @@ -195,8 +195,8 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-re
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: .Ltmp3:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: bl foo
Expand All @@ -211,8 +211,8 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-re
; V83A-NEXT: hint #39
; V83A-NEXT: .Ltmp3:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: bl foo
Expand All @@ -225,8 +225,8 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-re
; PAUTHLR: // %bb.0:
; PAUTHLR-NEXT: .Ltmp3:
; PAUTHLR-NEXT: paciasppc
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: .cfi_def_cfa_offset 16
; PAUTHLR-NEXT: .cfi_offset w30, -16
; PAUTHLR-NEXT: bl foo
Expand All @@ -245,8 +245,8 @@ define i32 @non_leaf_scs(i32 %x) "branch-protection-pauth-lr" "sign-return-addre
; CHECK-NEXT: hint #39
; CHECK-NEXT: .Ltmp4:
; CHECK-NEXT: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: bl foo
Expand All @@ -263,8 +263,8 @@ define i32 @non_leaf_scs(i32 %x) "branch-protection-pauth-lr" "sign-return-addre
; PAUTHLR-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
; PAUTHLR-NEXT: .Ltmp4:
; PAUTHLR-NEXT: paciasppc
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: .cfi_def_cfa_offset 16
; PAUTHLR-NEXT: .cfi_offset w30, -16
; PAUTHLR-NEXT: bl foo
Expand Down Expand Up @@ -304,8 +304,8 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr"
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: .Ltmp6:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: //APP
Expand All @@ -322,8 +322,8 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr"
; V83A-NEXT: hint #39
; V83A-NEXT: .Ltmp6:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: //APP
Expand All @@ -339,8 +339,8 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr"
; PAUTHLR: // %bb.0:
; PAUTHLR-NEXT: .Ltmp6:
; PAUTHLR-NEXT: paciasppc
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT: .cfi_negate_ra_state
; PAUTHLR-NEXT: .cfi_def_cfa_offset 16
; PAUTHLR-NEXT: .cfi_offset w30, -16
; PAUTHLR-NEXT: //APP
Expand Down
18 changes: 9 additions & 9 deletions llvm/test/CodeGen/AArch64/sign-return-address.ll
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" {
; COMPAT-LABEL: leaf_clobbers_lr:
; COMPAT: // %bb.0:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: //APP
Expand All @@ -60,8 +60,8 @@ define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" {
; V83A-LABEL: leaf_clobbers_lr:
; V83A: // %bb.0:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: //APP
Expand All @@ -79,8 +79,8 @@ define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
; COMPAT-LABEL: non_leaf_sign_all:
; COMPAT: // %bb.0:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: bl foo
Expand All @@ -91,8 +91,8 @@ define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
; V83A-LABEL: non_leaf_sign_all:
; V83A: // %bb.0:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: bl foo
Expand All @@ -106,8 +106,8 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
; COMPAT-LABEL: non_leaf_sign_non_leaf:
; COMPAT: // %bb.0:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: bl foo
Expand All @@ -118,8 +118,8 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
; V83A-LABEL: non_leaf_sign_non_leaf:
; V83A: // %bb.0:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: bl foo
Expand All @@ -136,8 +136,8 @@ define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstac
; CHECK-NEXT: str x30, [x18], #8
; CHECK-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
; CHECK-NEXT: paciasp
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT: .cfi_negate_ra_state
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: bl foo
Expand All @@ -164,8 +164,8 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" {
; COMPAT-LABEL: spill_lr_and_tail_call:
; COMPAT: // %bb.0:
; COMPAT-NEXT: hint #25
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT: .cfi_negate_ra_state
; COMPAT-NEXT: .cfi_def_cfa_offset 16
; COMPAT-NEXT: .cfi_offset w30, -16
; COMPAT-NEXT: //APP
Expand All @@ -178,8 +178,8 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" {
; V83A-LABEL: spill_lr_and_tail_call:
; V83A: // %bb.0:
; V83A-NEXT: paciasp
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT: .cfi_negate_ra_state
; V83A-NEXT: .cfi_def_cfa_offset 16
; V83A-NEXT: .cfi_offset w30, -16
; V83A-NEXT: //APP
Expand Down
Loading