From 860affefd94e3ef596f91e44d5f1d8209f82ff1a Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Mon, 25 Oct 2021 13:38:45 -0300 Subject: [PATCH 001/293] [lldb] Add message to functions not worth implementing in tss-typeref --- .../Swift/TypeSystemSwiftTypeRef.cpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 68b9aacea3be8..c9f55f60c44ce 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -2262,6 +2262,10 @@ TypeSystemSwiftTypeRef::GetFunctionReturnType(opaque_compiler_type_t type) { } size_t TypeSystemSwiftTypeRef::GetNumMemberFunctions(opaque_compiler_type_t type) { + // We forward the call to SwiftASTContext because an implementation of + // this function would require it to have an execution context being passed + // in. Given the purpose of TypeSystemSwiftTypeRef, it's unlikely this + // function will be called much. if (auto *swift_ast_context = GetSwiftASTContext()) return swift_ast_context->GetNumMemberFunctions(ReconstructType(type)); return {}; @@ -2269,6 +2273,10 @@ TypeSystemSwiftTypeRef::GetNumMemberFunctions(opaque_compiler_type_t type) { TypeMemberFunctionImpl TypeSystemSwiftTypeRef::GetMemberFunctionAtIndex(opaque_compiler_type_t type, size_t idx) { + // We forward the call to SwiftASTContext because an implementation of + // this function would require it to have an execution context being passed + // in. Given the purpose of TypeSystemSwiftTypeRef, it's unlikely this + // function will be called much. if (auto *swift_ast_context = GetSwiftASTContext()) return swift_ast_context->GetMemberFunctionAtIndex(ReconstructType(type), idx); @@ -2562,6 +2570,10 @@ CompilerType TypeSystemSwiftTypeRef::GetFieldAtIndex( opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) { + // We forward the call to SwiftASTContext because an implementation of + // this function would require it to have an execution context being passed + // in. Given the purpose of TypeSystemSwiftTypeRef, it's unlikely this + // function will be called much. LLDB_SCOPED_TIMER(); if (auto *swift_ast_context = GetSwiftASTContext()) return swift_ast_context->GetFieldAtIndex( @@ -3555,12 +3567,20 @@ TypeSystemSwiftTypeRef::GetRValueReferenceType(opaque_compiler_type_t type) { } uint32_t TypeSystemSwiftTypeRef::GetNumDirectBaseClasses(opaque_compiler_type_t type) { + // We forward the call to SwiftASTContext because an implementation of + // this function would require it to have an execution context being passed + // in. Given the purpose of TypeSystemSwiftTypeRef, it's unlikely this + // function will be called much. if (auto *swift_ast_context = GetSwiftASTContext()) return swift_ast_context->GetNumDirectBaseClasses(ReconstructType(type)); return {}; } CompilerType TypeSystemSwiftTypeRef::GetDirectBaseClassAtIndex( opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { + // We forward the call to SwiftASTContext because an implementation of + // this function would require it to have an execution context being passed + // in. Given the purpose of TypeSystemSwiftTypeRef, it's unlikely this + // function will be called much. if (auto *swift_ast_context = GetSwiftASTContext()) return swift_ast_context->GetDirectBaseClassAtIndex(ReconstructType(type), idx, bit_offset_ptr); From 3c6d4b1e1dd2764f6da8f2c470daaf47c7018277 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Wed, 27 Oct 2021 14:33:28 -0300 Subject: [PATCH 002/293] [lldb] Move DumpSummary implementation to TypeSystemSwift DumpSummary appears to be unused, and it has an empty implementation on SwiftASTContext. Move it to TypeSystemSwift so it's shared to TypeSystemSwiftTypeRef as well. --- .../Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 6 ------ lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h | 6 ------ lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h | 5 +++++ .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 10 ---------- .../Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 4 +--- 5 files changed, 6 insertions(+), 25 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 253279c534767..eb1bc7246ab04 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -8064,12 +8064,6 @@ std::string SwiftASTContext::ImportName(const clang::NamedDecl *clang_decl) { return clang_decl->getName().str(); } -void SwiftASTContext::DumpSummary(opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - const lldb_private::DataExtractor &data, - lldb::offset_t data_byte_offset, - size_t data_byte_size) {} - void SwiftASTContext::DumpTypeDescription(opaque_compiler_type_t type, lldb::DescriptionLevel level) { StreamFile s(stdout, false); diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h index f489a636bd153..88d8bc8fac2b8 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h @@ -709,12 +709,6 @@ class SwiftASTContext : public TypeSystemSwift { bool print_help_if_available, bool print_extensions_if_available, lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; - // TODO: These methods appear unused. Should they be removed? - - void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size) override; - // TODO: Determine if these methods should move to TypeSystemClang. bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h index 0d503071bf51e..855f8431a633e 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h @@ -289,6 +289,11 @@ class TypeSystemSwift : public TypeSystem { return {}; } + // TODO: This method appear unused. Should they be removed? + void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size) override { + } /// \} protected: /// Used in the logs. diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index ddc6729f8078f..ea90075ced565 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -3393,16 +3393,6 @@ void TypeSystemSwiftTypeRef::DumpTypeDescription(opaque_compiler_type_t type, return swift_ast_context->DumpTypeDescription(ReconstructType(type), s, level); } -void TypeSystemSwiftTypeRef::DumpSummary(opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size) { - LLDB_SCOPED_TIMER(); - if (auto *swift_ast_context = GetSwiftASTContext()) - return swift_ast_context->DumpSummary(ReconstructType(type), exe_ctx, s, - data, data_offset, data_byte_size); -} bool TypeSystemSwiftTypeRef::IsPointerOrReferenceType( opaque_compiler_type_t type, CompilerType *pointee_type) { auto impl = [&]() { diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index dc42bdddf500d..b15d8e6a362f1 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -214,9 +214,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { void DumpTypeDescription( lldb::opaque_compiler_type_t type, Stream *s, lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; - void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size) override; + bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type) override; llvm::Optional From 2823377dec7b0484526853005460e1be0b896d93 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 27 Oct 2021 18:15:17 +0100 Subject: [PATCH 003/293] [Clang] Add elementwise abs builtin. This patch implements __builtin_elementwise_abs as specified in D111529. Reviewed By: aaron.ballman, scanon Differential Revision: https://reviews.llvm.org/D111986 (cherry-picked from 01870d51b848) --- clang/include/clang/Basic/Builtins.def | 1 + .../clang/Basic/DiagnosticSemaKinds.td | 3 +- clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 11 +++++ clang/lib/Sema/SemaChecking.cpp | 29 ++++++++++++ .../test/CodeGen/builtins-elementwise-math.c | 44 ++++++++++++++++++- clang/test/Sema/builtins-elementwise-math.c | 21 +++++++++ .../SemaCXX/builtins-elementwise-math.cpp | 7 +++ 8 files changed, 115 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index 424de348dd2fe..7616c3e11e084 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -645,6 +645,7 @@ BUILTIN(__builtin_alloca, "v*z" , "Fn") BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn") BUILTIN(__builtin_call_with_static_chain, "v.", "nt") +BUILTIN(__builtin_elementwise_abs, "v.", "nct") BUILTIN(__builtin_elementwise_max, "v.", "nct") BUILTIN(__builtin_elementwise_min, "v.", "nct") diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 660716ddd1929..7d9633a3ca43c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11355,7 +11355,8 @@ def err_builtin_launder_invalid_arg : Error< def err_builtin_invalid_arg_type: Error < "%ordinal0 argument must be a " "%select{vector, integer or floating point type|matrix|" - "pointer to a valid matrix element type}1 (was %2)">; + "pointer to a valid matrix element type|" + "signed integer or floating point type}1 (was %2)">; def err_builtin_matrix_disabled: Error< "matrix types extension is disabled. Pass -fenable-matrix to enable it">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 334edaf931914..ecde9c2feb982 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12679,6 +12679,7 @@ class Sema final { bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc); bool SemaBuiltinElementwiseMath(CallExpr *TheCall); + bool SemaBuiltinElementwiseMathOneArg(CallExpr *TheCall); // Matrix builtin handling. ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall, diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 61743c5cd062b..84a78083d4cf9 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3101,6 +3101,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(V); } + case Builtin::BI__builtin_elementwise_abs: { + Value *Op0 = EmitScalarExpr(E->getArg(0)); + Value *Result; + if (Op0->getType()->isIntOrIntVectorTy()) + Result = Builder.CreateBinaryIntrinsic( + llvm::Intrinsic::abs, Op0, Builder.getFalse(), nullptr, "elt.abs"); + else + Result = Builder.CreateUnaryIntrinsic(llvm::Intrinsic::fabs, Op0, nullptr, + "elt.abs"); + return RValue::get(Result); + } case Builtin::BI__builtin_elementwise_max: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 20ec2c84fa1ba..05344d91afc50 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2288,6 +2288,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, break; } + case Builtin::BI__builtin_elementwise_abs: + if (SemaBuiltinElementwiseMathOneArg(TheCall)) + return ExprError(); + break; case Builtin::BI__builtin_elementwise_min: case Builtin::BI__builtin_elementwise_max: if (SemaBuiltinElementwiseMath(TheCall)) @@ -16755,6 +16759,31 @@ static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, return false; } +bool Sema::SemaBuiltinElementwiseMathOneArg(CallExpr *TheCall) { + if (checkArgCount(*this, TheCall, 1)) + return true; + + ExprResult A = UsualUnaryConversions(TheCall->getArg(0)); + SourceLocation ArgLoc = TheCall->getArg(0)->getBeginLoc(); + if (A.isInvalid()) + return true; + + TheCall->setArg(0, A.get()); + QualType TyA = A.get()->getType(); + if (checkMathBuiltinElementType(*this, ArgLoc, TyA)) + return true; + + QualType EltTy = TyA; + if (auto *VecTy = EltTy->getAs()) + EltTy = VecTy->getElementType(); + if (EltTy->isUnsignedIntegerType()) + return Diag(ArgLoc, diag::err_builtin_invalid_arg_type) + << 1 << /*signed integer or float ty*/ 3 << TyA; + + TheCall->setType(TyA); + return false; +} + bool Sema::SemaBuiltinElementwiseMath(CallExpr *TheCall) { if (checkArgCount(*this, TheCall, 2)) return true; diff --git a/clang/test/CodeGen/builtins-elementwise-math.c b/clang/test/CodeGen/builtins-elementwise-math.c index e930039879b79..bfb162422c1b5 100644 --- a/clang/test/CodeGen/builtins-elementwise-math.c +++ b/clang/test/CodeGen/builtins-elementwise-math.c @@ -8,12 +8,54 @@ __attribute__((address_space(1))) int int_as_one; typedef int bar; bar b; +void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2, + float4 vf1, float4 vf2, si8 vi1, si8 vi2, + long long int i1, long long int i2, short si) { + // CHECK-LABEL: define void @test_builtin_elementwise_abs( + // CHECK: [[F1:%.+]] = load float, float* %f1.addr, align 4 + // CHECK-NEXT: call float @llvm.fabs.f32(float [[F1]]) + f2 = __builtin_elementwise_abs(f1); + + // CHECK: [[D1:%.+]] = load double, double* %d1.addr, align 8 + // CHECK-NEXT: call double @llvm.fabs.f64(double [[D1]]) + d2 = __builtin_elementwise_abs(d1); + + // CHECK: [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16 + // CHECK-NEXT: call <4 x float> @llvm.fabs.v4f32(<4 x float> [[VF1]]) + vf2 = __builtin_elementwise_abs(vf1); + + // CHECK: [[I1:%.+]] = load i64, i64* %i1.addr, align 8 + // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false) + i2 = __builtin_elementwise_abs(i1); + + // CHECK: [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16 + // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false) + vi2 = __builtin_elementwise_abs(vi1); + + // CHECK: [[CVI2:%.+]] = load <8 x i16>, <8 x i16>* %cvi2, align 16 + // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[CVI2]], i1 false) + const si8 cvi2 = vi2; + vi2 = __builtin_elementwise_abs(cvi2); + + // CHECK: [[IA1:%.+]] = load i32, i32 addrspace(1)* @int_as_one, align 4 + // CHECK-NEXT: call i32 @llvm.abs.i32(i32 [[IA1]], i1 false) + b = __builtin_elementwise_abs(int_as_one); + + // CHECK: call i32 @llvm.abs.i32(i32 -10, i1 false) + b = __builtin_elementwise_abs(-10); + + // CHECK: [[SI:%.+]] = load i16, i16* %si.addr, align 2 + // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32 + // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.abs.i32(i32 [[SI_EXT]], i1 false) + // CHECK-NEXT: = trunc i32 [[RES]] to i16 + si = __builtin_elementwise_abs(si); +} + void test_builtin_elementwise_max(float f1, float f2, double d1, double d2, float4 vf1, float4 vf2, long long int i1, long long int i2, si8 vi1, si8 vi2, unsigned u1, unsigned u2, u4 vu1, u4 vu2) { // CHECK-LABEL: define void @test_builtin_elementwise_max( - // CHECK: [[F1:%.+]] = load float, float* %f1.addr, align 4 // CHECK-NEXT: [[F2:%.+]] = load float, float* %f2.addr, align 4 // CHECK-NEXT: call float @llvm.maxnum.f32(float %0, float %1) diff --git a/clang/test/Sema/builtins-elementwise-math.c b/clang/test/Sema/builtins-elementwise-math.c index 7c3c1aa0763a7..1825d0c684965 100644 --- a/clang/test/Sema/builtins-elementwise-math.c +++ b/clang/test/Sema/builtins-elementwise-math.c @@ -2,6 +2,7 @@ typedef float float4 __attribute__((ext_vector_type(4))); typedef int int3 __attribute__((ext_vector_type(3))); +typedef unsigned unsigned4 __attribute__((ext_vector_type(4))); struct Foo { char *p; @@ -11,6 +12,26 @@ __attribute__((address_space(1))) int int_as_one; typedef int bar; bar b; +void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u, unsigned4 uv) { + struct Foo s = __builtin_elementwise_abs(i); + // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}} + + i = __builtin_elementwise_abs(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} + + i = __builtin_elementwise_abs(i, i); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} + + i = __builtin_elementwise_abs(v); + // expected-error@-1 {{assigning to 'int' from incompatible type 'float4' (vector of 4 'float' values)}} + + u = __builtin_elementwise_abs(u); + // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned int')}} + + uv = __builtin_elementwise_abs(uv); + // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}} +} + void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, int *p) { i = __builtin_elementwise_max(p, d); // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}} diff --git a/clang/test/SemaCXX/builtins-elementwise-math.cpp b/clang/test/SemaCXX/builtins-elementwise-math.cpp index 4d552b7a17d05..fcf03d729620b 100644 --- a/clang/test/SemaCXX/builtins-elementwise-math.cpp +++ b/clang/test/SemaCXX/builtins-elementwise-math.cpp @@ -14,6 +14,13 @@ template struct is_const : true_type {}; // expected-no-diagnostics +void test_builtin_elementwise_abs() { + const int a = 2; + int b = 1; + static_assert(!is_const::value); + static_assert(!is_const::value); +} + void test_builtin_elementwise_max() { const int a = 2; int b = 1; From 8cf06001ed14905de0e4fd0ad91e47143d0f695c Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 2 Nov 2021 15:01:41 +0100 Subject: [PATCH 004/293] [Clang] Add min/max reduction builtins. This patch implements __builtin_reduce_max and __builtin_reduce_min as specified in D111529. The order of operations does not matter for min or max reductions and they can be directly lowered to the corresponding llvm.vector.reduce.{fmin,fmax,umin,umax,smin,smax} intrinsic calls. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D112001 (cherry-picked from 7999355106fb) --- clang/include/clang/Basic/Builtins.def | 2 + .../clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 38 ++++++++++++ clang/lib/Sema/SemaChecking.cpp | 25 ++++++++ clang/test/CodeGen/builtins-reduction-math.c | 59 +++++++++++++++++++ clang/test/Sema/builtins-reduction-math.c | 37 ++++++++++++ 7 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGen/builtins-reduction-math.c create mode 100644 clang/test/Sema/builtins-reduction-math.c diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index 7616c3e11e084..cfdb0418e23c4 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -648,6 +648,8 @@ BUILTIN(__builtin_call_with_static_chain, "v.", "nt") BUILTIN(__builtin_elementwise_abs, "v.", "nct") BUILTIN(__builtin_elementwise_max, "v.", "nct") BUILTIN(__builtin_elementwise_min, "v.", "nct") +BUILTIN(__builtin_reduce_max, "v.", "nct") +BUILTIN(__builtin_reduce_min, "v.", "nct") BUILTIN(__builtin_matrix_transpose, "v.", "nFt") BUILTIN(__builtin_matrix_column_major_load, "v.", "nFt") diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7d9633a3ca43c..cb48cdc788a37 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11356,7 +11356,7 @@ def err_builtin_invalid_arg_type: Error < "%ordinal0 argument must be a " "%select{vector, integer or floating point type|matrix|" "pointer to a valid matrix element type|" - "signed integer or floating point type}1 (was %2)">; + "signed integer or floating point type|vector type}1 (was %2)">; def err_builtin_matrix_disabled: Error< "matrix types extension is disabled. Pass -fenable-matrix to enable it">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ecde9c2feb982..43fa140dfc778 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12680,6 +12680,7 @@ class Sema final { bool SemaBuiltinElementwiseMath(CallExpr *TheCall); bool SemaBuiltinElementwiseMathOneArg(CallExpr *TheCall); + bool SemaBuiltinReduceMath(CallExpr *TheCall); // Matrix builtin handling. ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall, diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 84a78083d4cf9..c07bbb6eca494 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3145,6 +3145,44 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(Result); } + case Builtin::BI__builtin_reduce_max: { + auto GetIntrinsicID = [](QualType QT, llvm::Type *IrTy) { + if (IrTy->isIntOrIntVectorTy()) { + if (auto *VecTy = QT->getAs()) + QT = VecTy->getElementType(); + if (QT->isSignedIntegerType()) + return llvm::Intrinsic::vector_reduce_smax; + else + return llvm::Intrinsic::vector_reduce_umax; + } + return llvm::Intrinsic::vector_reduce_fmax; + }; + Value *Op0 = EmitScalarExpr(E->getArg(0)); + Value *Result = Builder.CreateUnaryIntrinsic( + GetIntrinsicID(E->getArg(0)->getType(), Op0->getType()), Op0, nullptr, + "rdx.min"); + return RValue::get(Result); + } + + case Builtin::BI__builtin_reduce_min: { + auto GetIntrinsicID = [](QualType QT, llvm::Type *IrTy) { + if (IrTy->isIntOrIntVectorTy()) { + if (auto *VecTy = QT->getAs()) + QT = VecTy->getElementType(); + if (QT->isSignedIntegerType()) + return llvm::Intrinsic::vector_reduce_smin; + else + return llvm::Intrinsic::vector_reduce_umin; + } + return llvm::Intrinsic::vector_reduce_fmin; + }; + Value *Op0 = EmitScalarExpr(E->getArg(0)); + Value *Result = Builder.CreateUnaryIntrinsic( + GetIntrinsicID(E->getArg(0)->getType(), Op0->getType()), Op0, nullptr, + "rdx.min"); + return RValue::get(Result); + } + case Builtin::BI__builtin_matrix_transpose: { const auto *MatrixTy = E->getArg(0)->getType()->getAs(); Value *MatValue = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 05344d91afc50..60f05d88d409e 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2297,6 +2297,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (SemaBuiltinElementwiseMath(TheCall)) return ExprError(); break; + case Builtin::BI__builtin_reduce_max: + case Builtin::BI__builtin_reduce_min: + if (SemaBuiltinReduceMath(TheCall)) + return ExprError(); + break; case Builtin::BI__builtin_matrix_transpose: return SemaBuiltinMatrixTranspose(TheCall, TheCallResult); @@ -16814,6 +16819,26 @@ bool Sema::SemaBuiltinElementwiseMath(CallExpr *TheCall) { return false; } +bool Sema::SemaBuiltinReduceMath(CallExpr *TheCall) { + if (checkArgCount(*this, TheCall, 1)) + return true; + + ExprResult A = UsualUnaryConversions(TheCall->getArg(0)); + if (A.isInvalid()) + return true; + + TheCall->setArg(0, A.get()); + const VectorType *TyA = A.get()->getType()->getAs(); + if (!TyA) { + SourceLocation ArgLoc = TheCall->getArg(0)->getBeginLoc(); + return Diag(ArgLoc, diag::err_builtin_invalid_arg_type) + << 1 << /* vector ty*/ 4 << A.get()->getType(); + } + + TheCall->setType(TyA->getElementType()); + return false; +} + ExprResult Sema::SemaBuiltinMatrixTranspose(CallExpr *TheCall, ExprResult CallResult) { if (checkArgCount(*this, TheCall, 1)) diff --git a/clang/test/CodeGen/builtins-reduction-math.c b/clang/test/CodeGen/builtins-reduction-math.c new file mode 100644 index 0000000000000..417caed494d90 --- /dev/null +++ b/clang/test/CodeGen/builtins-reduction-math.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +typedef float float4 __attribute__((ext_vector_type(4))); +typedef short int si8 __attribute__((ext_vector_type(8))); +typedef unsigned int u4 __attribute__((ext_vector_type(4))); + +__attribute__((address_space(1))) float4 vf1_as_one; + +void test_builtin_reduce_max(float4 vf1, si8 vi1, u4 vu1) { + // CHECK-LABEL: define void @test_builtin_reduce_max( + // CHECK: [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16 + // CHECK-NEXT: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1]]) + float r1 = __builtin_reduce_max(vf1); + + // CHECK: [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16 + // CHECK-NEXT: call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[VI1]]) + short r2 = __builtin_reduce_max(vi1); + + // CHECK: [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16 + // CHECK-NEXT: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[VU1]]) + unsigned r3 = __builtin_reduce_max(vu1); + + // CHECK: [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16 + // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> [[VF1_AS1]]) + // CHECK-NEXT: fpext float [[RDX1]] to double + const double r4 = __builtin_reduce_max(vf1_as_one); + + // CHECK: [[CVI1:%.+]] = load <8 x i16>, <8 x i16>* %cvi1, align 16 + // CHECK-NEXT: [[RDX2:%.+]] = call i16 @llvm.vector.reduce.smax.v8i16(<8 x i16> [[CVI1]]) + // CHECK-NEXT: sext i16 [[RDX2]] to i64 + const si8 cvi1 = vi1; + unsigned long long r5 = __builtin_reduce_max(cvi1); +} + +void test_builtin_reduce_min(float4 vf1, si8 vi1, u4 vu1) { + // CHECK-LABEL: define void @test_builtin_reduce_min( + // CHECK: [[VF1:%.+]] = load <4 x float>, <4 x float>* %vf1.addr, align 16 + // CHECK-NEXT: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1]]) + float r1 = __builtin_reduce_min(vf1); + + // CHECK: [[VI1:%.+]] = load <8 x i16>, <8 x i16>* %vi1.addr, align 16 + // CHECK-NEXT: call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[VI1]]) + short r2 = __builtin_reduce_min(vi1); + + // CHECK: [[VU1:%.+]] = load <4 x i32>, <4 x i32>* %vu1.addr, align 16 + // CHECK-NEXT: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[VU1]]) + unsigned r3 = __builtin_reduce_min(vu1); + + // CHECK: [[VF1_AS1:%.+]] = load <4 x float>, <4 x float> addrspace(1)* @vf1_as_one, align 16 + // CHECK-NEXT: [[RDX1:%.+]] = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> [[VF1_AS1]]) + // CHECK-NEXT: fpext float [[RDX1]] to double + const double r4 = __builtin_reduce_min(vf1_as_one); + + // CHECK: [[CVI1:%.+]] = load <8 x i16>, <8 x i16>* %cvi1, align 16 + // CHECK-NEXT: [[RDX2:%.+]] = call i16 @llvm.vector.reduce.smin.v8i16(<8 x i16> [[CVI1]]) + // CHECK-NEXT: sext i16 [[RDX2]] to i64 + const si8 cvi1 = vi1; + unsigned long long r5 = __builtin_reduce_min(cvi1); +} diff --git a/clang/test/Sema/builtins-reduction-math.c b/clang/test/Sema/builtins-reduction-math.c new file mode 100644 index 0000000000000..0d1aecaa99c30 --- /dev/null +++ b/clang/test/Sema/builtins-reduction-math.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 %s -pedantic -verify -triple=x86_64-apple-darwin9 + +typedef float float4 __attribute__((ext_vector_type(4))); +typedef int int3 __attribute__((ext_vector_type(3))); +typedef unsigned unsigned4 __attribute__((ext_vector_type(4))); + +struct Foo { + char *p; +}; + +void test_builtin_reduce_max(int i, float4 v, int3 iv) { + struct Foo s = __builtin_reduce_max(iv); + // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}} + + i = __builtin_reduce_max(v, v); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} + + i = __builtin_reduce_max(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} + + i = __builtin_reduce_max(i); + // expected-error@-1 {{1st argument must be a vector type (was 'int')}} +} + +void test_builtin_reduce_min(int i, float4 v, int3 iv) { + struct Foo s = __builtin_reduce_min(iv); + // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}} + + i = __builtin_reduce_min(v, v); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} + + i = __builtin_reduce_min(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} + + i = __builtin_reduce_min(i); + // expected-error@-1 {{1st argument must be a vector type (was 'int')}} +} From e986f4082f440225872234a1ff48495f0d224e64 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Fri, 22 Oct 2021 09:13:02 +0100 Subject: [PATCH 005/293] Coroutines: don't infer function attrs before lowering Coroutines have weird semantics that don't quite match normal LLVM functions, so trying to infer even simple attributes based on thier contents can go wrong. --- llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 3 ++- .../Transforms/Coroutines/coro-retcon-alloca.ll | 2 +- llvm/test/Transforms/Coroutines/coro-retcon.ll | 2 +- llvm/test/Transforms/FunctionAttrs/noreturn.ll | 17 +++++++++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index ca8660a98ded8..de69d9bff5673 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -1556,7 +1556,8 @@ static SCCNodesResult createSCCNodeSet(ArrayRef Functions) { SCCNodesResult Res; Res.HasUnknownCall = false; for (Function *F : Functions) { - if (!F || F->hasOptNone() || F->hasFnAttribute(Attribute::Naked)) { + if (!F || F->hasOptNone() || F->hasFnAttribute(Attribute::Naked) || + F->isPresplitCoroutine()) { // Treat any function we're trying not to optimize as if it were an // indirect call and omit it from the node set used below. Res.HasUnknownCall = true; diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll index bf2862fcac2bd..be8df510ecfa2 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon-alloca.ll @@ -10,7 +10,7 @@ define {i8*, i8*, i32} @f(i8* %buffer, i32 %n) { ; CHECK-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds i8, i8* [[BUFFER:%.*]], i64 8 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[N_VAL_SPILL_ADDR]] to i32* ; CHECK-NEXT: store i32 [[N:%.*]], i32* [[TMP0]], align 4 -; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @allocate(i32 [[N]]) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @allocate(i32 [[N]]) ; CHECK-NEXT: [[DOTSPILL_ADDR:%.*]] = bitcast i8* [[BUFFER]] to i8** ; CHECK-NEXT: store i8* [[TMP1]], i8** [[DOTSPILL_ADDR]], align 8 ; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i8*, i8*, i32 } { i8* bitcast ({ i8*, i8*, i32 } (i8*, i1)* @f.resume.0 to i8*), i8* undef, i32 undef }, i8* [[TMP1]], 1 diff --git a/llvm/test/Transforms/Coroutines/coro-retcon.ll b/llvm/test/Transforms/Coroutines/coro-retcon.ll index 5c9e33897139b..7445ba8c1117d 100644 --- a/llvm/test/Transforms/Coroutines/coro-retcon.ll +++ b/llvm/test/Transforms/Coroutines/coro-retcon.ll @@ -72,7 +72,7 @@ entry: define hidden { i8*, i8* } @g(i8* %buffer, i16* %ptr) { ; CHECK-LABEL: @g( ; CHECK-NEXT: coro.return: -; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @allocate(i32 8) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @allocate(i32 8) ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUFFER:%.*]] to i8** ; CHECK-NEXT: store i8* [[TMP0]], i8** [[TMP1]], align 8 ; CHECK-NEXT: [[PTR_SPILL_ADDR:%.*]] = bitcast i8* [[TMP0]] to i16** diff --git a/llvm/test/Transforms/FunctionAttrs/noreturn.ll b/llvm/test/Transforms/FunctionAttrs/noreturn.ll index 098788f93af8f..eba56c9630adb 100644 --- a/llvm/test/Transforms/FunctionAttrs/noreturn.ll +++ b/llvm/test/Transforms/FunctionAttrs/noreturn.ll @@ -71,3 +71,20 @@ define void @callsite_noreturn() { call i32 @f() noreturn ret void } + +; CHECK: Function Attrs: {{.*}}noreturn +; CHECK-NEXT: @unreachable +define void @unreachable() { + unreachable +} + +; CHECK-NOT: Function Attrs: {{.*}}noreturn +; CHECK: @coro +define void @coro() "coroutine.presplit"="1" { + call token @llvm.coro.id.retcon.once(i32 0, i32 0, i8* null, i8* bitcast(void() *@coro to i8*), i8* null, i8* null) + call i1 @llvm.coro.end(i8* null, i1 false) + unreachable +} + +declare token @llvm.coro.id.retcon.once(i32 %size, i32 %align, i8* %buffer, i8* %prototype, i8* %alloc, i8* %free) +declare i1 @llvm.coro.end(i8*, i1) \ No newline at end of file From 5ae95eaa8162fcb479328cc1d9ddac6f2cd9c867 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 4 Nov 2021 09:43:31 -0700 Subject: [PATCH 006/293] [debugserver] Fix typo in DNBArchImplARM64 rdar://85020754 (cherry picked from commit 3120cadac782cd51f88f52dd2e88a20a6aa77b4b) --- .../debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp index 69a833303c932..e065718c7df94 100644 --- a/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/arm64/DNBArchImplARM64.cpp @@ -157,9 +157,9 @@ kern_return_t DNBArchMachARM64::GetGPRState(bool force) { uint64_t log_pc = arm_thread_state64_get_pc(m_state.context.gpr); #else uint64_t log_fp = m_state.context.gpr.__fp; - uint64_t log_fp = m_state.context.gpr.__lr; - uint64_t log_fp = m_state.context.gpr.__sp; - uint64_t log_fp = m_state.context.gpr.__pc, + uint64_t log_lr = m_state.context.gpr.__lr; + uint64_t log_sp = m_state.context.gpr.__sp; + uint64_t log_pc = m_state.context.gpr.__pc; #endif DNBLogThreaded( "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs" From 83a8378c4e3254ab826bd1e92d95c2bfd90ad4f9 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Fri, 5 Nov 2021 13:37:24 -0300 Subject: [PATCH 007/293] [lldb] Use reflection metadata to find the value type of an existential --- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 80 +++++++++++++------ .../Swift/SwiftLanguageRuntimeImpl.h | 3 +- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 32169173e6a84..12f56a94df70d 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -2433,9 +2433,12 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_IndirectEnumCase( // because we aren't pointing to the LOCATION that stores the pointer to us, // we're pointing to us..." // See inlined comments for exceptions to this general rule. -Value::ValueType SwiftLanguageRuntimeImpl::GetValueType( - Value::ValueType static_value_type, CompilerType static_type, - CompilerType dynamic_type, bool is_indirect_enum_case) { +Value::ValueType +SwiftLanguageRuntimeImpl::GetValueType(ValueObject &in_value, + CompilerType dynamic_type, + bool is_indirect_enum_case) { + Value::ValueType static_value_type = in_value.GetValue().GetValueType(); + CompilerType static_type = in_value.GetCompilerType(); Flags static_type_flags(static_type.GetTypeInfo()); Flags dynamic_type_flags(dynamic_type.GetTypeInfo()); @@ -2456,21 +2459,50 @@ Value::ValueType SwiftLanguageRuntimeImpl::GetValueType( return Value::ValueType::LoadAddress; } - if (auto *ts = llvm::dyn_cast_or_null( - dynamic_type.GetTypeSystem())) - switch (ts->GetAllocationStrategy(dynamic_type.GetOpaqueQualType())) { - case SwiftASTContext::TypeAllocationStrategy::eDynamic: - case SwiftASTContext::TypeAllocationStrategy::eUnknown: - break; - case SwiftASTContext::TypeAllocationStrategy::eInline: // inline data; - // same as the - // static data - return static_value_type; - case SwiftASTContext::TypeAllocationStrategy::ePointer: // pointed-to; - // in the target - return Value::ValueType::LoadAddress; - } + lldb::addr_t existential_address; + bool use_local_buffer = false; + + if (in_value.GetValueType() == eValueTypeConstResult && + // We have a locally materialized value that is a host address; + // register it with MemoryReader so it does not treat it as a load + // address. Note that this assumes that any address at that host + // address is also a load address. If this assumption breaks there + // will be a crash in readBytes(). + static_value_type == lldb_private::Value::ValueType::HostAddress) { + existential_address = in_value.GetValue().GetScalar().ULongLong(); + use_local_buffer = true; + } else { + existential_address = in_value.GetAddressOf(); + } + + if (use_local_buffer) + PushLocalBuffer(existential_address, + in_value.GetByteSize().getValueOr(0)); + + // Read the value witness table and check if the data is inlined in + // the existential container or not. + swift::remote::RemoteAddress remote_existential(existential_address); + auto *reflection_ctx = GetReflectionContext(); + llvm::Optional is_inlined = + reflection_ctx->isValueInlinedInExistentialContainer( + remote_existential); + + if (use_local_buffer) + PopLocalBuffer(); + + // An error has occurred when trying to read value witness table, + // default to treating it as pointer. + if (!is_inlined.hasValue()) + return Value::ValueType::LoadAddress; + + // Inlined data, same as static data. + if (*is_inlined) + return static_value_type; + + // If the data is not inlined, we have a pointer. + return Value::ValueType::LoadAddress; } + if (static_type_flags.AllSet(eTypeIsSwift | eTypeIsGenericTypeParam)) { // if I am handling a non-pointer Swift type obtained from an archetype, // then the runtime vends the location @@ -2497,8 +2529,7 @@ Value::ValueType SwiftLanguageRuntimeImpl::GetValueType( dynamic_type_flags.AllSet(eTypeIsSwift) && dynamic_type_flags.AllClear(eTypeIsPointer | eTypeInstanceIsPointer)) return static_value_type; - else - return Value::ValueType::Scalar; + return Value::ValueType::Scalar; } bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType( @@ -2575,9 +2606,7 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType( return false; class_type_or_name = dyn_class_type_or_name; class_type_or_name.SetCompilerType(swift_type); - value_type = GetValueType(in_value.GetValue().GetValueType(), - in_value.GetCompilerType(), - class_type_or_name.GetCompilerType(), false); + value_type = Value::ValueType::Scalar; return true; } @@ -2611,7 +2640,7 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress( return false; LLDB_SCOPED_TIMER(); - + // Try to import a Clang type into Swift. if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) return GetDynamicTypeAndAddress_ClangType( @@ -2696,9 +2725,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress( } if (success) - value_type = GetValueType( - in_value.GetValue().GetValueType(), in_value.GetCompilerType(), - class_type_or_name.GetCompilerType(), is_indirect_enum_case); + value_type = GetValueType(in_value, class_type_or_name.GetCompilerType(), + is_indirect_enum_case); else if (scratch_ctx->HasFatalErrors()) return retry_once(); return success; diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h index 028b0ceb82c6d..7474ab2516600 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h @@ -202,8 +202,7 @@ class SwiftLanguageRuntimeImpl { std::function fn); // Classes that inherit from SwiftLanguageRuntime can see and modify these - Value::ValueType GetValueType(Value::ValueType static_value_type, - CompilerType static_type, + Value::ValueType GetValueType(ValueObject &in_value, CompilerType dynamic_type, bool is_indirect_enum_case); From 4301f820fc909431f271c3e5f2892df19f6c8713 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 5 Nov 2021 13:18:06 -0700 Subject: [PATCH 008/293] [lldb] Use std::string instead of llvm::Twine in GDBRemoteCommunicationClient From the documentation: A Twine is not intended for use directly and should not be stored, its implementation relies on the ability to store pointers to temporary stack objects which may be deallocated at the end of a statement. Twines should only be used accepted as const references in arguments, when an API wishes to accept possibly-concatenated strings. rdar://84799118 Differential revision: https://reviews.llvm.org/D113314 (cherry picked from commit 6d48e2505c7a68a470e75b61ad504d51db0f8a36) --- .../Process/gdb-remote/GDBRemoteCommunicationClient.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index e5c2339267610..47aee1f229ea7 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1075,9 +1075,8 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression( if (avail_type != CompressionType::None) { StringExtractorGDBRemote response; - llvm::Twine packet = "QEnableCompression:type:" + avail_name + ";"; - if (SendPacketAndWaitForResponse(packet.str(), response) != - PacketResult::Success) + std::string packet = "QEnableCompression:type:" + avail_name.str() + ";"; + if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success) return; if (response.IsOKResponse()) { From 7439524d80393352c05495cd9c86d973fee97693 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 4 Aug 2021 10:59:53 +0200 Subject: [PATCH 009/293] [lldb] Partly revert "Allow range-based for loops over DWARFDIE's children" As pointed out in D107434 by Walter, D103172 also changed two for loops that were actually not just iterating over some DIEs but also using the iteration variable later on for some other things. This patch reverts the respective faulty parts of D103172. (cherry picked from commit e4977f9cb58ff7820d0287ba309490af57787749) --- .../source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index a82748c06038f..f37c22a202396 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -3478,7 +3478,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( UniqueCStringMap dst_name_to_die; UniqueCStringMap src_name_to_die_artificial; UniqueCStringMap dst_name_to_die_artificial; - for (DWARFDIE src_die : src_class_die.children()) { + for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); + src_die = src_die.GetSibling()) { if (src_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances @@ -3496,7 +3497,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } } } - for (DWARFDIE dst_die : dst_class_die.children()) { + for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); + dst_die = dst_die.GetSibling()) { if (dst_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances From 1e21555961d86f3541afc094e4d9abdcd609cccb Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 5 Nov 2021 20:31:07 -0700 Subject: [PATCH 010/293] [lldb] Remove nested switches from ARMGetSupportedArchitectureAtIndex (NFC) Remove the nested switches from the ARMGetSupportedArchitectureAtIndex implementation. Differential revision: https://reviews.llvm.org/D113155 (cherry picked from commit 05fbe758906ea27344391bd27817b19788bbce91) --- .../Platform/MacOSX/PlatformDarwin.cpp | 676 +++--------------- .../Plugins/Platform/MacOSX/PlatformDarwin.h | 3 + .../unittests/Platform/PlatformDarwinTest.cpp | 93 +++ 3 files changed, 209 insertions(+), 563 deletions(-) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 62da060951392..d769e9f7ce30b 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -555,25 +555,105 @@ bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx, return false; } +static llvm::ArrayRef GetCompatibleArchs(ArchSpec::Core core) { + switch (core) { + default: + LLVM_FALLTHROUGH; + case ArchSpec::eCore_arm_arm64: { + static const char *g_arm64_compatible_archs[] = { + "arm64", "armv7", "armv7f", "armv7k", "armv7s", "armv7m", + "armv7em", "armv6m", "armv6", "armv5", "armv4", "arm", + "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", "thumbv7em", + "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_arm64_compatible_archs}; + } + case ArchSpec::eCore_arm_armv7: { + static const char *g_armv7_compatible_archs[] = { + "armv7", "armv6m", "armv6", "armv5", "armv4", "arm", + "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv7_compatible_archs}; + } + case ArchSpec::eCore_arm_armv7f: { + static const char *g_armv7f_compatible_archs[] = { + "armv7f", "armv7", "armv6m", "armv6", "armv5", + "armv4", "arm", "thumbv7f", "thumbv7", "thumbv6m", + "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv7f_compatible_archs}; + } + case ArchSpec::eCore_arm_armv7k: + static const char *g_armv7k_compatible_archs[] = { + "armv7k", "armv7", "armv6m", "armv6", "armv5", + "armv4", "arm", "thumbv7k", "thumbv7", "thumbv6m", + "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv7k_compatible_archs}; + case ArchSpec::eCore_arm_armv7s: + static const char *g_armv7s_compatible_archs[] = { + "armv7s", "armv7", "armv6m", "armv6", "armv5", + "armv4", "arm", "thumbv7s", "thumbv7", "thumbv6m", + "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv7s_compatible_archs}; + case ArchSpec::eCore_arm_armv7m: + static const char *g_armv7m_compatible_archs[] = { + "armv7m", "armv7", "armv6m", "armv6", "armv5", + "armv4", "arm", "thumbv7m", "thumbv7", "thumbv6m", + "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv7m_compatible_archs}; + case ArchSpec::eCore_arm_armv7em: + static const char *g_armv7em_compatible_archs[] = { + "armv7em", "armv7", "armv6m", "armv6", "armv5", + "armv4", "arm", "thumbv7em", "thumbv7", "thumbv6m", + "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv7em_compatible_archs}; + case ArchSpec::eCore_arm_armv6m: + static const char *g_armv6m_compatible_archs[] = { + "armv6m", "armv6", "armv5", "armv4", "arm", + "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv6m_compatible_archs}; + case ArchSpec::eCore_arm_armv6: + static const char *g_armv6_compatible_archs[] = { + "armv6", "armv5", "armv4", "arm", + "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv6_compatible_archs}; + case ArchSpec::eCore_arm_armv5: + static const char *g_armv5_compatible_archs[] = { + "armv5", "armv4", "arm", "thumbv5", "thumbv4t", "thumb", + }; + return {g_armv5_compatible_archs}; + case ArchSpec::eCore_arm_armv4: + static const char *g_armv4_compatible_archs[] = { + "armv4", + "arm", + "thumbv4t", + "thumb", + }; + return {g_armv4_compatible_archs}; + } + return {}; +} + +const char *PlatformDarwin::GetCompatibleArch(ArchSpec::Core core, size_t idx) { + llvm::ArrayRef compatible_archs = GetCompatibleArchs(core); + if (!compatible_archs.data()) + return nullptr; + if (idx < compatible_archs.size()) + return compatible_archs[idx]; + return nullptr; +} + /// The architecture selection rules for arm processors These cpu subtypes have /// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f /// processor. bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) { - ArchSpec system_arch(GetSystemArchitecture()); - -#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 -#define OSNAME "tvos" -#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 -#define OSNAME "watchos" -#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 -#define OSNAME "bridgeos" -#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 -#define OSNAME "macosx" -#else -#define OSNAME "ios" -#endif - #if TARGET_OS_OSX if (IsHost()) { if (idx == 0) { @@ -583,561 +663,31 @@ bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx, arch.SetTriple("arm64-apple-macosx"); return true; } + arch.Clear(); return false; } #endif - const ArchSpec::Core system_core = system_arch.GetCore(); - switch (system_core) { - default: - switch (idx) { - case 0: - arch.SetTriple("arm64-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv7f-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv7k-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv7s-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("armv7m-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("armv7em-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 12: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 13: - arch.SetTriple("thumbv7f-apple-" OSNAME); - return true; - case 14: - arch.SetTriple("thumbv7k-apple-" OSNAME); - return true; - case 15: - arch.SetTriple("thumbv7s-apple-" OSNAME); - return true; - case 16: - arch.SetTriple("thumbv7m-apple-" OSNAME); - return true; - case 17: - arch.SetTriple("thumbv7em-apple-" OSNAME); - return true; - case 18: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 19: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 20: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 21: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 22: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_arm64: - switch (idx) { - case 0: - arch.SetTriple("arm64-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv7s-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv7f-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv7m-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv7em-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 12: - arch.SetTriple("thumbv7f-apple-" OSNAME); - return true; - case 13: - arch.SetTriple("thumbv7k-apple-" OSNAME); - return true; - case 14: - arch.SetTriple("thumbv7s-apple-" OSNAME); - return true; - case 15: - arch.SetTriple("thumbv7m-apple-" OSNAME); - return true; - case 16: - arch.SetTriple("thumbv7em-apple-" OSNAME); - return true; - case 17: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 18: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 19: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 20: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 21: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv7f: - switch (idx) { - case 0: - arch.SetTriple("armv7f-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumbv7f-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 12: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 13: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv7k: - switch (idx) { - case 0: - arch.SetTriple("armv7k-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumbv7k-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 12: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 13: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv7s: - switch (idx) { - case 0: - arch.SetTriple("armv7s-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumbv7s-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 12: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 13: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv7m: - switch (idx) { - case 0: - arch.SetTriple("armv7m-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumbv7m-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 12: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 13: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv7em: - switch (idx) { - case 0: - arch.SetTriple("armv7em-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumbv7em-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 12: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 13: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv7: - switch (idx) { - case 0: - arch.SetTriple("armv7-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("thumbv7-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 10: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 11: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv6m: - switch (idx) { - case 0: - arch.SetTriple("armv6m-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("thumbv6m-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 8: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 9: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv6: - switch (idx) { - case 0: - arch.SetTriple("armv6-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("thumbv6-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 6: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 7: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; - - case ArchSpec::eCore_arm_armv5: - switch (idx) { - case 0: - arch.SetTriple("armv5-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("thumbv5-apple-" OSNAME); - return true; - case 4: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 5: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; +#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 +#define OSNAME "tvos" +#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 +#define OSNAME "watchos" +#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 +#define OSNAME "bridgeos" +#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 +#define OSNAME "macosx" +#else +#define OSNAME "ios" +#endif - case ArchSpec::eCore_arm_armv4: - switch (idx) { - case 0: - arch.SetTriple("armv4-apple-" OSNAME); - return true; - case 1: - arch.SetTriple("arm-apple-" OSNAME); - return true; - case 2: - arch.SetTriple("thumbv4t-apple-" OSNAME); - return true; - case 3: - arch.SetTriple("thumb-apple-" OSNAME); - return true; - default: - break; - } - break; + const ArchSpec system_arch = GetSystemArchitecture(); + const ArchSpec::Core system_core = system_arch.GetCore(); + if (const char *compatible_arch = GetCompatibleArch(system_core, idx)) { + std::string triple = + llvm::formatv("{0}-apple-" OSNAME, compatible_arch).str(); + arch.SetTriple(triple); } + arch.Clear(); return false; } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index 22f7ad4ff823a..3530b0e8dab93 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -103,6 +103,9 @@ class PlatformDarwin : public PlatformPOSIX { static lldb_private::FileSpec GetCurrentCommandLineToolsDirectory(); protected: + static const char *GetCompatibleArch(lldb_private::ArchSpec::Core core, + size_t idx); + struct CrashInfoAnnotations { uint64_t version; // unsigned long uint64_t message; // char * diff --git a/lldb/unittests/Platform/PlatformDarwinTest.cpp b/lldb/unittests/Platform/PlatformDarwinTest.cpp index 285dc2ee3db78..73a0b37fbc773 100644 --- a/lldb/unittests/Platform/PlatformDarwinTest.cpp +++ b/lldb/unittests/Platform/PlatformDarwinTest.cpp @@ -20,6 +20,7 @@ using namespace lldb_private; struct PlatformDarwinTester : public PlatformDarwin { public: using PlatformDarwin::FindComponentInPath; + using PlatformDarwin::GetCompatibleArch; }; TEST(PlatformDarwinTest, TestParseVersionBuildDir) { @@ -66,3 +67,95 @@ TEST(PlatformDarwinTest, FindComponentInPath) { EXPECT_EQ("", PlatformDarwinTester::FindComponentInPath("/path/to/foo", "bar")); } + +TEST(PlatformDarwinTest, GetCompatibleArchARM64) { + const ArchSpec::Core core = ArchSpec::eCore_arm_arm64; + EXPECT_STREQ("arm64", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv7", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("armv4", PlatformDarwinTester::GetCompatibleArch(core, 10)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 11)); + EXPECT_STREQ("thumbv7", PlatformDarwinTester::GetCompatibleArch(core, 12)); + EXPECT_STREQ("thumbv4t", PlatformDarwinTester::GetCompatibleArch(core, 21)); + EXPECT_STREQ("thumb", PlatformDarwinTester::GetCompatibleArch(core, 22)); + EXPECT_EQ(nullptr, PlatformDarwinTester::GetCompatibleArch(core, 23)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv7f) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv7f; + EXPECT_STREQ("armv7f", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv7", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 6)); + EXPECT_STREQ("thumbv7f", PlatformDarwinTester::GetCompatibleArch(core, 7)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv7k) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv7k; + EXPECT_STREQ("armv7k", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv7", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 6)); + EXPECT_STREQ("thumbv7k", PlatformDarwinTester::GetCompatibleArch(core, 7)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv7s) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv7s; + EXPECT_STREQ("armv7s", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv7", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 6)); + EXPECT_STREQ("thumbv7s", PlatformDarwinTester::GetCompatibleArch(core, 7)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv7m) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv7m; + EXPECT_STREQ("armv7m", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv7", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 6)); + EXPECT_STREQ("thumbv7m", PlatformDarwinTester::GetCompatibleArch(core, 7)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv7em) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv7em; + EXPECT_STREQ("armv7em", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv7", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 6)); + EXPECT_STREQ("thumbv7em", PlatformDarwinTester::GetCompatibleArch(core, 7)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv7) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv7; + EXPECT_STREQ("armv7", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv6m", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 5)); + EXPECT_STREQ("thumbv7", PlatformDarwinTester::GetCompatibleArch(core, 6)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv6m) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv6m; + EXPECT_STREQ("armv6m", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv6", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 4)); + EXPECT_STREQ("thumbv6m", PlatformDarwinTester::GetCompatibleArch(core, 5)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv6) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv6; + EXPECT_STREQ("armv6", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv5", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 3)); + EXPECT_STREQ("thumbv6", PlatformDarwinTester::GetCompatibleArch(core, 4)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv5) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv5; + EXPECT_STREQ("armv5", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("armv4", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 2)); + EXPECT_STREQ("thumbv5", PlatformDarwinTester::GetCompatibleArch(core, 3)); +} + +TEST(PlatformDarwinTest, GetCompatibleArchARMv4) { + const ArchSpec::Core core = ArchSpec::eCore_arm_armv4; + EXPECT_STREQ("armv4", PlatformDarwinTester::GetCompatibleArch(core, 0)); + EXPECT_STREQ("arm", PlatformDarwinTester::GetCompatibleArch(core, 1)); + EXPECT_STREQ("thumbv4t", PlatformDarwinTester::GetCompatibleArch(core, 2)); + EXPECT_STREQ("thumb", PlatformDarwinTester::GetCompatibleArch(core, 3)); +} From f4451aa7fb5a47395215bb9d02caed9a900c3929 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 5 Nov 2021 20:41:28 -0700 Subject: [PATCH 011/293] [lldb] Remove 'result' variable which is set but not used (NFC) (cherry picked from commit ef2efd2553e00bc98c73843da9792d90e4231d30) --- lldb/tools/debugserver/source/TTYState.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lldb/tools/debugserver/source/TTYState.cpp b/lldb/tools/debugserver/source/TTYState.cpp index 96699a360499e..9fe83a3b72e53 100644 --- a/lldb/tools/debugserver/source/TTYState.cpp +++ b/lldb/tools/debugserver/source/TTYState.cpp @@ -39,20 +39,19 @@ bool TTYState::GetTTYState(int fd, bool saveProcessGroup) { } bool TTYState::SetTTYState() const { - int result = 0; if (IsValid()) { if (TFlagsValid()) - result = fcntl(m_fd, F_SETFL, m_tflags); + fcntl(m_fd, F_SETFL, m_tflags); if (TTYStateValid()) - result = tcsetattr(m_fd, TCSANOW, &m_ttystate); + tcsetattr(m_fd, TCSANOW, &m_ttystate); if (ProcessGroupValid()) { // Save the original signal handler. void (*saved_sigttou_callback)(int) = NULL; saved_sigttou_callback = (void (*)(int))signal(SIGTTOU, SIG_IGN); // Set the process group - result = tcsetpgrp(m_fd, m_processGroup); + tcsetpgrp(m_fd, m_processGroup); // Restore the original signal handler. signal(SIGTTOU, saved_sigttou_callback); } From 1512c8f2d9a1b0edfb4711d961bd3d394ece0648 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 5 Nov 2021 23:08:27 -0700 Subject: [PATCH 012/293] [lldb] Fix C2360: initialization of 'identifier' is skipped by 'case' label Make sure that every case has its own lexical block. (cherry picked from commit 1ab9a2906e19cca87cafac25cc31231a36de4843) --- .../Platform/MacOSX/PlatformDarwin.cpp | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index d769e9f7ce30b..923e7abf25fa2 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -583,52 +583,59 @@ static llvm::ArrayRef GetCompatibleArchs(ArchSpec::Core core) { }; return {g_armv7f_compatible_archs}; } - case ArchSpec::eCore_arm_armv7k: + case ArchSpec::eCore_arm_armv7k: { static const char *g_armv7k_compatible_archs[] = { "armv7k", "armv7", "armv6m", "armv6", "armv5", "armv4", "arm", "thumbv7k", "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", }; return {g_armv7k_compatible_archs}; - case ArchSpec::eCore_arm_armv7s: + } + case ArchSpec::eCore_arm_armv7s: { static const char *g_armv7s_compatible_archs[] = { "armv7s", "armv7", "armv6m", "armv6", "armv5", "armv4", "arm", "thumbv7s", "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", }; return {g_armv7s_compatible_archs}; - case ArchSpec::eCore_arm_armv7m: + } + case ArchSpec::eCore_arm_armv7m: { static const char *g_armv7m_compatible_archs[] = { "armv7m", "armv7", "armv6m", "armv6", "armv5", "armv4", "arm", "thumbv7m", "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", }; return {g_armv7m_compatible_archs}; - case ArchSpec::eCore_arm_armv7em: + } + case ArchSpec::eCore_arm_armv7em: { static const char *g_armv7em_compatible_archs[] = { "armv7em", "armv7", "armv6m", "armv6", "armv5", "armv4", "arm", "thumbv7em", "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", }; return {g_armv7em_compatible_archs}; - case ArchSpec::eCore_arm_armv6m: + } + case ArchSpec::eCore_arm_armv6m: { static const char *g_armv6m_compatible_archs[] = { "armv6m", "armv6", "armv5", "armv4", "arm", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", }; return {g_armv6m_compatible_archs}; - case ArchSpec::eCore_arm_armv6: + } + case ArchSpec::eCore_arm_armv6: { static const char *g_armv6_compatible_archs[] = { "armv6", "armv5", "armv4", "arm", "thumbv6", "thumbv5", "thumbv4t", "thumb", }; return {g_armv6_compatible_archs}; - case ArchSpec::eCore_arm_armv5: + } + case ArchSpec::eCore_arm_armv5: { static const char *g_armv5_compatible_archs[] = { "armv5", "armv4", "arm", "thumbv5", "thumbv4t", "thumb", }; return {g_armv5_compatible_archs}; - case ArchSpec::eCore_arm_armv4: + } + case ArchSpec::eCore_arm_armv4: { static const char *g_armv4_compatible_archs[] = { "armv4", "arm", @@ -637,6 +644,7 @@ static llvm::ArrayRef GetCompatibleArchs(ArchSpec::Core core) { }; return {g_armv4_compatible_archs}; } + } return {}; } From 66d1e00eb1808822bfa5b631190112a917296a2a Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 8 Nov 2021 15:32:04 -0800 Subject: [PATCH 013/293] Revert "[lldb] Disable swift-create-module-contexts-in-parallel for a few tests" This reverts https://github.com/apple/llvm-project/pull/3474 --- .../pyobjsynthprovider/TestPyObjSynthProvider.py | 2 -- .../TestSwiftDynamicTypeResolutionImportConflict.py | 2 -- .../headermap_conflict/TestSwiftHeadermapConflict.py | 2 -- .../clangimporter/macro_conflict/TestSwiftMacroConflict.py | 5 ----- .../TestSwiftObjCMainConflictingDylibs.py | 2 -- .../TestSwiftObjCMainConflictingDylibsFailingImport.py | 2 -- .../rewrite_clang_paths/TestSwiftRewriteClangPaths.py | 2 -- 7 files changed, 17 deletions(-) diff --git a/lldb/test/API/functionalities/data-formatter/pyobjsynthprovider/TestPyObjSynthProvider.py b/lldb/test/API/functionalities/data-formatter/pyobjsynthprovider/TestPyObjSynthProvider.py index d0c132ddd258e..22ce7442a6289 100644 --- a/lldb/test/API/functionalities/data-formatter/pyobjsynthprovider/TestPyObjSynthProvider.py +++ b/lldb/test/API/functionalities/data-formatter/pyobjsynthprovider/TestPyObjSynthProvider.py @@ -28,8 +28,6 @@ def setUp(self): def provider_data_formatter_commands(self): """Test that the PythonObjectSyntheticChildProvider helper class works""" - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( diff --git a/lldb/test/API/lang/swift/clangimporter/dynamic_type_resolution_import_conflict/TestSwiftDynamicTypeResolutionImportConflict.py b/lldb/test/API/lang/swift/clangimporter/dynamic_type_resolution_import_conflict/TestSwiftDynamicTypeResolutionImportConflict.py index e4d349f565187..802f40eb77a8e 100644 --- a/lldb/test/API/lang/swift/clangimporter/dynamic_type_resolution_import_conflict/TestSwiftDynamicTypeResolutionImportConflict.py +++ b/lldb/test/API/lang/swift/clangimporter/dynamic_type_resolution_import_conflict/TestSwiftDynamicTypeResolutionImportConflict.py @@ -45,8 +45,6 @@ def test(self): self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") self.build() target, _, _, _ = lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec('main.swift'), diff --git a/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py b/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py index dc529a9664850..5a57d91e1a6ba 100644 --- a/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py +++ b/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py @@ -38,8 +38,6 @@ def test(self): self.runCmd("settings set symbols.use-swift-dwarfimporter false") self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") self.build() target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( diff --git a/lldb/test/API/lang/swift/clangimporter/macro_conflict/TestSwiftMacroConflict.py b/lldb/test/API/lang/swift/clangimporter/macro_conflict/TestSwiftMacroConflict.py index 1463280d99a59..4e24787603a93 100644 --- a/lldb/test/API/lang/swift/clangimporter/macro_conflict/TestSwiftMacroConflict.py +++ b/lldb/test/API/lang/swift/clangimporter/macro_conflict/TestSwiftMacroConflict.py @@ -38,8 +38,6 @@ def test(self): self.runCmd('settings set symbols.use-swift-dwarfimporter false') self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") self.build() target, process, _, _ = lldbutil.run_to_source_breakpoint( @@ -79,9 +77,6 @@ def test_with_dwarfimporter(self): self.runCmd('settings set symbols.use-swift-dwarfimporter true') self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") - self.build() target, process, _, _ = lldbutil.run_to_source_breakpoint( diff --git a/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs/TestSwiftObjCMainConflictingDylibs.py b/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs/TestSwiftObjCMainConflictingDylibs.py index 24a343d3459e1..c7c5411a4d3d7 100644 --- a/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs/TestSwiftObjCMainConflictingDylibs.py +++ b/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs/TestSwiftObjCMainConflictingDylibs.py @@ -37,8 +37,6 @@ def test(self): self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") self.build() target, process, _, foo_breakpoint = lldbutil.run_to_source_breakpoint( self, 'break here', lldb.SBFileSpec('Foo.swift'), diff --git a/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs_failing_import/TestSwiftObjCMainConflictingDylibsFailingImport.py b/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs_failing_import/TestSwiftObjCMainConflictingDylibsFailingImport.py index 99023af04a8be..14443ec5cf1f2 100644 --- a/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs_failing_import/TestSwiftObjCMainConflictingDylibsFailingImport.py +++ b/lldb/test/API/lang/swift/clangimporter/objcmain_conflicting_dylibs_failing_import/TestSwiftObjCMainConflictingDylibsFailingImport.py @@ -37,8 +37,6 @@ def test(self): self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") self.build() target, process, _, bar_breakpoint = lldbutil.run_to_source_breakpoint( diff --git a/lldb/test/API/lang/swift/clangimporter/rewrite_clang_paths/TestSwiftRewriteClangPaths.py b/lldb/test/API/lang/swift/clangimporter/rewrite_clang_paths/TestSwiftRewriteClangPaths.py index 75ff8f50fc299..cb1edf03b8ca5 100644 --- a/lldb/test/API/lang/swift/clangimporter/rewrite_clang_paths/TestSwiftRewriteClangPaths.py +++ b/lldb/test/API/lang/swift/clangimporter/rewrite_clang_paths/TestSwiftRewriteClangPaths.py @@ -60,8 +60,6 @@ def dotest(self, remap): self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) self.runCmd("settings set symbols.use-swift-dwarfimporter false") - # rdar://84688015 SILModule::checkForLeaks can assert when used concurrently. - self.runCmd("settings set target.experimental.swift-create-module-contexts-in-parallel false") botdir = os.path.realpath(self.getBuildArtifact("buildbot")) userdir = os.path.realpath(self.getBuildArtifact("user")) From 3a153b625ee71eb739f8050be713b35af862c466 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 8 Nov 2021 17:01:21 -0800 Subject: [PATCH 014/293] Support looking up absolute symbols The Swift stdlib uses absolute symbols in the dylib to communicate feature flags to the process. LLDB's expression evaluator needs to be able to find them. This wires up absolute symbols so they show up in the symtab lookup command, which is also all that's needed for them to be visible to the expression evaluator JIT. rdar://85093828 Differential Revision: https://reviews.llvm.org/D113445 (cherry picked from commit c9881c7d99c6e4073ed8de11cd3450ef23bd66fc) --- lldb/source/Symbol/Symbol.cpp | 3 ++- lldb/source/Symbol/Symtab.cpp | 1 + lldb/test/Shell/SymbolFile/absolute-symbol.s | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 lldb/test/Shell/SymbolFile/absolute-symbol.s diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index a25911d1734da..670b68c072006 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -115,7 +115,8 @@ void Symbol::Clear() { } bool Symbol::ValueIsAddress() const { - return m_addr_range.GetBaseAddress().GetSection().get() != nullptr; + return m_addr_range.GetBaseAddress().GetSection().get() != nullptr || + m_type == eSymbolTypeAbsolute; } ConstString Symbol::GetDisplayName() const { diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp index 76bd5882a55ce..0eed147c5f9d6 100644 --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -1096,6 +1096,7 @@ void Symtab::FindFunctionSymbols(ConstString name, uint32_t name_type_mask, case eSymbolTypeCode: case eSymbolTypeResolver: case eSymbolTypeReExported: + case eSymbolTypeAbsolute: symbol_indexes.push_back(temp_symbol_indexes[i]); break; default: diff --git a/lldb/test/Shell/SymbolFile/absolute-symbol.s b/lldb/test/Shell/SymbolFile/absolute-symbol.s new file mode 100644 index 0000000000000..912703fd38283 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/absolute-symbol.s @@ -0,0 +1,7 @@ +# RUN: %clang %s -g -c -o %t.o +# RUN: %lldb -b -o 'target modules lookup -s absolute_symbol' %t.o | FileCheck %s +# CHECK: 1 symbols match 'absolute_symbol' +# CHECK: Address: 0x0000000012345678 (0x0000000012345678) +# CHECK: Summary: 0x0000000012345678 +.globl absolute_symbol +absolute_symbol = 0x12345678 From 9afd5a03c45ba286203d97870c8aa9a1c4bf2d82 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 9 Nov 2021 10:15:54 -0800 Subject: [PATCH 015/293] Add a requires line to test. (cherry picked from commit 56f7da6e0d29139d7684b2dc08901fefb64e4fa1) --- lldb/test/Shell/SymbolFile/absolute-symbol.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/test/Shell/SymbolFile/absolute-symbol.s b/lldb/test/Shell/SymbolFile/absolute-symbol.s index 912703fd38283..08e7eeb818f78 100644 --- a/lldb/test/Shell/SymbolFile/absolute-symbol.s +++ b/lldb/test/Shell/SymbolFile/absolute-symbol.s @@ -1,4 +1,5 @@ -# RUN: %clang %s -g -c -o %t.o +# REQUIRES: system-darwin +# RUN: %clang %s -c -o %t.o # RUN: %lldb -b -o 'target modules lookup -s absolute_symbol' %t.o | FileCheck %s # CHECK: 1 symbols match 'absolute_symbol' # CHECK: Address: 0x0000000012345678 (0x0000000012345678) From f71c16238c73ef3bfcfc2446f869e6cd844d6afe Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 9 Nov 2021 10:46:09 -0800 Subject: [PATCH 016/293] Use yaml2obj instead of relying on invoking the Darwin system assembler. (cherry picked from commit 68a4d179c2ac4c882f2d242b81748ceed66827ff) --- lldb/test/Shell/SymbolFile/absolute-symbol.s | 8 -- .../Shell/SymbolFile/absolute-symbol.test | 95 +++++++++++++++++++ 2 files changed, 95 insertions(+), 8 deletions(-) delete mode 100644 lldb/test/Shell/SymbolFile/absolute-symbol.s create mode 100644 lldb/test/Shell/SymbolFile/absolute-symbol.test diff --git a/lldb/test/Shell/SymbolFile/absolute-symbol.s b/lldb/test/Shell/SymbolFile/absolute-symbol.s deleted file mode 100644 index 08e7eeb818f78..0000000000000 --- a/lldb/test/Shell/SymbolFile/absolute-symbol.s +++ /dev/null @@ -1,8 +0,0 @@ -# REQUIRES: system-darwin -# RUN: %clang %s -c -o %t.o -# RUN: %lldb -b -o 'target modules lookup -s absolute_symbol' %t.o | FileCheck %s -# CHECK: 1 symbols match 'absolute_symbol' -# CHECK: Address: 0x0000000012345678 (0x0000000012345678) -# CHECK: Summary: 0x0000000012345678 -.globl absolute_symbol -absolute_symbol = 0x12345678 diff --git a/lldb/test/Shell/SymbolFile/absolute-symbol.test b/lldb/test/Shell/SymbolFile/absolute-symbol.test new file mode 100644 index 0000000000000..1d234cb55e059 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/absolute-symbol.test @@ -0,0 +1,95 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: %lldb -b -o 'target modules lookup -s absolute_symbol' %t.o | FileCheck %s +# CHECK: 1 symbols match 'absolute_symbol' +# CHECK: Address: 0x0000000012345678 (0x0000000012345678) +# CHECK: Summary: 0x0000000012345678 +# Created from: +# .globl absolute_symbol +# absolute_symbol = 0x12345678 +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x1 + ncmds: 4 + sizeofcmds: 280 + flags: 0x0 + reserved: 0x0 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: '' + vmaddr: 0 + vmsize: 0 + fileoff: 312 + filesize: 0 + maxprot: 7 + initprot: 7 + nsects: 1 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0 + size: 0 + offset: 0x138 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x80000000 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '' + - cmd: LC_BUILD_VERSION + cmdsize: 24 + platform: 1 + minos: 786432 + sdk: 0 + ntools: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 312 + nsyms: 2 + stroff: 344 + strsize: 24 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 1 + iextdefsym: 1 + nextdefsym: 1 + iundefsym: 2 + nundefsym: 0 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 +LinkEditData: + NameList: + - n_strx: 17 + n_type: 0xE + n_sect: 1 + n_desc: 0 + n_value: 0 + - n_strx: 1 + n_type: 0x3 + n_sect: 0 + n_desc: 0 + n_value: 305419896 + StringTable: + - '' + - absolute_symbol + - ltmp0 + - '' +... + From f55350ddef41363d8c476e50ce6e0be7917ddcf5 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 9 Nov 2021 22:28:12 +0000 Subject: [PATCH 017/293] headers: optionalise some generated resource headers This splits out the generated headers and conditonalises them upon the target being enabled. The motivation here is that the RISCV header alone added 10MB to the resource directory, which was previously at 10MB, increasing the build size and time. This header is contributing ~50% of the size of the resource headers (~10MB). The ARM generated headers are contributing about ~10% or 1MB. This could be extended further adding only the static resource headers for the targets that the LLVM build supports. The changes to the tests for ARM mirror what the RISCV target already did and rnk identified as a possible issue. Testing: cmake -G Ninja -D LLVM_TARGETS_TO_BUILD=X86 -D LLVM_ENABLE_PROJECTS="clang;lld" ../clang ninja check-clang Differential Revision: https://reviews.llvm.org/D112890 Reviewed By: craig.topper (cherry picked from commit c17d9b4b125e5561925aa85aaa0b113e383a2ee5) --- clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c | 2 ++ clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c | 2 ++ clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c | 2 ++ clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c | 2 ++ clang/test/CodeGen/aarch64-neon-2velem.c | 2 ++ clang/test/CodeGen/aarch64-neon-3v.c | 2 ++ clang/test/CodeGen/aarch64-neon-across.c | 2 ++ clang/test/CodeGen/aarch64-neon-fcvt-intrinsics.c | 2 ++ clang/test/CodeGen/aarch64-neon-fma.c | 2 ++ clang/test/CodeGen/aarch64-neon-intrinsics.c | 2 ++ clang/test/CodeGen/aarch64-neon-ldst-one.c | 2 ++ clang/test/CodeGen/aarch64-neon-misc.c | 2 ++ clang/test/CodeGen/aarch64-neon-perm.c | 2 ++ clang/test/CodeGen/aarch64-neon-range-checks.c | 2 ++ clang/test/CodeGen/aarch64-neon-scalar-copy.c | 2 ++ clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c | 2 ++ clang/test/CodeGen/aarch64-neon-sha3.c | 2 ++ clang/test/CodeGen/aarch64-neon-shifts.c | 2 ++ clang/test/CodeGen/aarch64-neon-sm4-sm3.c | 2 ++ clang/test/CodeGen/aarch64-neon-tbl.c | 2 ++ clang/test/CodeGen/aarch64-neon-vcadd.c | 2 ++ clang/test/CodeGen/aarch64-neon-vcombine.c | 2 ++ clang/test/CodeGen/aarch64-neon-vget-hilo.c | 2 ++ clang/test/CodeGen/aarch64-neon-vget.c | 2 ++ clang/test/CodeGen/aarch64-neon-vsqadd-float-conversion.c | 2 ++ .../test/CodeGen/aarch64-neon-vuqadd-float-conversion-warning.c | 2 ++ clang/test/CodeGen/aarch64-poly64.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c | 2 ++ .../test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c | 2 ++ .../CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c | 2 ++ .../aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c | 2 ++ .../CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c | 2 ++ clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c | 2 ++ clang/test/CodeGen/arm-bf16-getset-intrinsics.c | 2 ++ clang/test/CodeGen/arm-bf16-params-returns.c | 2 ++ clang/test/CodeGen/arm-cde-gpr.c | 2 ++ clang/test/CodeGen/arm-cde-reinterpret.c | 2 ++ clang/test/CodeGen/arm-cde-vec.c | 2 ++ clang/test/CodeGen/arm-cde-vfp.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/absneg.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/admin.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/bitwise-imm.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/compare.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/cplusplus.cpp | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/dup.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/get-set-lane.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/idup.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/load-store.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/predicates.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/reinterpret.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/scalar-shifts.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/scatter-gather.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/ternary.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vabavq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vabdq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vadc.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vaddq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vaddv.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vandq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vbicq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vbrsrq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vcaddq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vclz.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vcmlaq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vcmulq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vcvt.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vcvt_anpm.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm-dyadic.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vector-shift-var.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/veorq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vhaddq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vhcaddq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vhsubq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vld24.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vldr.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vminaq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vminq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vminvq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmldav.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmlldav.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmovl.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmovn.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmullbq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmulltq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vmulq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vornq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vorrq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqaddq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqdmlad.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqdmulhq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqdmullbq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqdmulltq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqmovn.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqrdmulhq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vqsubq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vrev.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vrhaddq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vrnd.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vshlc.c | 2 ++ clang/test/CodeGen/arm-mve-intrinsics/vsubq.c | 2 ++ clang/test/CodeGen/arm-neon-directed-rounding.c | 2 ++ clang/test/CodeGen/arm-neon-fma.c | 2 ++ clang/test/CodeGen/arm-neon-numeric-maxmin.c | 2 ++ clang/test/CodeGen/arm-neon-range-checks.c | 2 ++ clang/test/CodeGen/arm-neon-vcvtX.c | 2 ++ clang/test/CodeGen/arm-neon-vget.c | 2 ++ clang/test/CodeGen/arm-neon-vld.c | 2 ++ clang/test/CodeGen/arm-neon-vst.c | 2 ++ clang/test/CodeGen/arm-poly64.c | 2 ++ clang/test/CodeGen/arm64-arguments.c | 2 ++ clang/test/CodeGen/arm64-lanes.c | 2 ++ clang/test/CodeGen/arm64-vrnd.c | 2 ++ clang/test/CodeGen/arm64_vcopy.c | 2 ++ clang/test/CodeGen/arm64_vcreate.c | 2 ++ clang/test/CodeGen/arm64_vdup.c | 2 ++ clang/test/CodeGen/arm64_vdupq_n_f64.c | 2 ++ clang/test/CodeGen/arm_neon_intrinsics.c | 2 ++ clang/test/CodeGen/armv7k-abi.c | 2 ++ clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c | 2 ++ clang/test/CodeGen/neon-aapcs-align.c | 2 ++ clang/test/CodeGen/neon-crypto.c | 2 ++ clang/test/CodeGen/neon-immediate-ubsan.c | 2 ++ clang/test/CodeGenCXX/int64_uint64.cpp | 2 ++ clang/test/CodeGenCXX/poly-unsigned.cpp | 2 ++ clang/test/Headers/arm-cde-header.c | 2 ++ clang/test/Headers/arm-fp16-header.c | 2 ++ clang/test/Headers/arm-neon-header.c | 2 ++ clang/test/Headers/riscv-vector-header.c | 2 ++ clang/test/Sema/aarch64-bf16-ldst-intrinsics.c | 2 ++ clang/test/Sema/aarch64-neon-bf16-ranges.c | 2 ++ clang/test/Sema/aarch64-neon-fp16-ranges.c | 2 ++ clang/test/Sema/aarch64-neon-ranges.c | 2 ++ clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c | 2 ++ clang/test/Sema/aarch64-sve-lax-vector-conversions.c | 2 ++ clang/test/Sema/arm-bfloat.cpp | 2 ++ clang/test/Sema/arm-cde-immediates.c | 2 ++ clang/test/Sema/arm-mve-immediates.c | 2 ++ clang/test/Sema/arm-neon-types.c | 2 ++ clang/test/Sema/arm-no-fp16.c | 2 ++ clang/test/Sema/arm64-neon-args.c | 2 ++ clang/test/Sema/arm64-neon-header.c | 2 ++ clang/test/Sema/arm_vfma.c | 2 ++ clang/test/Sema/big-endian-neon-initializers.c | 2 ++ clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp | 2 ++ clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp | 2 ++ 366 files changed, 732 insertions(+) diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c b/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c index 14558778278e7..8c5d11aeb344e 100644 --- a/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c +++ b/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c @@ -1,3 +1,5 @@ +// REQUIRES: riscv-registered-target + // RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-v \ // RUN: -O2 -emit-llvm %s -o - \ // RUN: | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c b/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c index 966c50f62c8b1..9db578ad1eeee 100644 --- a/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c +++ b/clang/test/CodeGen/aarch64-bf16-dotprod-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-feature +neon -target-feature +bf16 \ // RUN: -disable-O0-optnone -emit-llvm -fno-legacy-pass-manager %s -o - | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c b/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c index 7f3bf7f1ec301..2c5ca5688e223 100644 --- a/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c +++ b/clang/test/CodeGen/aarch64-bf16-getset-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-feature +neon -target-feature +bf16 \ // RUN: -disable-O0-optnone -emit-llvm -fno-legacy-pass-manager %s -o - | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c b/clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c index b5a2c20f2e32b..16b9ad1283557 100644 --- a/clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c +++ b/clang/test/CodeGen/aarch64-bf16-lane-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-feature +neon -target-feature +bf16 \ // RUN: -disable-O0-optnone -emit-llvm -fno-legacy-pass-manager %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-LE %s diff --git a/clang/test/CodeGen/aarch64-neon-2velem.c b/clang/test/CodeGen/aarch64-neon-2velem.c index 25c0ae4988b74..3608848dccef2 100644 --- a/clang/test/CodeGen/aarch64-neon-2velem.c +++ b/clang/test/CodeGen/aarch64-neon-2velem.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-3v.c b/clang/test/CodeGen/aarch64-neon-3v.c index 1ed90430edfeb..fee1d60856135 100644 --- a/clang/test/CodeGen/aarch64-neon-3v.c +++ b/clang/test/CodeGen/aarch64-neon-3v.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // Test new aarch64 intrinsics and types diff --git a/clang/test/CodeGen/aarch64-neon-across.c b/clang/test/CodeGen/aarch64-neon-across.c index 5fc29d509be82..98bd659d40964 100644 --- a/clang/test/CodeGen/aarch64-neon-across.c +++ b/clang/test/CodeGen/aarch64-neon-across.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-fcvt-intrinsics.c b/clang/test/CodeGen/aarch64-neon-fcvt-intrinsics.c index 6cda12bf5beab..3d80becc8bd2c 100644 --- a/clang/test/CodeGen/aarch64-neon-fcvt-intrinsics.c +++ b/clang/test/CodeGen/aarch64-neon-fcvt-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-fma.c b/clang/test/CodeGen/aarch64-neon-fma.c index 16d5255463a39..e5b6d6b63d962 100644 --- a/clang/test/CodeGen/aarch64-neon-fma.c +++ b/clang/test/CodeGen/aarch64-neon-fma.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // Test new aarch64 intrinsics and types diff --git a/clang/test/CodeGen/aarch64-neon-intrinsics.c b/clang/test/CodeGen/aarch64-neon-intrinsics.c index 76f5cfd3aaa8a..1b96c19c48a67 100644 --- a/clang/test/CodeGen/aarch64-neon-intrinsics.c +++ b/clang/test/CodeGen/aarch64-neon-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -fallow-half-arguments-and-returns -S -disable-O0-optnone \ // RUN: -flax-vector-conversions=none -emit-llvm -o - %s \ diff --git a/clang/test/CodeGen/aarch64-neon-ldst-one.c b/clang/test/CodeGen/aarch64-neon-ldst-one.c index db352fecf221e..a0045ba7a19a1 100644 --- a/clang/test/CodeGen/aarch64-neon-ldst-one.c +++ b/clang/test/CodeGen/aarch64-neon-ldst-one.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -fallow-half-arguments-and-returns -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-misc.c b/clang/test/CodeGen/aarch64-neon-misc.c index c185eb7af2e24..672b1121016f7 100644 --- a/clang/test/CodeGen/aarch64-neon-misc.c +++ b/clang/test/CodeGen/aarch64-neon-misc.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -fallow-half-arguments-and-returns -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-perm.c b/clang/test/CodeGen/aarch64-neon-perm.c index c5d5ab18070cb..9353de7247d31 100644 --- a/clang/test/CodeGen/aarch64-neon-perm.c +++ b/clang/test/CodeGen/aarch64-neon-perm.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-range-checks.c b/clang/test/CodeGen/aarch64-neon-range-checks.c index 3bb80c6979ac7..8a40d4dd42484 100644 --- a/clang/test/CodeGen/aarch64-neon-range-checks.c +++ b/clang/test/CodeGen/aarch64-neon-range-checks.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +sha3 -target-feature +sm4 -verify %s #include diff --git a/clang/test/CodeGen/aarch64-neon-scalar-copy.c b/clang/test/CodeGen/aarch64-neon-scalar-copy.c index 2d74cace185ce..8d366671b8e7f 100644 --- a/clang/test/CodeGen/aarch64-neon-scalar-copy.c +++ b/clang/test/CodeGen/aarch64-neon-scalar-copy.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c b/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c index 367978d84af41..0db7f94b3f1c9 100644 --- a/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c +++ b/clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-cpu cyclone \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-sha3.c b/clang/test/CodeGen/aarch64-neon-sha3.c index 9b043cdc3d44b..917a48be89365 100644 --- a/clang/test/CodeGen/aarch64-neon-sha3.c +++ b/clang/test/CodeGen/aarch64-neon-sha3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon \ // RUN: -target-feature +sha3 -S -emit-llvm -o - %s \ diff --git a/clang/test/CodeGen/aarch64-neon-shifts.c b/clang/test/CodeGen/aarch64-neon-shifts.c index e9a679bc69a44..548f942178949 100644 --- a/clang/test/CodeGen/aarch64-neon-shifts.c +++ b/clang/test/CodeGen/aarch64-neon-shifts.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -ffp-contract=fast -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-sm4-sm3.c b/clang/test/CodeGen/aarch64-neon-sm4-sm3.c index ee5e2a3331da6..2cb97cbbe09c3 100644 --- a/clang/test/CodeGen/aarch64-neon-sm4-sm3.c +++ b/clang/test/CodeGen/aarch64-neon-sm4-sm3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon \ // RUN: -target-feature +sm4 -S -emit-llvm -o - %s \ // RUN: | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-tbl.c b/clang/test/CodeGen/aarch64-neon-tbl.c index c9626c1f5fe03..4fd01d2ce5ea0 100644 --- a/clang/test/CodeGen/aarch64-neon-tbl.c +++ b/clang/test/CodeGen/aarch64-neon-tbl.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-vcadd.c b/clang/test/CodeGen/aarch64-neon-vcadd.c index 2d721f187fe62..ffe9e17a5bfcd 100644 --- a/clang/test/CodeGen/aarch64-neon-vcadd.c +++ b/clang/test/CodeGen/aarch64-neon-vcadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon \ // RUN: -target-feature +v8.3a -target-feature +fullfp16 -S -emit-llvm -o - %s \ // RUN: | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-vcombine.c b/clang/test/CodeGen/aarch64-neon-vcombine.c index 71f5ddfb62770..29db20a35f8a6 100644 --- a/clang/test/CodeGen/aarch64-neon-vcombine.c +++ b/clang/test/CodeGen/aarch64-neon-vcombine.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -fallow-half-arguments-and-returns -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // Test new aarch64 intrinsics and types diff --git a/clang/test/CodeGen/aarch64-neon-vget-hilo.c b/clang/test/CodeGen/aarch64-neon-vget-hilo.c index 71b344bf20dfd..1a4958a01ef6a 100644 --- a/clang/test/CodeGen/aarch64-neon-vget-hilo.c +++ b/clang/test/CodeGen/aarch64-neon-vget-hilo.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -fallow-half-arguments-and-returns -disable-O0-optnone -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-vget.c b/clang/test/CodeGen/aarch64-neon-vget.c index 9f88acc17cb12..3fca55cde05fe 100644 --- a/clang/test/CodeGen/aarch64-neon-vget.c +++ b/clang/test/CodeGen/aarch64-neon-vget.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-darwin -target-feature +neon \ // RUN: -fallow-half-arguments-and-returns -disable-O0-optnone -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-vsqadd-float-conversion.c b/clang/test/CodeGen/aarch64-neon-vsqadd-float-conversion.c index 3871d2bc5c166..c8b933495dab5 100644 --- a/clang/test/CodeGen/aarch64-neon-vsqadd-float-conversion.c +++ b/clang/test/CodeGen/aarch64-neon-vsqadd-float-conversion.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg -dce \ // RUN: | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-neon-vuqadd-float-conversion-warning.c b/clang/test/CodeGen/aarch64-neon-vuqadd-float-conversion-warning.c index 0d66b6df35852..e05dec71e2711 100644 --- a/clang/test/CodeGen/aarch64-neon-vuqadd-float-conversion-warning.c +++ b/clang/test/CodeGen/aarch64-neon-vuqadd-float-conversion-warning.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s 2>&1 | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-poly64.c b/clang/test/CodeGen/aarch64-poly64.c index ebc58b5840faf..9271e8910fdca 100644 --- a/clang/test/CodeGen/aarch64-poly64.c +++ b/clang/test/CodeGen/aarch64-poly64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -ffp-contract=fast -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg \ // RUN: | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c index 0d5af49d27582..6dbc81a75cdd6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmmla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c index f4b81a671d093..5026d24161698 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c index db2a6c5521143..74dc628104f85 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create2.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c index 7ec4814fd111a..87b6851805741 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c index 37ada8a187378..72dd27323dc05 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c index 17723b9419a7b..06bbc2b5395dd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c index f30bbb880f83f..162c3b4b0323c 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_create4.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c index f7f397aba059f..0b28a8a5474e2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvt-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c index 8dee5e5e4f8e2..d1ccc96a78bab 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_cvtnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c index 0c8a8ad19ecc0..1c67b04d3350e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c index c4efd621a3367..6899f1b32f1f0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get3-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c index b14583058382a..76f124dcf569f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_get4-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c index 55d9761c46050..5ae6a47c66399 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c index 254797e28c9ac..9d9455cdd2bae 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c index 8f2e7aab912b8..75da99ef12fa2 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ro.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +f64mm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c index bf1688bb01180..38bea85c81864 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1rq-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c index 4fa4a0692f5c1..a5743df89a06c 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c index fbb994b4a891d..b2015a2cbc02b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld2.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c index a5afd64089bed..ee3416727f3a0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c index 9353dae26f0d0..7c75df430b9c6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c index 9d73d5f88f3e8..5e5e22353e00d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c index bff9ae56ed601..42f7ffb6c0029 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld4.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c index 848a7a8fcbb35..6ae5cfd07e199 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c index 005600a5de963..9dbb94f5c3daf 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c index 7d972a9dda84e..8fb8c0396280b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c index 545c9f4d5d99d..1b27c79f82188 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp32.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f32mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f32mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f32mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c index 1682a53ad4d8e..edf7545b016ad 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_matmul_fp64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c index 6716fa3225aa5..20550a8960946 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_mmla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +i8mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c index 22b9dd7621e75..20499a446beae 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_rev-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c index 0cbd71ed0029e..8a5199d91af69 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c index 175341b108d36..95fbacc51593a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set2.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c index da1f81a6600e3..808652f9a425a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c index df9e06a72ba44..b88d0006fa57d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c index 9f8466db1359a..fb22d805b693e 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c index 7d5cc547991f5..ee213a8252030 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_set4.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c index f3a9381e556f0..6b6e3874b0903 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c index a1480b4c7d0f5..52380c60a3d27 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c index 5a9e11a8dedf4..8db3ecb68bd35 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st3-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c index 3c8bb7da46386..6c09309eefced 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st4-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c index 05fb09613489b..e6f0f33267215 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c index 36862a268049f..c1a018bfc5f9f 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c index 3814ae8673048..500aa9394eba6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c index d4753ced350ef..3cc273acc32e6 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn1-fp64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c index a23b5af5f506a..26f849ec2ec65 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c index 0ce57ce58aaac..a3bcc1fd0163d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c index bdec8cbf0af06..be78197a38b8a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_trn2-fp64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c index 47c7fb7bbcf27..bd13d9b27a0bf 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c index 62fb4f8f75aab..094b725c7ac7d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c index e928b3c218f9a..39a6ecb850043 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c index 434c180b59097..311aaf3fd18e5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c index 00165062585d2..4094dd39954ee 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c index 07ec64a99d587..381ff11cbb615 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=error -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c index 98dea16c8a7db..7eb53a6055e60 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c index 509f8b7efa615..a578a70de2d05 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c index 838edb1cb0e29..89efbd5ec62c7 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c index b4f1289441f45..33391b27be6a5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp1-fp64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c index 6adb017443c0a..d64a0941b80ff 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c index 372bc8882319e..0cb075641bd57 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c index fc53015551d15..dd78c3c2d5a31 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_uzp2-fp64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c index 7bcf840e542ce..6ad107aace551 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c index 218e8413454af..f08abee07ddcd 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c index 88ec67c309e18..8790ba06414c3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip1-fp64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c index c86a0e518c5bd..78619e5e294f4 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c index 626324f0e32ae..a16bee63693dc 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c index f4ff36c2ee6be..a00be8b8e3011 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_zip2-fp64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +f64mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c index 0df6a9b7b4507..ef9b50bf4e65a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_asrd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c index 7d83addc05335..8deb8400ef63d 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c index cafdd638b23e6..6e617574b9b26 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_cmla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c index 29e5eba397750..cfdd562e4eba9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_dot.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c index cce61cfd2b046..a51f38202a5c1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c index 1c334cfe17cd4..6b2a16377830b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get2.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c index 05f35f20a614f..00f91c232858b 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c index 37c5d1838acb2..dbacfe14c3c96 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_get4.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c index e107e02c7e8b2..bfe896cda63e4 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c index 528999a5c1b1f..8e4bff14d56e0 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_mul.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c index 641bbff06aa52..9c5f1680cac4a 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c index e1ad02d812ad1..1438d9ed846e1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c index 7ffff9b08e4a1..6f80df99a40e9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c index 8ce509784ccda..9108c78f5adc1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s #include diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c index e07094c5ed525..d8da32714c0bb 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c index ac01ce0b770da..b92a2aa634fa8 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c index adfc966363ede..2daffd6745eea 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c index 316914fad06a5..5a7e448f11229 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdecw.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c index e2687e19240fa..7e4220cc4b9e8 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c index 9ad619207647d..6f8ec6d680084 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c index 269ab07242f49..d4cb534b11509 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qinch.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c index f123b39a47f38..68c6a78d9b5a9 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qincw.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c index 5a3131b2da6b6..0394cb60c11e5 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set2.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c index c4bb8cb880f27..eabe1169913ae 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c index 6036bcd159c07..0e74773a4c3ab 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_set4.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=note %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c index 25f15402988ac..710c87844a2c3 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_tmad.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c index f7fdd76114af9..5df86a18c26a1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/big_endian.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s // expected-error@* {{Big endian is currently not supported for arm_sve.h}} diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c index 31f4d4a74347c..21c74979b7aa6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adalp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c index 0cf04ccf681ee..fbd141adbbbb9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c index e9290948268fd..4c65d4e4e01d9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c index c10060a8aef5e..7d2aee653d79a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aese.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c index d4ed607012c0b..9664f6095ffba 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesimc.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c index 25bd65d38a4fa..a3365210e4077 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aesmc.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c index 98a8b351ae21f..c2b642df3ccbf 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c index ffc9f3be8d70e..9d64f4c9fd48d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cdot.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c index bf196a0b2dd6a..63cef2502a801 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cmla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c index e36fb406842a4..9a6babdbbabfe 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtlt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c index 2d45ad177a07e..f6110a4aa547f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c index a482db147c23a..748e86491e68b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtx.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c index aeb2a7b758830..e5dd6d6bee48c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_cvtxnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c index 1161b6a91836d..3d457f2412739 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histcnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c index e49a3993197d6..79793c8168457 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_histseg.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c index 47febd9823a4b..83b3196d3c97a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c index 44164b1b21a79..55e53a34c5d72 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c index ad439a224fce9..785a509aff181 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c index 96dcbd2d94209..03b9699b6702d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1sw.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c index 29454ffb7ecca..e14016820c42d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1ub.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c index f9b9161df295d..a6d34d358f830 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c index cf95768e0a717..b13216ee339ce 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_ldnt1uw.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c index bcb227120ed46..7d9fac31cf85f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_logb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c index d98bd678a9023..84b24e999e65d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_match.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c index 01e43f95fdd50..08bef2ce86ce4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxnmp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c index fcf84455cb391..cb4ad46bf0833 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_maxp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c index 4072511e3d524..84e7c2305c918 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minnmp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c index 9885b2b936f64..f04d958c8eb46 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_minp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c index c6e866ab9e145..369730a9e173c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c index c9370f1580014..8911c14336037 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mls.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c index 0fbffffcc771b..0658b1d721100 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c index 74c2187f6fccf..33f7e8f0c50d3 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_movlt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c index bd4559e1e9eaf..93a22aedcaefd 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mul.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c index 2580268bf1518..6d79863b6ad7d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nmatch.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c index 97d6c4c95940d..1a8736b3a8ef4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qabs.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c index d5956427e3634..2ec6bc114280b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qcadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c index 59af8c87fc69d..f8f6f3f00a763 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qneg.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c index 4b8dd93bf08b2..78582f1b34335 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdcmlah.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c index 3e31a7ecaf252..7983500832c13 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c index 0f996502d9bda..1a40950835249 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c index a4256ec54c620..cdfe8aab53e18 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c index 2ae6c61db07f4..c207f67621703 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshrunt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c index 93618ea3ceebf..58f706134b574 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshlu.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c index a06cc62a94bbf..0c183bfef804a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c index 13a82a36272af..abdeb1df4a3f9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c index ab218f35a83c3..27e9995d85259 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c index 7df3a4227d7c7..38258ea90bba9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshrunt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c index 267a953c2c3cd..b00417479d68c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c index 5c1da4ba561e7..37a5ac8d3f79d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c index 7fa498ee212bd..7230a851ba1dd 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c index d039e8c92ddad..16c0c98c4b19d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qxtunt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c index 7fdb0bc3ba6f8..29870a1354f2f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rax1.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sha3 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sha3 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sha3 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c index 19a88273caef6..7092e99ecae85 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_recpe.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c index 8923be4528485..edb6212442416 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshr.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c index 031c1381536df..14952497c2105 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c index a46ac59b7c4b7..051ec6970806e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c index 528c838d1fc5e..1ff540e7ce820 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsqrte.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c index 50af90afc5a90..96700cce1c5b7 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsra.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c index 4d457aab44e11..52230d48e99fa 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c index 2f78ad61545e6..e4787791376b0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shllt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c index 92837b904fc5d..b984dfc88befe 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c index cd412035e8b9a..b6fd128a63015 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_shrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c index e30fa18f5a50c..9b880e92d05f3 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sli.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c index b43b014cbee92..f030936f69086 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4e.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c index 488e74e3b7b01..01ea130e27c16 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sm4ekey.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-sm4 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c index f99fce73698c6..9c5062397db51 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sra.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c index 5fd74b88c3373..05147360ebb42 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sri.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c index 6d24e3f272be9..b2b99daec01f7 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c index e8ec536916dee..8073c69ba392c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1b.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c index 8463b55dcad42..09898292132aa 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1h.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c index 561c3e14c1a31..7f9b92187d886 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_stnt1w.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c index 936ffedd00860..49205569d2347 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbl2.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c index c31918dbfaafc..dcc92f95cd4d0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_tbx.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c index ac37dbdfc0b15..34ab60965fd43 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilege.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c index 0186ad1f75846..766ad05de715c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilegt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c index bebd40a0dbd33..7e200997ec63f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c index 1bd486d746279..43c5ac6660b32 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilerw.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c index c2ed031ae08bf..83dbfe45316e5 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr-bfloat.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -D__ARM_FEATURE_SVE -D__ARM_FEATURE_SVE2 -D__ARM_FEATURE_BF16_SCALAR_ARITHMETIC -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c index 84f4c15606083..a9f801f46a0c1 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_whilewr.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c index e235f37e386ac..3ae3cf4018bee 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_xar.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c index 12d695d1a4a7b..5a5310c9671eb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c index 88b662d089f9d..b7ef82bcf5dca 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cdot.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=warning %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify -verify-ignore-unexpected=warning %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c index 4c0592addb5d8..8ccb9e011e68d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_cmla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c index ee679750b9f6b..00f0d8510fea4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mla.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c index da67b6de26bbf..ac41562880a23 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c index 8f2b4e4897c07..311f1fb5f6bd0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlalt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c index e727f5745bd66..8d3688bdcbcf9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mls.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c index cda90d870b687..6e7e92a6a4b2b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c index c51ccff08b792..0cb31ef077aba 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mlslt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c index fe407224e4dfb..f8dfcc4fc2320 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mul.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c index 9902a4a89618d..221471b3f42bb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c index f29b01d278738..d181faf15b0b8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_mullt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c index 8dea17f829a8f..b915767eb4832 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qcadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c index 24adade56741d..df0a8769b2c20 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c index b3dd7bd940dc1..9732df7523d5b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlalt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c index 250e6755794e6..70cc4d6f0486f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c index 9d38a7849cfdd..009c31cdee216 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmlslt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c index 58401229adaae..b371875bbb939 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmulh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c index 5b22db2f8ed09..786a98cef5910 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c index 597ac7e08a679..7795b209274b5 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qdmullt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c index ce1bafe877559..acd4af3acb9b8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdcmlah.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c index 266d658af31bc..519a30828a72c 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlah.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c index 8074a605041b4..42fd70eca817d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmlsh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c index 14834aa42596b..b3be7843150aa 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrdmulh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c index f92fe6011e7d5..6c7c7c0a9a24d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c index 0c791e005bfdc..63500c15e1503 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c index 541ae62837d1b..7a4d2ff95b91b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c index 4b6dc9e7f164f..e47d3d2d08c34 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qrshrunt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c index ca26aec41bdb4..489044f140a73 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshlu.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c index 19d4d8a97a60b..857af25773393 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c index 18d9ccc04a425..0e5ba44a508c2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c index bee61489d4d61..65b202863d4f0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c index 8b7c202fba80e..b101de4f37f73 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_qshrunt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c index 9da56a0163ce0..ce68a7be57f2b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshr.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c index dfba6aeb1d760..311d9e3377ebc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c index c859022738528..78fb1d33419dc 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rshrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c index acf5065a9348f..d8ac6d94f01a2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_rsra.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c index 5e4af80a5bb9d..0d479f385b254 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c index 6b67e2dd45c34..0776df29472de 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shllt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c index f783779ac2232..7b12a5bf9fd51 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c index 8bca15b643170..4fef731833d02 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_shrnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c index ce159bcf679ab..4ac718296b362 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sli.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c index b70d4351ad887..a2eacc743164a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sra.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c index 19acfebc661a7..05baeeb4eebaf 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_sri.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c index d0d7f5d0dc133..b9544b6a7937a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/negative/acle_sve2_xar.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -fsyntax-only -verify %s diff --git a/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c b/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c index 2fdb9f1c2b3f5..e5f1f8b1deba9 100644 --- a/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c +++ b/clang/test/CodeGen/arm-bf16-dotprod-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple armv8-arm-none-eabi \ // RUN: -target-feature +neon -target-feature +bf16 -mfloat-abi soft \ diff --git a/clang/test/CodeGen/arm-bf16-getset-intrinsics.c b/clang/test/CodeGen/arm-bf16-getset-intrinsics.c index c798a102f4e34..756e71e54e059 100644 --- a/clang/test/CodeGen/arm-bf16-getset-intrinsics.c +++ b/clang/test/CodeGen/arm-bf16-getset-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple armv8.6a-arm-none-eabi -target-feature +neon -target-feature +bf16 -mfloat-abi hard \ // RUN: -disable-O0-optnone -emit-llvm -fno-legacy-pass-manager %s -o - | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-bf16-params-returns.c b/clang/test/CodeGen/arm-bf16-params-returns.c index 650ae0adb6127..7509617ba2d28 100644 --- a/clang/test/CodeGen/arm-bf16-params-returns.c +++ b/clang/test/CodeGen/arm-bf16-params-returns.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple armv8.6a-arm-none-eabi -target-abi aapcs -mfloat-abi hard -target-feature +bf16 -target-feature +neon -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefix=CHECK32-HARD // RUN: %clang_cc1 -triple armv8.6a-arm-none-eabi -target-abi aapcs -mfloat-abi softfp -target-feature +bf16 -target-feature +neon -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefix=CHECK32-SOFTFP // RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-abi aapcs -target-feature +bf16 -target-feature +neon -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefix=CHECK64 diff --git a/clang/test/CodeGen/arm-cde-gpr.c b/clang/test/CodeGen/arm-cde-gpr.c index ceb33e8ab9745..735d8d4c4ec84 100644 --- a/clang/test/CodeGen/arm-cde-gpr.c +++ b/clang/test/CodeGen/arm-cde-gpr.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi \ // RUN: -target-feature +cdecp0 -target-feature +cdecp1 \ diff --git a/clang/test/CodeGen/arm-cde-reinterpret.c b/clang/test/CodeGen/arm-cde-reinterpret.c index bebfc5dee8454..4e70a66c5ed25 100644 --- a/clang/test/CodeGen/arm-cde-reinterpret.c +++ b/clang/test/CodeGen/arm-cde-reinterpret.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi \ // RUN: -target-feature +cdecp0 -target-feature +mve.fp \ // RUN: -mfloat-abi hard -O0 -disable-O0-optnone \ diff --git a/clang/test/CodeGen/arm-cde-vec.c b/clang/test/CodeGen/arm-cde-vec.c index be4b8bef75ec3..e5cf897f9f88a 100644 --- a/clang/test/CodeGen/arm-cde-vec.c +++ b/clang/test/CodeGen/arm-cde-vec.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi \ // RUN: -target-feature +cdecp0 -target-feature +cdecp1 \ diff --git a/clang/test/CodeGen/arm-cde-vfp.c b/clang/test/CodeGen/arm-cde-vfp.c index 41fef605860db..e3cb6326ddb13 100644 --- a/clang/test/CodeGen/arm-cde-vfp.c +++ b/clang/test/CodeGen/arm-cde-vfp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi \ // RUN: -target-feature +cdecp0 -target-feature +cdecp1 \ diff --git a/clang/test/CodeGen/arm-mve-intrinsics/absneg.c b/clang/test/CodeGen/arm-mve-intrinsics/absneg.c index b63135bc450a6..841eb24ae2231 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/absneg.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/absneg.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/admin.c b/clang/test/CodeGen/arm-mve-intrinsics/admin.c index 6c81cda00bac8..48048bdd328d3 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/admin.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/admin.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s --check-prefixes=CHECK,CHECK-LE // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s --check-prefixes=CHECK,CHECK-LE diff --git a/clang/test/CodeGen/arm-mve-intrinsics/bitwise-imm.c b/clang/test/CodeGen/arm-mve-intrinsics/bitwise-imm.c index c41e0265c8fd2..3a93334c87707 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/bitwise-imm.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/bitwise-imm.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/compare.c b/clang/test/CodeGen/arm-mve-intrinsics/compare.c index efe5a56f7efb8..7d05f525dec28 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/compare.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/compare.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/cplusplus.cpp b/clang/test/CodeGen/arm-mve-intrinsics/cplusplus.cpp index 59604c58b740a..40fbc4ba27c05 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/cplusplus.cpp +++ b/clang/test/CodeGen/arm-mve-intrinsics/cplusplus.cpp @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/dup.c b/clang/test/CodeGen/arm-mve-intrinsics/dup.c index f3c694a9b03eb..480f35a46d6e8 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/dup.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/dup.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/get-set-lane.c b/clang/test/CodeGen/arm-mve-intrinsics/get-set-lane.c index 5a6d67df80cfc..3ccf80794f569 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/get-set-lane.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/get-set-lane.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/idup.c b/clang/test/CodeGen/arm-mve-intrinsics/idup.c index ac3ab3e632bdd..e562a08ad157f 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/idup.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/idup.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/load-store.c b/clang/test/CodeGen/arm-mve-intrinsics/load-store.c index 5a676ebb5924b..ea821d7216d34 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/load-store.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/load-store.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/predicates.c b/clang/test/CodeGen/arm-mve-intrinsics/predicates.c index fc36fdb80d439..dc9f995fe8b87 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/predicates.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/predicates.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/reinterpret.c b/clang/test/CodeGen/arm-mve-intrinsics/reinterpret.c index 36f70be1cb0d1..7817cdf4856d1 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/reinterpret.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/reinterpret.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s --check-prefix=BOTH --check-prefix=LE // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s --check-prefix=BOTH --check-prefix=LE diff --git a/clang/test/CodeGen/arm-mve-intrinsics/scalar-shifts.c b/clang/test/CodeGen/arm-mve-intrinsics/scalar-shifts.c index ef544291c5627..7703560c6aff4 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/scalar-shifts.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/scalar-shifts.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/scatter-gather.c b/clang/test/CodeGen/arm-mve-intrinsics/scatter-gather.c index a7d1a1c966633..6e1a5c546b2fb 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/scatter-gather.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/scatter-gather.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/ternary.c b/clang/test/CodeGen/arm-mve-intrinsics/ternary.c index 42408974a91ba..66788f604649b 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/ternary.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/ternary.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vabavq.c b/clang/test/CodeGen/arm-mve-intrinsics/vabavq.c index 3f5adb7d8db92..270976ee23acf 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vabavq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vabavq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vabdq.c b/clang/test/CodeGen/arm-mve-intrinsics/vabdq.c index eda67d48a5dc5..f400cc7f2b687 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vabdq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vabdq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vadc.c b/clang/test/CodeGen/arm-mve-intrinsics/vadc.c index 5e428efd1b29c..7993d87cc37a2 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vadc.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vadc.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vaddq.c b/clang/test/CodeGen/arm-mve-intrinsics/vaddq.c index ca529457ed639..e4a2a8889c2c2 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vaddq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vaddq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vaddv.c b/clang/test/CodeGen/arm-mve-intrinsics/vaddv.c index 48655dcaf3645..bbf31c0539399 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vaddv.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vaddv.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vandq.c b/clang/test/CodeGen/arm-mve-intrinsics/vandq.c index c56c7e7d3b486..b04217f0e3abf 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vandq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vandq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vbicq.c b/clang/test/CodeGen/arm-mve-intrinsics/vbicq.c index 941fb5e35865e..b5391320af446 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vbicq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vbicq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vbrsrq.c b/clang/test/CodeGen/arm-mve-intrinsics/vbrsrq.c index 0c2c1dd825339..2c3abf96555fe 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vbrsrq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vbrsrq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vcaddq.c b/clang/test/CodeGen/arm-mve-intrinsics/vcaddq.c index bdfba6d394a50..4750d263d03d0 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vcaddq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vcaddq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vclz.c b/clang/test/CodeGen/arm-mve-intrinsics/vclz.c index 490bafcd74c34..cdd96073a72ab 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vclz.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vclz.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vcmlaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vcmlaq.c index ed2ef56d7bc10..27c7da6f162fe 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vcmlaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vcmlaq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vcmulq.c b/clang/test/CodeGen/arm-mve-intrinsics/vcmulq.c index 142e909a1f0e0..2f7124b3f640d 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vcmulq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vcmulq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vcvt.c b/clang/test/CodeGen/arm-mve-intrinsics/vcvt.c index 1cbcbe823ef86..c8b8267615b2e 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vcvt.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vcvt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -DPOLYMORPHIC -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vcvt_anpm.c b/clang/test/CodeGen/arm-mve-intrinsics/vcvt_anpm.c index 8563245a9f328..823a2ace4935c 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vcvt_anpm.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vcvt_anpm.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -DPOLYMORPHIC -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm-dyadic.c b/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm-dyadic.c index 7cbaf4001c7ec..cd143fcd13a88 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm-dyadic.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm-dyadic.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm.c b/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm.c index 4eec660a2f056..5df975879f6e2 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-imm.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-var.c b/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-var.c index f83808d77aca2..5ef2f11ff0d89 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-var.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vector-shift-var.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/veorq.c b/clang/test/CodeGen/arm-mve-intrinsics/veorq.c index 68f40dce9eb60..a454da210aee2 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/veorq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/veorq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vhaddq.c b/clang/test/CodeGen/arm-mve-intrinsics/vhaddq.c index 3abf36bc37f27..a87069c2f87bf 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vhaddq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vhaddq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vhcaddq.c b/clang/test/CodeGen/arm-mve-intrinsics/vhcaddq.c index 1f4efd634e9b1..7d69969b7338a 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vhcaddq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vhcaddq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vhsubq.c b/clang/test/CodeGen/arm-mve-intrinsics/vhsubq.c index 04aabe3952a5d..abd680e767746 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vhsubq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vhsubq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vld24.c b/clang/test/CodeGen/arm-mve-intrinsics/vld24.c index 98abd277c9950..6a438fb6406cc 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vld24.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vld24.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vldr.c b/clang/test/CodeGen/arm-mve-intrinsics/vldr.c index d6deb754cc67a..78de897a12240 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vldr.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vldr.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c index a656657b66197..4dcffe0277eac 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxaq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c index 52b439fe5555f..83bf93d1d42d2 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmaq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c index 19b5d28a52440..390c5f0e45e17 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxnmq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c index 7fb2f5191f440..6471afb86d461 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmaxq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c index 6a6279cce0df2..d7eed60a954d4 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminaq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c index 5ddc3914f1857..6624c344573f6 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminnmaq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c index 0723dfae2f064..e37d94870a2b1 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminnmq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminq.c index 1f3b0d670ee17..8d257d12ad79f 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vminvq.c b/clang/test/CodeGen/arm-mve-intrinsics/vminvq.c index 94fbb1791473a..4165e067f8d1a 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vminvq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vminvq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmldav.c b/clang/test/CodeGen/arm-mve-intrinsics/vmldav.c index 913b56346913e..ff446ee1ee2df 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmldav.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmldav.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmlldav.c b/clang/test/CodeGen/arm-mve-intrinsics/vmlldav.c index 52941229ac216..dec96998d4ec2 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmlldav.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmlldav.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmovl.c b/clang/test/CodeGen/arm-mve-intrinsics/vmovl.c index 7fd0fd591a43a..b39dd4673ca2d 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmovl.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmovl.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmovn.c b/clang/test/CodeGen/arm-mve-intrinsics/vmovn.c index 48c7bd4ce1681..b4aaa8f7b6aba 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmovn.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmovn.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck --check-prefix=LE %s // RUN: %clang_cc1 -triple thumbebv8.1m.main-arm-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck --check-prefix=BE %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c index 4f018da3f97b8..1c3d2f509f87d 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmulhq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmullbq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmullbq.c index bf3dce8a34a9a..8123f2942e95b 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmullbq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmullbq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmulltq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmulltq.c index 515960ba5fb4b..c3354c1d1cd51 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmulltq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmulltq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vmulq.c b/clang/test/CodeGen/arm-mve-intrinsics/vmulq.c index 214e9d95cacda..aeec2d5a3eeb0 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vmulq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vmulq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vornq.c b/clang/test/CodeGen/arm-mve-intrinsics/vornq.c index eabb8aea9f903..5aa5116f28080 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vornq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vornq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vorrq.c b/clang/test/CodeGen/arm-mve-intrinsics/vorrq.c index ccdd1e0768f54..9a6799a2a846f 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vorrq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vorrq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqaddq.c b/clang/test/CodeGen/arm-mve-intrinsics/vqaddq.c index 1d05e9dcefafa..5009a6b0e15e8 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqaddq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqaddq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqdmlad.c b/clang/test/CodeGen/arm-mve-intrinsics/vqdmlad.c index 20b6745800ff1..ed5c26e33f76f 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqdmlad.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqdmlad.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqdmulhq.c b/clang/test/CodeGen/arm-mve-intrinsics/vqdmulhq.c index 45a2b5eb79849..a5d51bd0c6dd4 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqdmulhq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqdmulhq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqdmullbq.c b/clang/test/CodeGen/arm-mve-intrinsics/vqdmullbq.c index cf9ffdf138725..ec1c5c1bc1ddd 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqdmullbq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqdmullbq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqdmulltq.c b/clang/test/CodeGen/arm-mve-intrinsics/vqdmulltq.c index 26b216c8dc17e..9022b9bbb4a6f 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqdmulltq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqdmulltq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqmovn.c b/clang/test/CodeGen/arm-mve-intrinsics/vqmovn.c index a24306340f347..5b1b412d31b46 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqmovn.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqmovn.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -DPOLYMORPHIC -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqrdmulhq.c b/clang/test/CodeGen/arm-mve-intrinsics/vqrdmulhq.c index b62fe8de9c326..20af8142cb70f 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqrdmulhq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqrdmulhq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vqsubq.c b/clang/test/CodeGen/arm-mve-intrinsics/vqsubq.c index d6ac32b05b2c0..156723d8b5e84 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vqsubq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vqsubq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vrev.c b/clang/test/CodeGen/arm-mve-intrinsics/vrev.c index 5cb720dcb67ba..72ecb1d67cf66 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vrev.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vrev.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vrhaddq.c b/clang/test/CodeGen/arm-mve-intrinsics/vrhaddq.c index 17fb58b8dabfc..c7623bd79281c 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vrhaddq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vrhaddq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c b/clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c index f9f76f54d691f..7c88cad4bc977 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vrmulhq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vrnd.c b/clang/test/CodeGen/arm-mve-intrinsics/vrnd.c index 6df91cfbbc7e9..6b9ec6a65e7d3 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vrnd.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vrnd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vshlc.c b/clang/test/CodeGen/arm-mve-intrinsics/vshlc.c index 2cbaccd0ed3ae..b428a42c7c7f4 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vshlc.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vshlc.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vsubq.c b/clang/test/CodeGen/arm-mve-intrinsics/vsubq.c index bc904809a1e9f..a35386646a65a 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vsubq.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vsubq.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -sroa | FileCheck %s diff --git a/clang/test/CodeGen/arm-neon-directed-rounding.c b/clang/test/CodeGen/arm-neon-directed-rounding.c index c493e3897ab6a..cc4145ba27ddd 100644 --- a/clang/test/CodeGen/arm-neon-directed-rounding.c +++ b/clang/test/CodeGen/arm-neon-directed-rounding.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 \ // RUN: -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | \ // RUN: opt -S -mem2reg | FileCheck -check-prefixes=CHECK,CHECK-A32 %s diff --git a/clang/test/CodeGen/arm-neon-fma.c b/clang/test/CodeGen/arm-neon-fma.c index 889a752fc970a..2d0ba7cfef280 100644 --- a/clang/test/CodeGen/arm-neon-fma.c +++ b/clang/test/CodeGen/arm-neon-fma.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7-none-linux-gnueabihf \ // RUN: -target-abi aapcs \ // RUN: -target-cpu cortex-a7 \ diff --git a/clang/test/CodeGen/arm-neon-numeric-maxmin.c b/clang/test/CodeGen/arm-neon-numeric-maxmin.c index bf7d115f7da5d..11b16d463ce52 100644 --- a/clang/test/CodeGen/arm-neon-numeric-maxmin.c +++ b/clang/test/CodeGen/arm-neon-numeric-maxmin.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck %s #include diff --git a/clang/test/CodeGen/arm-neon-range-checks.c b/clang/test/CodeGen/arm-neon-range-checks.c index 488dad6d59acd..66eeb3327d4b7 100644 --- a/clang/test/CodeGen/arm-neon-range-checks.c +++ b/clang/test/CodeGen/arm-neon-range-checks.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-eabi -target-feature +neon -target-feature +dotprod -target-feature +v8.1a -verify %s // RUN: %clang_cc1 -triple armv8.1a-none-eabi -target-feature +neon -target-feature +dotprod -target-feature +v8.1a -verify %s diff --git a/clang/test/CodeGen/arm-neon-vcvtX.c b/clang/test/CodeGen/arm-neon-vcvtX.c index 79813711ab825..64e6ba8ebfe06 100644 --- a/clang/test/CodeGen/arm-neon-vcvtX.c +++ b/clang/test/CodeGen/arm-neon-vcvtX.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -ffreestanding -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck %s #include diff --git a/clang/test/CodeGen/arm-neon-vget.c b/clang/test/CodeGen/arm-neon-vget.c index 841cf0396d461..1bde3774bfa51 100644 --- a/clang/test/CodeGen/arm-neon-vget.c +++ b/clang/test/CodeGen/arm-neon-vget.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7-apple-darwin \ // RUN: -target-abi apcs-gnu \ // RUN: -target-cpu cortex-a8 \ diff --git a/clang/test/CodeGen/arm-neon-vld.c b/clang/test/CodeGen/arm-neon-vld.c index c9aac63c81a7a..decdac3d060a7 100644 --- a/clang/test/CodeGen/arm-neon-vld.c +++ b/clang/test/CodeGen/arm-neon-vld.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ // RUN: FileCheck -check-prefixes=CHECK,CHECK-A64 %s diff --git a/clang/test/CodeGen/arm-neon-vst.c b/clang/test/CodeGen/arm-neon-vst.c index dc7105a7322c6..7be4bbb3296f9 100644 --- a/clang/test/CodeGen/arm-neon-vst.c +++ b/clang/test/CodeGen/arm-neon-vst.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -S -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | \ // RUN: FileCheck -check-prefixes=CHECK,CHECK-A64 %s diff --git a/clang/test/CodeGen/arm-poly64.c b/clang/test/CodeGen/arm-poly64.c index 52c757f0acbbe..4590513013291 100644 --- a/clang/test/CodeGen/arm-poly64.c +++ b/clang/test/CodeGen/arm-poly64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple armv8.2a-arm-none-eabi -target-feature +neon \ // RUN: -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/arm64-arguments.c b/clang/test/CodeGen/arm64-arguments.c index b362346aa8a82..aff2ba2bd0b35 100644 --- a/clang/test/CodeGen/arm64-arguments.c +++ b/clang/test/CodeGen/arm64-arguments.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-LE // RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-BE diff --git a/clang/test/CodeGen/arm64-lanes.c b/clang/test/CodeGen/arm64-lanes.c index 3d765bf777b7b..69132c7e41f0f 100644 --- a/clang/test/CodeGen/arm64-lanes.c +++ b/clang/test/CodeGen/arm64-lanes.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s // RUN: %clang_cc1 -triple aarch64_be-linux-gnu -target-feature +neon -ffreestanding -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s --check-prefix CHECK-BE diff --git a/clang/test/CodeGen/arm64-vrnd.c b/clang/test/CodeGen/arm64-vrnd.c index 24298f896d319..2d048bb3bacd8 100644 --- a/clang/test/CodeGen/arm64-vrnd.c +++ b/clang/test/CodeGen/arm64-vrnd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -flax-vector-conversions=none -emit-llvm -o - %s | FileCheck %s #include diff --git a/clang/test/CodeGen/arm64_vcopy.c b/clang/test/CodeGen/arm64_vcopy.c index ece0623bfcc5c..eacd7aa09f673 100644 --- a/clang/test/CodeGen/arm64_vcopy.c +++ b/clang/test/CodeGen/arm64_vcopy.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -disable-O0-optnone -emit-llvm %s | opt -S -mem2reg | FileCheck %s // Test ARM64 SIMD copy vector element to vector element: vcopyq_lane* diff --git a/clang/test/CodeGen/arm64_vcreate.c b/clang/test/CodeGen/arm64_vcreate.c index ddfa147705d50..ae2103c7d5003 100644 --- a/clang/test/CodeGen/arm64_vcreate.c +++ b/clang/test/CodeGen/arm64_vcreate.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | opt -S -mem2reg | FileCheck %s // Test ARM64 SIMD vcreate intrinsics diff --git a/clang/test/CodeGen/arm64_vdup.c b/clang/test/CodeGen/arm64_vdup.c index 67eb8553638a8..73853ec1f2b16 100644 --- a/clang/test/CodeGen/arm64_vdup.c +++ b/clang/test/CodeGen/arm64_vdup.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s // Test ARM64 SIMD duplicate lane and n intrinsics diff --git a/clang/test/CodeGen/arm64_vdupq_n_f64.c b/clang/test/CodeGen/arm64_vdupq_n_f64.c index ac5d1a9436a36..f5e10aae51b96 100644 --- a/clang/test/CodeGen/arm64_vdupq_n_f64.c +++ b/clang/test/CodeGen/arm64_vdupq_n_f64.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -fallow-half-arguments-and-returns -S -o - -disable-O0-optnone -emit-llvm %s | opt -S -mem2reg | FileCheck %s #include diff --git a/clang/test/CodeGen/arm_neon_intrinsics.c b/clang/test/CodeGen/arm_neon_intrinsics.c index a84f75ad422e4..e2dcf32460825 100644 --- a/clang/test/CodeGen/arm_neon_intrinsics.c +++ b/clang/test/CodeGen/arm_neon_intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7s-apple-darwin -target-abi apcs-gnu\ // RUN: -target-cpu swift -fallow-half-arguments-and-returns \ // RUN: -target-feature +fullfp16 -ffreestanding \ diff --git a/clang/test/CodeGen/armv7k-abi.c b/clang/test/CodeGen/armv7k-abi.c index a7e04dc3611b2..7691c7bc80dad 100644 --- a/clang/test/CodeGen/armv7k-abi.c +++ b/clang/test/CodeGen/armv7k-abi.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7k-apple-watchos2.0 -target-abi aapcs16 -target-cpu cortex-a7 %s -o - -emit-llvm | FileCheck %s #include diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c index c27651f55a188..38c4f7bd0bc72 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -msve-vector-bits=512 -fallow-half-arguments-and-returns -S -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/neon-aapcs-align.c b/clang/test/CodeGen/neon-aapcs-align.c index 4b7e5ff4d387a..5ffeb2496c134 100644 --- a/clang/test/CodeGen/neon-aapcs-align.c +++ b/clang/test/CodeGen/neon-aapcs-align.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple armv7a-none-eabi -target-feature +neon -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=AAPCS // RUN: %clang_cc1 -triple armv7a-none-gnueabi -target-feature +neon -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=AAPCS // RUN: %clang_cc1 -triple armv7a-none-freebsd -target-feature +neon -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=AAPCS diff --git a/clang/test/CodeGen/neon-crypto.c b/clang/test/CodeGen/neon-crypto.c index db3249856c452..6eeb47fd42cd5 100644 --- a/clang/test/CodeGen/neon-crypto.c +++ b/clang/test/CodeGen/neon-crypto.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-feature +neon \ // RUN: -target-feature +sha2 -target-feature +aes \ // RUN: -target-cpu cortex-a57 -emit-llvm -O1 -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/neon-immediate-ubsan.c b/clang/test/CodeGen/neon-immediate-ubsan.c index 69a54c8464210..abbf461be9b40 100644 --- a/clang/test/CodeGen/neon-immediate-ubsan.c +++ b/clang/test/CodeGen/neon-immediate-ubsan.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple armv7s-linux-gnu -target-abi apcs-gnu -emit-llvm -o - %s \ // RUN: -target-feature +neon -target-cpu cortex-a8 \ // RUN: -fsanitize=signed-integer-overflow \ diff --git a/clang/test/CodeGenCXX/int64_uint64.cpp b/clang/test/CodeGenCXX/int64_uint64.cpp index aad6ea0b741de..be16dfcf3f067 100644 --- a/clang/test/CodeGenCXX/int64_uint64.cpp +++ b/clang/test/CodeGenCXX/int64_uint64.cpp @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm-linux-guneabi \ // RUN: -target-cpu cortex-a8 \ // RUN: -emit-llvm -w -O1 -o - %s | FileCheck --check-prefix=CHECK-ARM %s diff --git a/clang/test/CodeGenCXX/poly-unsigned.cpp b/clang/test/CodeGenCXX/poly-unsigned.cpp index e2ab430a969ed..831edd704f517 100644 --- a/clang/test/CodeGenCXX/poly-unsigned.cpp +++ b/clang/test/CodeGenCXX/poly-unsigned.cpp @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-ios -target-feature +neon -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s // RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s // RUN: %clang_cc1 -triple armv7-apple-ios -ffreestanding -target-cpu cortex-a8 -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-SIGNED-POLY %s diff --git a/clang/test/Headers/arm-cde-header.c b/clang/test/Headers/arm-cde-header.c index 694483e66960b..ea8a4fef886e4 100644 --- a/clang/test/Headers/arm-cde-header.c +++ b/clang/test/Headers/arm-cde-header.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -std=c89 -triple thumbv8.1m.main-none-none-eabi -fallow-half-arguments-and-returns -target-feature +mve.fp -target-feature +cdecp0 -fsyntax-only %s // RUN: %clang_cc1 -std=c17 -triple thumbv8.1m.main-none-none-eabi -fallow-half-arguments-and-returns -target-feature +mve -target-feature +cdecp0 -fsyntax-only %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -fallow-half-arguments-and-returns -target-feature +mve.fp -target-feature +cdecp0 -fsyntax-only %s diff --git a/clang/test/Headers/arm-fp16-header.c b/clang/test/Headers/arm-fp16-header.c index 85068bb892779..8016b670b1fcb 100644 --- a/clang/test/Headers/arm-fp16-header.c +++ b/clang/test/Headers/arm-fp16-header.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang -fsyntax-only -ffreestanding --target=aarch64-none-eabi -march=armv8.2-a+fp16 -std=c89 -xc %s // RUN: %clang -fsyntax-only -Wall -Werror -ffreestanding --target=aarch64-none-eabi -march=armv8.2-a+fp16 -std=c99 -xc %s // RUN: %clang -fsyntax-only -Wall -Werror -ffreestanding --target=aarch64-none-eabi -march=armv8.2-a+fp16 -std=c11 -xc %s diff --git a/clang/test/Headers/arm-neon-header.c b/clang/test/Headers/arm-neon-header.c index 8f64633b44d56..5ad363b1d36fc 100644 --- a/clang/test/Headers/arm-neon-header.c +++ b/clang/test/Headers/arm-neon-header.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -Wvector-conversions -ffreestanding %s // RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -flax-vector-conversions=none -ffreestanding %s // RUN: %clang_cc1 -x c++ -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -Wvector-conversions -ffreestanding %s diff --git a/clang/test/Headers/riscv-vector-header.c b/clang/test/Headers/riscv-vector-header.c index beb54a30ee709..ce618b5a717e1 100644 --- a/clang/test/Headers/riscv-vector-header.c +++ b/clang/test/Headers/riscv-vector-header.c @@ -1,3 +1,5 @@ +// REQUIRES: riscv-registered-target + // RUN: %clang_cc1 -triple riscv64 -fsyntax-only \ // RUN: -target-feature +m -target-feature +a -target-feature +f \ // RUN: -target-feature +d -target-feature +experimental-v %s diff --git a/clang/test/Sema/aarch64-bf16-ldst-intrinsics.c b/clang/test/Sema/aarch64-bf16-ldst-intrinsics.c index acf4e02fdf934..e21dd0b53e1fc 100644 --- a/clang/test/Sema/aarch64-bf16-ldst-intrinsics.c +++ b/clang/test/Sema/aarch64-bf16-ldst-intrinsics.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-feature +neon -target-feature +bf16 \ // RUN: -O2 -fallow-half-arguments-and-returns -verify -fsyntax-only %s diff --git a/clang/test/Sema/aarch64-neon-bf16-ranges.c b/clang/test/Sema/aarch64-neon-bf16-ranges.c index bbed036846e57..671c66eca9b3e 100644 --- a/clang/test/Sema/aarch64-neon-bf16-ranges.c +++ b/clang/test/Sema/aarch64-neon-bf16-ranges.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -fsyntax-only -verify \ // RUN: -triple aarch64-arm-none-eabi -target-feature +neon \ // RUN: -target-feature +bf16 %s diff --git a/clang/test/Sema/aarch64-neon-fp16-ranges.c b/clang/test/Sema/aarch64-neon-fp16-ranges.c index 60190525e042a..806365925d9db 100644 --- a/clang/test/Sema/aarch64-neon-fp16-ranges.c +++ b/clang/test/Sema/aarch64-neon-fp16-ranges.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-linux-gnu -fallow-half-arguments-and-returns -target-feature +neon -target-feature +fullfp16 -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -triple aarch64-linux-gnu -fallow-half-arguments-and-returns -target-feature +fullfp16 -target-feature +neon -ffreestanding -fsyntax-only -verify %s diff --git a/clang/test/Sema/aarch64-neon-ranges.c b/clang/test/Sema/aarch64-neon-ranges.c index f9b652fc9bf5b..01dc9d34c0eea 100644 --- a/clang/test/Sema/aarch64-neon-ranges.c +++ b/clang/test/Sema/aarch64-neon-ranges.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s diff --git a/clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c b/clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c index a93110db7cce0..6c32f946acffc 100644 --- a/clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c +++ b/clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=128 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=256 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s diff --git a/clang/test/Sema/aarch64-sve-lax-vector-conversions.c b/clang/test/Sema/aarch64-sve-lax-vector-conversions.c index 1a1addcf1c1ba..7ae9d7c68aa25 100644 --- a/clang/test/Sema/aarch64-sve-lax-vector-conversions.c +++ b/clang/test/Sema/aarch64-sve-lax-vector-conversions.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify=lax-vector-none %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=integer -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify=lax-vector-integer %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=all -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify=lax-vector-all %s diff --git a/clang/test/Sema/arm-bfloat.cpp b/clang/test/Sema/arm-bfloat.cpp index ce3fc44baa39f..8c2eadeed7959 100644 --- a/clang/test/Sema/arm-bfloat.cpp +++ b/clang/test/Sema/arm-bfloat.cpp @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \ // RUN: -triple aarch64-arm-none-eabi -target-cpu cortex-a75 \ // RUN: -target-feature +bf16 -target-feature +neon %s diff --git a/clang/test/Sema/arm-cde-immediates.c b/clang/test/Sema/arm-cde-immediates.c index 7e5725e446601..e3b440e4800af 100644 --- a/clang/test/Sema/arm-cde-immediates.c +++ b/clang/test/Sema/arm-cde-immediates.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -fallow-half-arguments-and-returns -target-feature +mve.fp -target-feature +cdecp0 -verify -fsyntax-only %s #include diff --git a/clang/test/Sema/arm-mve-immediates.c b/clang/test/Sema/arm-mve-immediates.c index 508513ee6156f..e447fa592ae6b 100644 --- a/clang/test/Sema/arm-mve-immediates.c +++ b/clang/test/Sema/arm-mve-immediates.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -fallow-half-arguments-and-returns -target-feature +mve.fp -verify -fsyntax-only %s #include diff --git a/clang/test/Sema/arm-neon-types.c b/clang/test/Sema/arm-neon-types.c index 989f20ab20ec5..48af89616ad59 100644 --- a/clang/test/Sema/arm-neon-types.c +++ b/clang/test/Sema/arm-neon-types.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7-apple-darwin10 -target-cpu cortex-a8 -fsyntax-only -Wvector-conversion -ffreestanding -verify %s #ifndef INCLUDE diff --git a/clang/test/Sema/arm-no-fp16.c b/clang/test/Sema/arm-no-fp16.c index 91c48483f295c..000b82c3feb47 100644 --- a/clang/test/Sema/arm-no-fp16.c +++ b/clang/test/Sema/arm-no-fp16.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7-none-eabi %s -target-feature +neon \ // RUN: -fallow-half-arguments-and-returns -target-feature -fp16 \ // RUN: -fsyntax-only -verify diff --git a/clang/test/Sema/arm64-neon-args.c b/clang/test/Sema/arm64-neon-args.c index a6c4f13a4316b..a797239a87fbd 100644 --- a/clang/test/Sema/arm64-neon-args.c +++ b/clang/test/Sema/arm64-neon-args.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-darwin -target-feature +neon -fsyntax-only -ffreestanding -verify %s // RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -target-feature +neon -fsyntax-only -ffreestanding -verify %s diff --git a/clang/test/Sema/arm64-neon-header.c b/clang/test/Sema/arm64-neon-header.c index 640cc76fd9952..d23308b437a8c 100644 --- a/clang/test/Sema/arm64-neon-header.c +++ b/clang/test/Sema/arm64-neon-header.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple arm64-apple-darwin -target-feature +neon -Wvector-conversion -fsyntax-only -ffreestanding -verify %s #include diff --git a/clang/test/Sema/arm_vfma.c b/clang/test/Sema/arm_vfma.c index 8c08b4d8b9e7d..d3a21fa31c6f3 100644 --- a/clang/test/Sema/arm_vfma.c +++ b/clang/test/Sema/arm_vfma.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple thumbv7-none-eabi -target-feature +neon -target-feature +vfp4 -fsyntax-only -verify %s #include diff --git a/clang/test/Sema/big-endian-neon-initializers.c b/clang/test/Sema/big-endian-neon-initializers.c index c706d007509cf..c62c720e366ce 100644 --- a/clang/test/Sema/big-endian-neon-initializers.c +++ b/clang/test/Sema/big-endian-neon-initializers.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 %s -triple aarch64_be -target-feature +neon -verify -fsyntax-only -ffreestanding // RUN: %clang_cc1 %s -triple armebv7 -target-cpu cortex-a8 -verify -fsyntax-only -ffreestanding diff --git a/clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp b/clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp index 616984781edb1..af819f2e41a0a 100644 --- a/clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp +++ b/clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=128 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=256 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s diff --git a/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp b/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp index 2cd4af0bb0045..fb98dc67bb895 100644 --- a/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp +++ b/clang/test/SemaCXX/aarch64-sve-lax-vector-conversions.cpp @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify=lax-vector-none %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=integer -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify=lax-vector-integer %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=all -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify=lax-vector-all %s From b987701c0c7c9faa0443b3888e842c096e520572 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 9 Nov 2021 23:41:41 +0000 Subject: [PATCH 018/293] test: mark more ARM64 tests are requiring the ARM backend These do not seem to be needed upstream, but mark these tests as requiring either ARM or ARM64 enabled which will generate the resource headers. --- clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c | 2 ++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c | 2 ++ .../test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c | 2 ++ .../test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c | 2 ++ clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c | 2 ++ 79 files changed, 158 insertions(+) diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c index 62258237bc5ef..a0748007005ff 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfdot.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c index 8669de8ea3224..28e1402ca9179 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c index 006ff6bc3200b..65918043d6768 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_bfmlalt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c index 6f0e4daaa2d6c..6f21e9be921e1 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_sudot.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +i8mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c index e77f509b22c3f..e38821ca7cf03 100644 --- a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_usdot.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -target-feature +i8mm -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -target-feature +i8mm -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c index 57ef110e09204..5fe722a4a181d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_aba.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c index 28f4d38f81f11..049e1b8afe4d4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c index fb281da93b0df..68cd274008703 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abalt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c index 1c59ec6110a5a..122fc925ee5d1 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c index ed5a692d94a24..e0646b1e92c6b 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_abdlt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c index 55c0f3c70577b..c6f7ffa811940 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c index 4f11e63fd41ea..f9de86921d179 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_adclt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c index e325d0098caa0..16a52f37746c4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c index bcb68970513b7..8d522b45a3152 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addhnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c index affe1c78393ed..e05d69d136ab6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c index c729ea91675f3..4a5862201898d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlbt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c index 88a0966e897e9..7218ab4027ff3 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addlt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c index cd3519c3217ff..5f18d182c02eb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c index d038c42d9d0a3..e34261567cd33 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_addwt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c index 874f111bf09f1..220bd5fa05638 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bcax.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c index f30c16dd2a742..dc88972d14ce6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bdep.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c index 462c87044bc24..78b0aac8ab177 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bext.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c index b8b178dbde8a7..74066d8c89504 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bgrp.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c index dc5fdd75f3bd7..8c3d748e575f4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c index 15907841949b8..3c8cb2426c4a0 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl1n.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c index 67fb0d5381b51..27fcf3d2fd6a6 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_bsl2n.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c index 5efa4fd866628..813f512632cb7 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eor3.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c index 262d41fbd355a..ce1406eccf3a2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eorbt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c index 0b305f15ce768..c68c2a82b28cb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_eortb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c index 9f70269dfea38..5491e48d9480a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c index efce49325e2b3..17e1d99941712 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsub.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c index 381b760db8544..e7876355215ec 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_hsubr.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c index 9efa5f168f558..b29065c5a2502 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c index 95d3eac914c82..4f7481e3b9d35 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlalt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c index f96e1d9dba4c7..134881913e9b8 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c index 458ddd26c2a37..b4f2a46f60a66 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mlslt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c index c8f6166e708d4..7ccdbefc250bf 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c index 13ac0f34e905c..ab65c4cd96819 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_mullt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c index 444606b295a03..3cd6d44e08c6a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_nbsl.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c index c0f9b4e5f31c4..1ded1bbcc15f1 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmul.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c index c7be4eac2d751..f1f482792c911 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c index 41bd143e11a57..7b4adb5a49f1f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullb_128.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c index e196e9bf0dbbd..3a4d72b660955 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c index 398e876ab1839..483a8fc3cd230 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_pmullt_128.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2-aes -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c index 3d843dcf642f3..485be20ea2f63 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c index 51073ec47c9ef..4176eaa1105eb 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c index 59082de1c3092..3dd9c9e84f53f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalbt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c index 605bce53b0916..e3b927846af1d 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlalt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c index f331e6f24d1fc..315a4904f5ee2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c index 4584e4ff5d7e4..648bcc05ab6a2 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslbt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c index 52694173d2a9d..cd328b7c5fe29 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmlslt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c index 7d48bca9c7be3..11e18ccd42822 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmulh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c index 62fb6ecde66fd..5528ef5faa704 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c index df4262e548747..1ac5b401f87b4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qdmullt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c index 5cc49a713072a..3d9f8abed69f1 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlah.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c index 3838bdc53e1ef..a66bfde9c8397 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmlsh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c index e009441ffcbfd..5152bca692493 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrdmulh.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c index 475e2ef221176..fff46bfc39e9f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qrshl.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c index 23aea5df55d61..bba33e304bad5 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qshl.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c index 2522cc4aacf71..7f9ec2b003b6a 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsub.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c index 2150fd13f69c5..d0cab69d8a1e4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_qsubr.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c index 204731fce79ef..a376010384ecd 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c index 15c0e9025b508..ea4efaea650f4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_raddhnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c index 6e4f5ca98aa80..4fe87013b6911 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rhadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c index 4debc2d6555e1..231a753b71e73 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rshl.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c index 8e7532c66f262..d3bcd22887715 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c index 0ca5ca1ea1ef4..a8b378265701e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_rsubhnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c index 7686f3d6f1edd..67f2703f03c1f 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c index a9c1f3a48251c..713c3c8048f88 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sbclt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c index fcb023320040e..4c556312134b4 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sqadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c index c56d5d0f710e3..dc8930404c330 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c index 4864fb9401822..1189bdbc02011 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subhnt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c index 988be977ce2da..e38562b64dd40 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c index 02afe3e0cbcb4..78f7397a9406e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublbt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c index 4a8bd9635043b..19bcb5601c2ab 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_sublt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c index 36c7561145661..e590fdf77a261 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subltb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c index 1f86b5edb252e..00d8818aa9c7e 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwb.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c index 9e72444ce958c..8f65c3c676d51 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_subwt.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c index 72b96cfc84531..e04a0e20d4df9 100644 --- a/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c +++ b/clang/test/CodeGen/aarch64-sve2-intrinsics/acle_sve2_uqadd.c @@ -1,3 +1,5 @@ +// REQUIRES: aarch64-registered-target || arm-registered-target + // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - -x c++ %s | FileCheck %s // RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2 -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s From 2d7f32ae1df06eae5a732190a5db9cce7c9e4ef3 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 9 Nov 2021 23:17:07 -0800 Subject: [PATCH 019/293] [ObjC][ARC] Use the addresses of the ARC runtime functions instead of integer 0/1 for the operand of bundle "clang.arc.attachedcall" (#3518) * Refactor inlineRetainOrClaimRVCalls. NFC This is in preparation for committing https://reviews.llvm.org/D103000. (cherry picked from commit 898dc4590c4fcf230531be7f9a0099632e8af78c) * [ObjC][ARC] Use the addresses of the ARC runtime functions instead of integer 0/1 for the operand of bundle "clang.arc.attachedcall" This should make it easier to understand what the IR is doing and also simplify some of the passes as they no longer have to translate the integer values to the runtime functions. Differential Revision: https://reviews.llvm.org/D102996 (cherry picked from commit 59cc39ae141f92c01836064cd033c537f16dec5e) * [ObjC][ARC] Use the addresses of the ARC runtime functions instead of integer 0/1 for the operand of bundle "clang.arc.attachedcall" https://reviews.llvm.org/D102996 changes the operand of bundle "clang.arc.attachedcall". This patch makes changes to llvm that are needed to handle the new IR. This should make it easier to understand what the IR is doing and also simplify some of the passes as they no longer have to translate the integer values to the runtime functions. Differential Revision: https://reviews.llvm.org/D103000 (cherry picked from commit dea6f71af0fdd7c54cacd43f5fb15e293924fa20) --- clang/lib/CodeGen/CGObjC.cpp | 80 ++++++++---------- clang/test/CodeGenObjC/arc-rv-attr.m | 20 ++--- clang/test/CodeGenObjCXX/arc-rv-attr.mm | 2 +- llvm/docs/LangRef.rst | 26 ++++-- llvm/include/llvm/Analysis/ObjCARCUtil.h | 41 ++++++---- llvm/include/llvm/IR/Function.h | 9 +- llvm/include/llvm/IR/InstrTypes.h | 7 ++ llvm/lib/IR/Function.cpp | 9 +- llvm/lib/IR/Verifier.cpp | 72 ++++++++++++---- llvm/lib/Target/X86/X86ExpandPseudo.cpp | 11 +-- llvm/lib/Target/X86/X86ISelLowering.cpp | 14 ++-- llvm/lib/Target/X86/X86InstrCompiler.td | 8 +- llvm/lib/Target/X86/X86InstrControl.td | 6 +- llvm/lib/Transforms/ObjCARC/ObjCARC.cpp | 25 ++++-- llvm/lib/Transforms/ObjCARC/ObjCARC.h | 4 +- .../Transforms/ObjCARC/ObjCARCContract.cpp | 2 +- llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 2 +- llvm/lib/Transforms/Utils/InlineFunction.cpp | 82 ++++++++++--------- llvm/test/CodeGen/AArch64/call-rv-marker.ll | 12 +-- llvm/test/CodeGen/X86/call-rv-marker.ll | 18 ++-- .../test/CodeGen/X86/expand-call-rvmarker.mir | 8 +- .../test/Transforms/DeadArgElim/deadretval.ll | 6 +- .../Transforms/Inline/inline-retainRV-call.ll | 48 +++++------ .../ObjCARC/contract-marker-funclet.ll | 8 +- .../Transforms/ObjCARC/contract-rv-attr.ll | 23 +++--- llvm/test/Transforms/ObjCARC/rv.ll | 6 +- llvm/test/Transforms/SCCP/clang-arc-rv.ll | 3 +- .../Transforms/TailCallElim/deopt-bundle.ll | 4 +- llvm/test/Verifier/invoke.ll | 2 +- llvm/test/Verifier/operand-bundles.ll | 36 ++++++-- 30 files changed, 349 insertions(+), 245 deletions(-) diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index b71d839e029f8..accc926dbde16 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -2108,6 +2108,13 @@ static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, setARCRuntimeFunctionLinkage(CGM, RTF.getCallee()); } +static llvm::Function *getARCIntrinsic(llvm::Intrinsic::ID IntID, + CodeGenModule &CGM) { + llvm::Function *fn = CGM.getIntrinsic(IntID); + setARCRuntimeFunctionLinkage(CGM, fn); + return fn; +} + /// Perform an operation having the signature /// i8* (i8*) /// where a null input causes a no-op and returns null. @@ -2118,10 +2125,8 @@ static llvm::Value *emitARCValueOperation( if (isa(value)) return value; - if (!fn) { - fn = CGF.CGM.getIntrinsic(IntID); - setARCRuntimeFunctionLinkage(CGF.CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(IntID, CGF.CGM); // Cast the argument to 'id'. llvm::Type *origType = returnType ? returnType : value->getType(); @@ -2140,10 +2145,8 @@ static llvm::Value *emitARCValueOperation( static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr, llvm::Function *&fn, llvm::Intrinsic::ID IntID) { - if (!fn) { - fn = CGF.CGM.getIntrinsic(IntID); - setARCRuntimeFunctionLinkage(CGF.CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(IntID, CGF.CGM); // Cast the argument to 'id*'. llvm::Type *origType = addr.getElementType(); @@ -2168,10 +2171,8 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr, bool ignored) { assert(addr.getElementType() == value->getType()); - if (!fn) { - fn = CGF.CGM.getIntrinsic(IntID); - setARCRuntimeFunctionLinkage(CGF.CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(IntID, CGF.CGM); llvm::Type *origType = value->getType(); @@ -2193,10 +2194,8 @@ static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, llvm::Intrinsic::ID IntID) { assert(dst.getType() == src.getType()); - if (!fn) { - fn = CGF.CGM.getIntrinsic(IntID); - setARCRuntimeFunctionLinkage(CGF.CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(IntID, CGF.CGM); llvm::Value *args[] = { CGF.Builder.CreateBitCast(dst.getPointer(), CGF.Int8PtrPtrTy), @@ -2340,13 +2339,19 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value, // retainRV or claimRV calls in the IR. We currently do this only when the // optimization level isn't -O0 since global-isel, which is currently run at // -O0, doesn't know about the operand bundle. + ObjCEntrypoints &EPs = CGF.CGM.getObjCEntrypoints(); + llvm::Function *&EP = IsRetainRV + ? EPs.objc_retainAutoreleasedReturnValue + : EPs.objc_unsafeClaimAutoreleasedReturnValue; + llvm::Intrinsic::ID IID = + IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue + : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue; + EP = getARCIntrinsic(IID, CGF.CGM); // FIXME: Do this when the target isn't aarch64. if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && CGF.CGM.getTarget().getTriple().isAArch64()) { - llvm::Value *bundleArgs[] = {llvm::ConstantInt::get( - CGF.Int64Ty, - llvm::objcarc::getAttachedCallOperandBundleEnum(IsRetainRV))}; + llvm::Value *bundleArgs[] = {EP}; llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs); auto *oldCall = cast(value); llvm::CallBase *newCall = llvm::CallBase::addOperandBundle( @@ -2362,13 +2367,6 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value, CGF.CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail(); llvm::CallInst::TailCallKind tailKind = isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None; - ObjCEntrypoints &EPs = CGF.CGM.getObjCEntrypoints(); - llvm::Function *&EP = IsRetainRV - ? EPs.objc_retainAutoreleasedReturnValue - : EPs.objc_unsafeClaimAutoreleasedReturnValue; - llvm::Intrinsic::ID IID = - IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue - : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue; return emitARCValueOperation(CGF, value, nullptr, EP, IID, tailKind); } @@ -2401,10 +2399,8 @@ void CodeGenFunction::EmitARCRelease(llvm::Value *value, if (isa(value)) return; llvm::Function *&fn = CGM.getObjCEntrypoints().objc_release; - if (!fn) { - fn = CGM.getIntrinsic(llvm::Intrinsic::objc_release); - setARCRuntimeFunctionLinkage(CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(llvm::Intrinsic::objc_release, CGM); // Cast the argument to 'id'. value = Builder.CreateBitCast(value, Int8PtrTy); @@ -2447,10 +2443,8 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr, assert(addr.getElementType() == value->getType()); llvm::Function *&fn = CGM.getObjCEntrypoints().objc_storeStrong; - if (!fn) { - fn = CGM.getIntrinsic(llvm::Intrinsic::objc_storeStrong); - setARCRuntimeFunctionLinkage(CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(llvm::Intrinsic::objc_storeStrong, CGM); llvm::Value *args[] = { Builder.CreateBitCast(addr.getPointer(), Int8PtrPtrTy), @@ -2603,10 +2597,8 @@ void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) { /// Essentially objc_storeWeak(addr, nil). void CodeGenFunction::EmitARCDestroyWeak(Address addr) { llvm::Function *&fn = CGM.getObjCEntrypoints().objc_destroyWeak; - if (!fn) { - fn = CGM.getIntrinsic(llvm::Intrinsic::objc_destroyWeak); - setARCRuntimeFunctionLinkage(CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(llvm::Intrinsic::objc_destroyWeak, CGM); // Cast the argument to 'id*'. addr = Builder.CreateBitCast(addr, Int8PtrPtrTy); @@ -2651,10 +2643,8 @@ void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr, /// call i8* \@objc_autoreleasePoolPush(void) llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() { llvm::Function *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush; - if (!fn) { - fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush); - setARCRuntimeFunctionLinkage(CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush, CGM); return EmitNounwindRuntimeCall(fn); } @@ -2679,10 +2669,8 @@ void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) { EmitRuntimeCallOrInvoke(fn, value); } else { llvm::FunctionCallee &fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop; - if (!fn) { - fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop); - setARCRuntimeFunctionLinkage(CGM, fn); - } + if (!fn) + fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop, CGM); EmitRuntimeCall(fn, value); } diff --git a/clang/test/CodeGenObjC/arc-rv-attr.m b/clang/test/CodeGenObjC/arc-rv-attr.m index 73e835e027178..f341f735d720e 100644 --- a/clang/test/CodeGenObjC/arc-rv-attr.m +++ b/clang/test/CodeGenObjC/arc-rv-attr.m @@ -10,7 +10,7 @@ void test_assign() { } // CHECK-LABEL: define{{.*}} void @test_assign() // CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ] +// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: store i8* [[T1]], i8** [[X]] @@ -25,7 +25,7 @@ void test_assign_assign() { // CHECK-LABEL: define{{.*}} void @test_assign_assign() // CHECK: [[X:%.*]] = alloca i8* // CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] @@ -44,7 +44,7 @@ void test_strong_assign_assign() { // CHECK-LABEL: define{{.*}} void @test_strong_assign_assign() // CHECK: [[X:%.*]] = alloca i8* // CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] @@ -67,7 +67,7 @@ void test_assign_strong_assign() { // CHECK-LABEL: define{{.*}} void @test_assign_strong_assign() // CHECK: [[X:%.*]] = alloca i8* // CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]] @@ -87,7 +87,7 @@ void test_init() { } // CHECK-LABEL: define{{.*}} void @test_init() // CHECK: [[X:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: store i8* [[T1]], i8** [[X]] @@ -102,7 +102,7 @@ void test_init_assignment() { // CHECK-LABEL: define{{.*}} void @test_init_assignment() // CHECK: [[X:%.*]] = alloca i8* // CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: store i8* [[T1]], i8** [[X]] @@ -120,7 +120,7 @@ void test_strong_init_assignment() { // CHECK-LABEL: define{{.*}} void @test_strong_init_assignment() // CHECK: [[X:%.*]] = alloca i8* // CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: store i8* [[T1]], i8** [[X]] @@ -140,7 +140,7 @@ void test_init_strong_assignment() { // CHECK-LABEL: define{{.*}} void @test_init_strong_assignment() // CHECK: [[X:%.*]] = alloca i8* // CHECK: [[Y:%.*]] = alloca i8* -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 0) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] @@ -159,7 +159,7 @@ void test_ignored() { makeA(); } // CHECK-LABEL: define{{.*}} void @test_ignored() -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: ret void @@ -167,7 +167,7 @@ void test_cast_to_void() { (void)makeA(); } // CHECK-LABEL: define{{.*}} void @test_cast_to_void() -// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i64 1) ] +// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenObjCXX/arc-rv-attr.mm b/clang/test/CodeGenObjCXX/arc-rv-attr.mm index 0f4519bd527d9..85d5787d50dce 100644 --- a/clang/test/CodeGenObjCXX/arc-rv-attr.mm +++ b/clang/test/CodeGenObjCXX/arc-rv-attr.mm @@ -3,7 +3,7 @@ id foo(void); // CHECK-LABEL: define{{.*}} void @_Z14test_list_initv( -// CHECK: %[[CALL1:.*]] = call i8* @_Z3foov() [ "clang.arc.attachedcall"(i64 0) ] +// CHECK: %[[CALL1:.*]] = call i8* @_Z3foov() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] // CHECK: call i8* @llvm.objc.retain(i8* %[[CALL1]]) void test_list_init() { diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 7053e7f7f3419..4c774c4be8973 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2459,14 +2459,26 @@ for further details. ObjC ARC Attached Call Operand Bundles ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A ``"clang.arc.attachedcall`` operand bundle on a call indicates the call is +A ``"clang.arc.attachedcall"`` operand bundle on a call indicates the call is implicitly followed by a marker instruction and a call to an ObjC runtime -function that uses the result of the call. If the argument passed to the operand -bundle is 0, ``@objc_retainAutoreleasedReturnValue`` is called. If 1 is passed, -``@objc_unsafeClaimAutoreleasedReturnValue`` is called. The return value of a -call with this bundle is used by a call to ``@llvm.objc.clang.arc.noop.use`` -unless the called function's return type is void, in which case the operand -bundle is ignored. +function that uses the result of the call. The operand bundle takes either the +pointer to the runtime function (``@objc_retainAutoreleasedReturnValue`` or +``@objc_unsafeClaimAutoreleasedReturnValue``) or no arguments. If the bundle +doesn't take any arguments, only the marker instruction has to be emitted after +the call; the runtime function calls don't have to be emitted since they already +have been emitted. The return value of a call with this bundle is used by a call +to ``@llvm.objc.clang.arc.noop.use`` unless the called function's return type is +void, in which case the operand bundle is ignored. + +.. code-block:: llvm + + ; The marker instruction and a runtime function call are inserted after the call + ; to @foo. + call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] + call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_unsafeClaimAutoreleasedReturnValue) ] + + ; Only the marker instruction is inserted after the call to @foo. + call i8* @foo() [ "clang.arc.attachedcall"() ] The operand bundle is needed to ensure the call is immediately followed by the marker instruction or the ObjC runtime call in the final output. diff --git a/llvm/include/llvm/Analysis/ObjCARCUtil.h b/llvm/include/llvm/Analysis/ObjCARCUtil.h index 2566bfbcf61cc..66699062f9711 100644 --- a/llvm/include/llvm/Analysis/ObjCARCUtil.h +++ b/llvm/include/llvm/Analysis/ObjCARCUtil.h @@ -14,6 +14,8 @@ #ifndef LLVM_IR_OBJCARCUTIL_H #define LLVM_IR_OBJCARCUTIL_H +#include "llvm/Analysis/ObjCARCInstKind.h" +#include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/LLVMContext.h" @@ -24,13 +26,6 @@ inline const char *getRVMarkerModuleFlagStr() { return "clang.arc.retainAutoreleasedReturnValueMarker"; } -enum AttachedCallOperandBundle : unsigned { RVOB_Retain, RVOB_Claim }; - -inline AttachedCallOperandBundle -getAttachedCallOperandBundleEnum(bool IsRetain) { - return IsRetain ? RVOB_Retain : RVOB_Claim; -} - inline bool hasAttachedCallOpBundle(const CallBase *CB) { // Ignore the bundle if the return type is void. Global optimization passes // can turn the called function's return type to void. That should happen only @@ -43,14 +38,32 @@ inline bool hasAttachedCallOpBundle(const CallBase *CB) { .hasValue(); } -inline bool hasAttachedCallOpBundle(const CallBase *CB, bool IsRetain) { - assert(hasAttachedCallOpBundle(CB) && - "call doesn't have operand bundle clang_arc_attachedcall"); +/// This function returns operand bundle clang_arc_attachedcall's argument, +/// which is the address of the ARC runtime function. +inline Optional getAttachedARCFunction(const CallBase *CB) { auto B = CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall); - if (!B.hasValue()) - return false; - return cast(B->Inputs[0])->getZExtValue() == - getAttachedCallOperandBundleEnum(IsRetain); + if (!B.hasValue() || B->Inputs.size() == 0) + return None; + + return cast(B->Inputs[0]); +} + +/// Check whether the function is retainRV/claimRV. +inline bool isRetainOrClaimRV(ARCInstKind Kind) { + return Kind == ARCInstKind::RetainRV || Kind == ARCInstKind::ClaimRV; +} + +/// This function returns the ARCInstKind of the function attached to operand +/// bundle clang_arc_attachedcall. It returns None if the call doesn't have the +/// operand bundle or the operand is null. Otherwise it returns either RetainRV +/// or ClaimRV. +inline ARCInstKind getAttachedARCFunctionKind(const CallBase *CB) { + Optional Fn = getAttachedARCFunction(CB); + if (!Fn.hasValue()) + return ARCInstKind::None; + auto FnClass = GetFunctionClass(*Fn); + assert(isRetainOrClaimRV(FnClass) && "unexpected ARC runtime function"); + return FnClass; } } // end namespace objcarc diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index e0094e2afff2a..f6942ff5a519b 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -904,13 +904,14 @@ class Function : public GlobalObject, public ilist_node { /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it, or blockaddress expressions. /// Optionally passes back an offending user for diagnostic purposes, - /// ignores callback uses, assume like pointer annotation calls, and - /// references in llvm.used and llvm.compiler.used variables. - /// + /// ignores callback uses, assume like pointer annotation calls, references in + /// llvm.used and llvm.compiler.used variables, and operand bundle + /// "clang.arc.attachedcall". bool hasAddressTaken(const User ** = nullptr, bool IgnoreCallbackUses = false, bool IgnoreAssumeLikeCalls = true, - bool IngoreLLVMUsed = false) const; + bool IngoreLLVMUsed = false, + bool IgnoreARCAttachedCall = false) const; /// isDefTriviallyDead - Return true if it is trivially safe to remove /// this function definition from the module (because it isn't externally diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index e50dc32356775..83b2f111e5119 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1918,6 +1918,13 @@ class CallBase : public Instruction { Idx < getBundleOperandsEndIndex(); } + /// Return true if the operand at index \p Idx is a bundle operand that has + /// tag ID \p ID. + bool isOperandBundleOfType(uint32_t ID, unsigned Idx) const { + return isBundleOperand(Idx) && + getOperandBundleForOperand(Idx).getTagID() == ID; + } + /// Returns true if the use is a bundle operand. bool isBundleOperand(const Use *U) const { assert(this == U->getUser() && diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 4034b1505bd01..ba9ad7b017c99 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -1702,8 +1702,8 @@ Optional Intrinsic::remangleIntrinsicFunction(Function *F) { /// and llvm.compiler.used variables. bool Function::hasAddressTaken(const User **PutOffender, bool IgnoreCallbackUses, - bool IgnoreAssumeLikeCalls, - bool IgnoreLLVMUsed) const { + bool IgnoreAssumeLikeCalls, bool IgnoreLLVMUsed, + bool IgnoreARCAttachedCall) const { for (const Use &U : uses()) { const User *FU = U.getUser(); if (isa(FU)) @@ -1747,6 +1747,11 @@ bool Function::hasAddressTaken(const User **PutOffender, return true; } if (!Call->isCallee(&U)) { + if (IgnoreARCAttachedCall && + Call->isOperandBundleOfType(LLVMContext::OB_clang_arc_attachedcall, + U.getOperandNo())) + continue; + if (PutOffender) *PutOffender = FU; return true; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index baeb570692a90..213ebe2f5367c 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -570,6 +570,9 @@ class Verifier : public InstVisitor, VerifierSupport { /// declarations share the same calling convention. void verifyDeoptimizeCallingConvs(); + void verifyAttachedCallBundle(const CallBase &Call, + const OperandBundleUse &BU); + /// Verify all-or-nothing property of DIFile source attribute within a CU. void verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F); @@ -2595,7 +2598,8 @@ void Verifier::visitFunction(const Function &F) { // uses. if (F.isIntrinsic() && F.getParent()->isMaterialized()) { const User *U; - if (F.hasAddressTaken(&U)) + if (F.hasAddressTaken(&U, false, true, false, + /*IgnoreARCAttachedCall=*/true)) Assert(false, "Invalid user of intrinsic instruction!", U); } @@ -3347,17 +3351,10 @@ void Verifier::visitCallBase(CallBase &Call) { Assert(!FoundAttachedCallBundle, "Multiple \"clang.arc.attachedcall\" operand bundles", Call); FoundAttachedCallBundle = true; + verifyAttachedCallBundle(Call, BU); } } - if (FoundAttachedCallBundle) - Assert((FTy->getReturnType()->isPointerTy() || - (Call.doesNotReturn() && FTy->getReturnType()->isVoidTy())), - "a call with operand bundle \"clang.arc.attachedcall\" must call a " - "function returning a pointer or a non-returning function that has " - "a void return type", - Call); - // Verify that each inlinable callsite of a debug-info-bearing function in a // debug-info-bearing function has a debug location attached to it. Failure to // do so causes assertion failures when the inliner sets up inline scope info. @@ -4502,10 +4499,21 @@ void Verifier::visitInstruction(Instruction &I) { } if (Function *F = dyn_cast(I.getOperand(i))) { + // This code checks whether the function is used as the operand of a + // clang_arc_attachedcall operand bundle. + auto IsAttachedCallOperand = [](Function *F, const CallBase *CBI, + int Idx) { + return CBI && CBI->isOperandBundleOfType( + LLVMContext::OB_clang_arc_attachedcall, Idx); + }; + // Check to make sure that the "address of" an intrinsic function is never - // taken. - Assert(!F->isIntrinsic() || - (CBI && &CBI->getCalledOperandUse() == &I.getOperandUse(i)), + // taken. Ignore cases where the address of the intrinsic function is used + // as the argument of operand bundle "clang.arc.attachedcall" as those + // cases are handled in verifyAttachedCallBundle. + Assert((!F->isIntrinsic() || + (CBI && &CBI->getCalledOperandUse() == &I.getOperandUse(i)) || + IsAttachedCallOperand(F, CBI, i)), "Cannot take the address of an intrinsic!", &I); Assert( !F->isIntrinsic() || isa(I) || @@ -4519,9 +4527,10 @@ void Verifier::visitInstruction(Instruction &I) { F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void || F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 || F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint || - F->getIntrinsicID() == Intrinsic::wasm_rethrow, + F->getIntrinsicID() == Intrinsic::wasm_rethrow || + IsAttachedCallOperand(F, CBI, i), "Cannot invoke an intrinsic other than donothing, patchpoint, " - "statepoint, coro_resume or coro_destroy", + "statepoint, coro_resume, coro_destroy or clang.arc.attachedcall", &I); Assert(F->getParent() == &M, "Referencing function in another module!", &I, &M, F, F->getParent()); @@ -5742,6 +5751,41 @@ void Verifier::verifyDeoptimizeCallingConvs() { } } +void Verifier::verifyAttachedCallBundle(const CallBase &Call, + const OperandBundleUse &BU) { + FunctionType *FTy = Call.getFunctionType(); + + Assert((FTy->getReturnType()->isPointerTy() || + (Call.doesNotReturn() && FTy->getReturnType()->isVoidTy())), + "a call with operand bundle \"clang.arc.attachedcall\" must call a " + "function returning a pointer or a non-returning function that has a " + "void return type", + Call); + + Assert((BU.Inputs.empty() || + (BU.Inputs.size() == 1 && isa(BU.Inputs.front()))), + "operand bundle \"clang.arc.attachedcall\" can take either no " + "arguments or one function as an argument", + Call); + + if (BU.Inputs.empty()) + return; + + auto *Fn = cast(BU.Inputs.front()); + Intrinsic::ID IID = Fn->getIntrinsicID(); + + if (IID) { + Assert((IID == Intrinsic::objc_retainAutoreleasedReturnValue || + IID == Intrinsic::objc_unsafeClaimAutoreleasedReturnValue), + "invalid function argument", Call); + } else { + StringRef FnName = Fn->getName(); + Assert((FnName == "objc_retainAutoreleasedReturnValue" || + FnName == "objc_unsafeClaimAutoreleasedReturnValue"), + "invalid function argument", Call); + } +} + void Verifier::verifySourceDebugInfo(const DICompileUnit &U, const DIFile &F) { bool HasSource = F.getSource().hasValue(); if (!HasSourceDebugInfo.count(&U)) diff --git a/llvm/lib/Target/X86/X86ExpandPseudo.cpp b/llvm/lib/Target/X86/X86ExpandPseudo.cpp index 4add8d30e010e..ca7dfcdbb9cae 100644 --- a/llvm/lib/Target/X86/X86ExpandPseudo.cpp +++ b/llvm/lib/Target/X86/X86ExpandPseudo.cpp @@ -236,19 +236,10 @@ void X86ExpandPseudo::expandCALL_RVMARKER(MachineBasicBlock &MBB, MBB.getParent()->moveCallSiteInfo(&MI, Marker); // Emit call to ObjC runtime. - unsigned RuntimeCallType = MI.getOperand(0).getImm(); - assert(RuntimeCallType <= 1 && "objc runtime call type must be 0 or 1"); - Module *M = MBB.getParent()->getFunction().getParent(); - auto &Context = M->getContext(); - auto *I8PtrTy = PointerType::get(IntegerType::get(Context, 8), 0); - FunctionCallee Fn = M->getOrInsertFunction( - RuntimeCallType == 0 ? "objc_retainAutoreleasedReturnValue" - : "objc_unsafeClaimAutoreleasedReturnValue", - FunctionType::get(I8PtrTy, {I8PtrTy}, false)); const uint32_t *RegMask = TRI->getCallPreservedMask(*MBB.getParent(), CallingConv::C); BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(X86::CALL64pcrel32)) - .addGlobalAddress(cast(Fn.getCallee()), 0, 0) + .addGlobalAddress(MI.getOperand(0).getGlobal(), 0, 0) .addRegMask(RegMask) .addReg(X86::RAX, RegState::Implicit | diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 344bf73b2c5e0..15bd8a169f1d1 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -4436,14 +4436,12 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, "tail calls cannot be marked with clang.arc.attachedcall"); assert(Is64Bit && "clang.arc.attachedcall is only supported in 64bit mode"); - // Add target constant to select ObjC runtime call just before the call - // target. RuntimeCallType == 0 selects objc_retainAutoreleasedReturnValue, - // RuntimeCallType == 0 selects objc_unsafeClaimAutoreleasedReturnValue when - // epxanding the pseudo. - unsigned RuntimeCallType = - objcarc::hasAttachedCallOpBundle(CLI.CB, true) ? 0 : 1; - Ops.insert(Ops.begin() + 1, - DAG.getTargetConstant(RuntimeCallType, dl, MVT::i32)); + // Add a target global address for the retainRV/claimRV runtime function + // just before the call target. + Function *ARCFn = *objcarc::getAttachedARCFunction(CLI.CB); + auto PtrVT = getPointerTy(DAG.getDataLayout()); + auto GA = DAG.getTargetGlobalAddress(ARCFn, dl, PtrVT); + Ops.insert(Ops.begin() + 1, GA); Chain = DAG.getNode(X86ISD::CALL_RVMARKER, dl, NodeTys, Ops); } else { Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops); diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 202d320cd731f..9cdd0177f027a 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -1197,10 +1197,10 @@ def : Pat<(X86call (i64 tglobaladdr:$dst)), def : Pat<(X86call (i64 texternalsym:$dst)), (CALL64pcrel32 texternalsym:$dst)>; -def : Pat<(X86call_rvmarker (timm:$sel), (i64 texternalsym:$dst)), - (CALL64pcrel32_RVMARKER timm:$sel, texternalsym:$dst)>; -def : Pat<(X86call_rvmarker (timm:$sel), (i64 tglobaladdr:$dst)), - (CALL64pcrel32_RVMARKER timm:$sel, tglobaladdr:$dst)>; +def : Pat<(X86call_rvmarker (i64 tglobaladdr:$rvfunc), (i64 texternalsym:$dst)), + (CALL64pcrel32_RVMARKER tglobaladdr:$rvfunc, texternalsym:$dst)>; +def : Pat<(X86call_rvmarker (i64 tglobaladdr:$rvfunc), (i64 tglobaladdr:$dst)), + (CALL64pcrel32_RVMARKER tglobaladdr:$rvfunc, tglobaladdr:$dst)>; // Tailcall stuff. The TCRETURN instructions execute after the epilog, so they diff --git a/llvm/lib/Target/X86/X86InstrControl.td b/llvm/lib/Target/X86/X86InstrControl.td index a6cb17f17a179..680389662aa87 100644 --- a/llvm/lib/Target/X86/X86InstrControl.td +++ b/llvm/lib/Target/X86/X86InstrControl.td @@ -419,15 +419,15 @@ let isPseudo = 1, isCall = 1, isCodeGenOnly = 1, Uses = [RSP, SSP], SchedRW = [WriteJump] in { def CALL64m_RVMARKER : - PseudoI<(outs), (ins i32imm:$sel, i64mem:$dst), [(X86call_rvmarker timm:$sel, (loadi64 addr:$dst))]>, + PseudoI<(outs), (ins i64imm:$rvfunc, i64mem:$dst), [(X86call_rvmarker tglobaladdr:$rvfunc, (loadi64 addr:$dst))]>, Requires<[In64BitMode]>; def CALL64r_RVMARKER : - PseudoI<(outs), (ins i32imm:$sel, GR64:$dst), [(X86call_rvmarker timm:$sel, GR64:$dst)]>, + PseudoI<(outs), (ins i64imm:$rvfunc, GR64:$dst), [(X86call_rvmarker tglobaladdr:$rvfunc, GR64:$dst)]>, Requires<[In64BitMode]>; def CALL64pcrel32_RVMARKER : - PseudoI<(outs), (ins i32imm:$sel, i64i32imm_brtarget:$dst), []>, + PseudoI<(outs), (ins i64imm:$rvfunc, i64i32imm_brtarget:$dst), []>, Requires<[In64BitMode]>; } diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp index 06b12149f5971..296610eedccd9 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp @@ -103,9 +103,8 @@ CallInst *BundledRetainClaimRVs::insertRVCallWithColors( Instruction *InsertPt, CallBase *AnnotatedCall, const DenseMap &BlockColors) { IRBuilder<> Builder(InsertPt); - bool IsRetainRV = objcarc::hasAttachedCallOpBundle(AnnotatedCall, true); - Function *Func = EP.get(IsRetainRV ? ARCRuntimeEntryPointKind::RetainRV - : ARCRuntimeEntryPointKind::ClaimRV); + Function *Func = *objcarc::getAttachedARCFunction(AnnotatedCall); + assert(Func && "operand isn't a Function"); Type *ParamTy = Func->getArg(0)->getType(); Value *CallArg = Builder.CreateBitCast(AnnotatedCall, ParamTy); auto *Call = @@ -116,13 +115,21 @@ CallInst *BundledRetainClaimRVs::insertRVCallWithColors( BundledRetainClaimRVs::~BundledRetainClaimRVs() { if (ContractPass) { - // At this point, we know that the annotated calls can't be tail calls as - // they are followed by marker instructions and retainRV/claimRV calls. Mark - // them as notail, so that the backend knows these calls can't be tail - // calls. - for (auto P : RVCalls) - if (auto *CI = dyn_cast(P.second)) + for (auto P : RVCalls) { + CallBase *CB = P.second; + // At this point, we know that the annotated calls can't be tail calls + // as they are followed by marker instructions and retainRV/claimRV + // calls. Mark them as notail so that the backend knows these calls + // can't be tail calls. + if (auto *CI = dyn_cast(CB)) CI->setTailCallKind(CallInst::TCK_NoTail); + + // Remove the ARC intrinsic function operand from the operand bundle. + OperandBundleDef OB("clang.arc.attachedcall", None); + auto *NewCB = CallBase::Create(CB, OB, CB); + CB->replaceAllUsesWith(NewCB); + CB->eraseFromParent(); + } } else { for (auto P : RVCalls) EraseInstruction(P.first); diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.h b/llvm/lib/Transforms/ObjCARC/ObjCARC.h index 1f9d76969bfd7..62f88a8cc02ba 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARC.h +++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.h @@ -105,8 +105,7 @@ CallInst *createCallInstWithColors( class BundledRetainClaimRVs { public: - BundledRetainClaimRVs(ARCRuntimeEntryPoints &P, bool ContractPass) - : EP(P), ContractPass(ContractPass) {} + BundledRetainClaimRVs(bool ContractPass) : ContractPass(ContractPass) {} ~BundledRetainClaimRVs(); /// Insert a retainRV/claimRV call to the normal destination blocks of invokes @@ -155,7 +154,6 @@ class BundledRetainClaimRVs { /// A map of inserted retainRV/claimRV calls to annotated calls/invokes. DenseMap RVCalls; - ARCRuntimeEntryPoints &EP; bool ContractPass; }; diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp index 577973c806015..185a19fc47f40 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -540,7 +540,7 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) { AA = A; DT = D; PA.setAA(A); - BundledRetainClaimRVs BRV(EP, true); + BundledRetainClaimRVs BRV(true); BundledInsts = &BRV; std::pair R = BundledInsts->insertAfterInvokes(F, DT); diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index ada6aa8d9b6dc..89e62267389f2 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -2462,7 +2462,7 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) { return false; Changed = CFGChanged = false; - BundledRetainClaimRVs BRV(EP, false); + BundledRetainClaimRVs BRV(false); BundledInsts = &BRV; LLVM_DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName() diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 9363e0dc9b268..50e3d26aed277 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1672,10 +1672,11 @@ void llvm::updateProfileCallee( /// 3. Otherwise, a call to objc_retain is inserted if the call in the caller is /// a retainRV call. static void -inlineRetainOrClaimRVCalls(CallBase &CB, +inlineRetainOrClaimRVCalls(CallBase &CB, objcarc::ARCInstKind RVCallKind, const SmallVectorImpl &Returns) { Module *Mod = CB.getModule(); - bool IsRetainRV = objcarc::hasAttachedCallOpBundle(&CB, true), + assert(objcarc::isRetainOrClaimRV(RVCallKind) && "unexpected ARC function"); + bool IsRetainRV = RVCallKind == objcarc::ARCInstKind::RetainRV, IsClaimRV = !IsRetainRV; for (auto *RI : Returns) { @@ -1695,43 +1696,47 @@ inlineRetainOrClaimRVCalls(CallBase &CB, continue; if (auto *II = dyn_cast(&*CurI)) { - if (II->getIntrinsicID() == Intrinsic::objc_autoreleaseReturnValue && - II->hasNUses(0) && - objcarc::GetRCIdentityRoot(II->getOperand(0)) == RetOpnd) { - // If we've found a matching authoreleaseRV call: - // - If claimRV is attached to the call, insert a call to objc_release - // and erase the autoreleaseRV call. - // - If retainRV is attached to the call, just erase the autoreleaseRV - // call. - if (IsClaimRV) { - Builder.SetInsertPoint(II); - Function *IFn = - Intrinsic::getDeclaration(Mod, Intrinsic::objc_release); - Value *BC = - Builder.CreateBitCast(RetOpnd, IFn->getArg(0)->getType()); - Builder.CreateCall(IFn, BC, ""); - } - II->eraseFromParent(); - InsertRetainCall = false; - } - } else if (auto *CI = dyn_cast(&*CurI)) { - if (objcarc::GetRCIdentityRoot(CI) == RetOpnd && - !objcarc::hasAttachedCallOpBundle(CI)) { - // If we've found an unannotated call that defines RetOpnd, add a - // "clang.arc.attachedcall" operand bundle. - Value *BundleArgs[] = {ConstantInt::get( - Builder.getInt64Ty(), - objcarc::getAttachedCallOperandBundleEnum(IsRetainRV))}; - OperandBundleDef OB("clang.arc.attachedcall", BundleArgs); - auto *NewCall = CallBase::addOperandBundle( - CI, LLVMContext::OB_clang_arc_attachedcall, OB, CI); - NewCall->copyMetadata(*CI); - CI->replaceAllUsesWith(NewCall); - CI->eraseFromParent(); - InsertRetainCall = false; + if (II->getIntrinsicID() != Intrinsic::objc_autoreleaseReturnValue || + !II->hasNUses(0) || + objcarc::GetRCIdentityRoot(II->getOperand(0)) != RetOpnd) + break; + + // If we've found a matching authoreleaseRV call: + // - If claimRV is attached to the call, insert a call to objc_release + // and erase the autoreleaseRV call. + // - If retainRV is attached to the call, just erase the autoreleaseRV + // call. + if (IsClaimRV) { + Builder.SetInsertPoint(II); + Function *IFn = + Intrinsic::getDeclaration(Mod, Intrinsic::objc_release); + Value *BC = Builder.CreateBitCast(RetOpnd, IFn->getArg(0)->getType()); + Builder.CreateCall(IFn, BC, ""); } + II->eraseFromParent(); + InsertRetainCall = false; + break; } + auto *CI = dyn_cast(&*CurI); + + if (!CI) + break; + + if (objcarc::GetRCIdentityRoot(CI) != RetOpnd || + objcarc::hasAttachedCallOpBundle(CI)) + break; + + // If we've found an unannotated call that defines RetOpnd, add a + // "clang.arc.attachedcall" operand bundle. + Value *BundleArgs[] = {*objcarc::getAttachedARCFunction(&CB)}; + OperandBundleDef OB("clang.arc.attachedcall", BundleArgs); + auto *NewCall = CallBase::addOperandBundle( + CI, LLVMContext::OB_clang_arc_attachedcall, OB, CI); + NewCall->copyMetadata(*CI); + CI->replaceAllUsesWith(NewCall); + CI->eraseFromParent(); + InsertRetainCall = false; break; } @@ -1953,8 +1958,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, FirstNewBlock = LastBlock; ++FirstNewBlock; // Insert retainRV/clainRV runtime calls. - if (objcarc::hasAttachedCallOpBundle(&CB)) - inlineRetainOrClaimRVCalls(CB, Returns); + objcarc::ARCInstKind RVCallKind = objcarc::getAttachedARCFunctionKind(&CB); + if (RVCallKind != objcarc::ARCInstKind::None) + inlineRetainOrClaimRVCalls(CB, RVCallKind, Returns); // Updated caller/callee profiles only when requested. For sample loader // inlining, the context-sensitive inlinee profile doesn't need to be diff --git a/llvm/test/CodeGen/AArch64/call-rv-marker.ll b/llvm/test/CodeGen/AArch64/call-rv-marker.ll index 3b5ab40839b57..3f53b5b487279 100644 --- a/llvm/test/CodeGen/AArch64/call-rv-marker.ll +++ b/llvm/test/CodeGen/AArch64/call-rv-marker.ll @@ -33,7 +33,7 @@ define dso_local i8* @rv_marker_1() { ; GISEL-NOT: mov x29, x29 ; entry: - %call = call i8* @foo1() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @foo1() [ "clang.arc.attachedcall"() ] ret i8* %call } @@ -49,7 +49,7 @@ define dso_local void @rv_marker_2_select(i32 %c) { entry: %tobool.not = icmp eq i32 %c, 0 %.sink = select i1 %tobool.not, i32 2, i32 1 - %call1 = call i8* @foo0(i32 %.sink) [ "clang.arc.attachedcall"(i64 0) ] + %call1 = call i8* @foo0(i32 %.sink) [ "clang.arc.attachedcall"() ] tail call void @foo2(i8* %call1) ret void } @@ -61,7 +61,7 @@ define dso_local void @rv_marker_3() personality i8* bitcast (i32 (...)* @__gxx_ ; SELDAG-NEXT: mov x29, x29 ; entry: - %call = call i8* @foo1() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @foo1() [ "clang.arc.attachedcall"() ] invoke void @objc_object(i8* %call) #5 to label %invoke.cont unwind label %lpad @@ -87,7 +87,7 @@ entry: %s = alloca %struct.S, align 1 %0 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0 call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %0) #2 - %call = invoke i8* @foo1() [ "clang.arc.attachedcall"(i64 0) ] + %call = invoke i8* @foo1() [ "clang.arc.attachedcall"() ] to label %invoke.cont unwind label %lpad invoke.cont: ; preds = %entry @@ -127,7 +127,7 @@ define dso_local i8* @rv_marker_5_indirect_call() { ; entry: %0 = load i8* ()*, i8* ()** @fptr, align 8 - %call = call i8* %0() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* %0() [ "clang.arc.attachedcall"() ] tail call void @foo2(i8* %call) ret i8* %call } @@ -142,7 +142,7 @@ define dso_local void @rv_marker_multiarg(i64 %a, i64 %b, i64 %c) { ; CHECK-NEXT: bl foo ; SELDAG-NEXT: mov x29, x29 ; GISEL-NOT: mov x29, x29 - call i8* @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.attachedcall"(i64 0) ] + call i8* @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.attachedcall"() ] ret void } diff --git a/llvm/test/CodeGen/X86/call-rv-marker.ll b/llvm/test/CodeGen/X86/call-rv-marker.ll index 91a0e61f5e5af..fd22ec59e5f73 100644 --- a/llvm/test/CodeGen/X86/call-rv-marker.ll +++ b/llvm/test/CodeGen/X86/call-rv-marker.ll @@ -34,7 +34,7 @@ define i8* @rv_marker_1_retain() { ; CHECK-NEXT: retq ; entry: - %call = call i8* @foo1() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @foo1() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] ret i8* %call } @@ -49,7 +49,7 @@ define i8* @rv_marker_1_claim() { ; CHECK-NEXT: retq ; entry: - %call = call i8* @foo1() [ "clang.arc.attachedcall"(i64 1) ] + %call = call i8* @foo1() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_unsafeClaimAutoreleasedReturnValue) ] ret i8* %call } @@ -70,7 +70,7 @@ define void @rv_marker_2_select(i32 %c) { entry: %tobool.not = icmp eq i32 %c, 0 %.sink = select i1 %tobool.not, i32 2, i32 1 - %call1 = call i8* @foo0(i32 %.sink) [ "clang.arc.attachedcall"(i64 0) ] + %call1 = call i8* @foo0(i32 %.sink) [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] tail call void @foo2(i8* %call1) ret void } @@ -92,7 +92,7 @@ define void @rv_marker_3() personality i8* bitcast (i32 (...)* @__gxx_personalit ; CHECK-NEXT: Ltmp0: ; entry: - %call = call i8* @foo1() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @foo1() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] invoke void @objc_object(i8* %call) #5 to label %invoke.cont unwind label %lpad @@ -127,7 +127,7 @@ entry: %s = alloca %struct.S, align 1 %0 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0 call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %0) #2 - %call = invoke i8* @foo1() [ "clang.arc.attachedcall"(i64 0) ] + %call = invoke i8* @foo1() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] to label %invoke.cont unwind label %lpad invoke.cont: ; preds = %entry @@ -177,7 +177,7 @@ define i8* @rv_marker_5_indirect_call() { ; entry: %lv = load i8* ()*, i8* ()** @fptr, align 8 - %call = call i8* %lv() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* %lv() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] tail call void @foo2(i8* %call) ret i8* %call } @@ -197,7 +197,7 @@ define void @rv_marker_multiarg(i64 %a, i64 %b, i64 %c) { ; CHECK-NEXT: popq %rax ; CHECK-NEXT: retq ; - %r = call i8* @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.attachedcall"(i64 0) ] + %r = call i8* @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] ret void } @@ -210,10 +210,12 @@ define void @test_nonlazybind() { ; CHECK-NEXT: movq %rax, %rdi ; CHECK-NEXT: callq _objc_retainAutoreleasedReturnValue ; - %call1 = notail call i8* @foo_nonlazybind() [ "clang.arc.attachedcall"(i64 0) ] + %call1 = notail call i8* @foo_nonlazybind() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] ret void } declare i8* @foo_nonlazybind() nonlazybind +declare i8* @objc_retainAutoreleasedReturnValue(i8*) +declare i8* @objc_unsafeClaimAutoreleasedReturnValue(i8*) declare i32 @__gxx_personality_v0(...) diff --git a/llvm/test/CodeGen/X86/expand-call-rvmarker.mir b/llvm/test/CodeGen/X86/expand-call-rvmarker.mir index f4f8fabf1a877..e83090e22f7e4 100644 --- a/llvm/test/CodeGen/X86/expand-call-rvmarker.mir +++ b/llvm/test/CodeGen/X86/expand-call-rvmarker.mir @@ -52,7 +52,7 @@ body: | bb.0 (%ir-block.0): frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp CFI_INSTRUCTION def_cfa_offset 16 - CALL64pcrel32_RVMARKER 0, @fn, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $rax + CALL64pcrel32_RVMARKER @objc_retainAutoreleasedReturnValue, @fn, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $rax $rcx = frame-destroy POP64r implicit-def $rsp, implicit $rsp RET 0, $rax @@ -83,7 +83,7 @@ body: | bb.0 (%ir-block.0): frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp CFI_INSTRUCTION def_cfa_offset 16 - CALL64pcrel32_RVMARKER 1, @fn, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $rax + CALL64pcrel32_RVMARKER @objc_unsafeClaimAutoreleasedReturnValue, @fn, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $rax $rcx = frame-destroy POP64r implicit-def $rsp, implicit $rsp RET 0, $rax @@ -120,7 +120,7 @@ body: | $rax = MOV64rr $rdi $rdi = MOV64rr killed $rdx $rdx = MOV64rr killed $rax - CALL64pcrel32_RVMARKER 0, @fn, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit-def $rsp, implicit-def $ssp, implicit-def dead $rax + CALL64pcrel32_RVMARKER @objc_retainAutoreleasedReturnValue, @fn, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit-def $rsp, implicit-def $ssp, implicit-def dead $rax $rax = frame-destroy POP64r implicit-def $rsp, implicit $rsp RET 0, $rax @@ -150,6 +150,6 @@ body: | bb.0 (%ir-block.0): frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp CFI_INSTRUCTION def_cfa_offset 16 - CALL64pcrel32_RVMARKER 0, @fn, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def dead $rax + CALL64pcrel32_RVMARKER @objc_retainAutoreleasedReturnValue, @fn, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def dead $rax $rax = frame-destroy POP64r implicit-def $rsp, implicit $rsp RET 0 diff --git a/llvm/test/Transforms/DeadArgElim/deadretval.ll b/llvm/test/Transforms/DeadArgElim/deadretval.ll index f3b343745e4d2..750e8f27bc3be 100644 --- a/llvm/test/Transforms/DeadArgElim/deadretval.ll +++ b/llvm/test/Transforms/DeadArgElim/deadretval.ll @@ -32,10 +32,12 @@ define internal i8* @callee4(i8* %a0) { declare void @llvm.objc.clang.arc.noop.use(...) ; CHECK-LABEL: define i8* @test4( -; CHECK: tail call i8* @callee4() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: tail call i8* @callee4() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] define i8* @test4() { - %call = tail call i8* @callee4(i8* @g0) [ "clang.arc.attachedcall"(i64 0) ] + %call = tail call i8* @callee4(i8* @g0) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] call void (...) @llvm.objc.clang.arc.noop.use(i8* %call) ret i8* @g0 } + +declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) diff --git a/llvm/test/Transforms/Inline/inline-retainRV-call.ll b/llvm/test/Transforms/Inline/inline-retainRV-call.ll index f8ac2154f9339..774663895f1ac 100644 --- a/llvm/test/Transforms/Inline/inline-retainRV-call.ll +++ b/llvm/test/Transforms/Inline/inline-retainRV-call.ll @@ -4,35 +4,35 @@ declare i8* @foo0() define i8* @callee0_autoreleaseRV() { - %call = call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] %1 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) ret i8* %call } ; CHECK-LABEL: define void @test0_autoreleaseRV( -; CHECK: call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] define void @test0_autoreleaseRV() { - %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret void } ; CHECK-LABEL: define void @test0_claimRV_autoreleaseRV( -; CHECK: %[[CALL:.*]] = call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[CALL:.*]] = call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK: call void @llvm.objc.release(i8* %[[CALL]]) ; CHECK-NEXT: ret void define void @test0_claimRV_autoreleaseRV() { - %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i64 1) ] + %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] ret void } ; CHECK-LABEL: define void @test1_autoreleaseRV( -; CHECK: invoke i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: invoke i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] define void @test1_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { entry: - %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i64 0) ] + %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] to label %invoke.cont unwind label %lpad invoke.cont: @@ -45,13 +45,13 @@ lpad: } ; CHECK-LABEL: define void @test1_claimRV_autoreleaseRV( -; CHECK: %[[INVOKE:.*]] = invoke i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[INVOKE:.*]] = invoke i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK: call void @llvm.objc.release(i8* %[[INVOKE]]) ; CHECK-NEXT: br define void @test1_claimRV_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { entry: - %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i64 1) ] + %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] to label %invoke.cont unwind label %lpad invoke.cont: @@ -69,29 +69,29 @@ define i8* @callee1_no_autoreleaseRV() { } ; CHECK-LABEL: define void @test2_no_autoreleaseRV( -; CHECK: call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK-NEXT: ret void define void @test2_no_autoreleaseRV() { - %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret void } ; CHECK-LABEL: define void @test2_claimRV_no_autoreleaseRV( -; CHECK: call i8* @foo0() [ "clang.arc.attachedcall"(i64 1) ] +; CHECK: call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] ; CHECK-NEXT: ret void define void @test2_claimRV_no_autoreleaseRV() { - %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.attachedcall"(i64 1) ] + %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] ret void } ; CHECK-LABEL: define void @test3_no_autoreleaseRV( -; CHECK: invoke i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: invoke i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] define void @test3_no_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { entry: - %call = invoke i8* @callee1_no_autoreleaseRV() [ "clang.arc.attachedcall"(i64 0) ] + %call = invoke i8* @callee1_no_autoreleaseRV() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] to label %invoke.cont unwind label %lpad invoke.cont: @@ -117,7 +117,7 @@ define i8* @callee2_nocall() { ; CHECK-NEXT: ret void define void @test4_nocall() { - %call = call i8* @callee2_nocall() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @callee2_nocall() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret void } @@ -126,7 +126,7 @@ define void @test4_nocall() { ; CHECK-NEXT: ret void define void @test4_claimRV_nocall() { - %call = call i8* @callee2_nocall() [ "clang.arc.attachedcall"(i64 1) ] + %call = call i8* @callee2_nocall() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] ret void } @@ -134,17 +134,17 @@ define void @test4_claimRV_nocall() { ; the attribute. I'm not sure this will happen in practice. define i8* @callee3_marker() { - %1 = call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] + %1 = call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret i8* %1 } ; CHECK-LABEL: define void @test5( -; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %[[V0]]) ; CHECK-NEXT: ret void define void @test5() { - %call = call i8* @callee3_marker() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @callee3_marker() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret void } @@ -153,23 +153,25 @@ define void @test5() { ; autoreleaseRV that isn't a cast instruction. define i8* @callee0_autoreleaseRV2() { - %call = call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] %1 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) store i8* null, i8** @g0 ret i8* %call } ; CHECK-LABEL: define void @test6( -; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(i8* %[[V0]]) ; CHECK: store i8* null, i8** @g0, align 8 ; CHECK: call i8* @llvm.objc.retain(i8* %[[V0]]) ; CHECK-NEXT: ret void define void @test6() { - %call = call i8* @callee0_autoreleaseRV2() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @callee0_autoreleaseRV2() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret void } +declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) +declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*) declare i8* @llvm.objc.autoreleaseReturnValue(i8*) declare i32 @__gxx_personality_v0(...) diff --git a/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll b/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll index c40f411c9fb75..fb3dbc0272f44 100644 --- a/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll +++ b/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll @@ -51,11 +51,11 @@ invoke.cont: ; preds = %entry } ; CHECK-LABEL: define dso_local void @"?test_attr_claimRV@@YAXXZ"() -; CHECK: %[[CALL4:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "clang.arc.attachedcall"(i64 1) ] +; CHECK: %[[CALL4:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "clang.arc.attachedcall"() ] ; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL4]]) ; CHECK: %[[V1:.*]] = cleanuppad -; CHECK: %[[CALL:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "funclet"(token %[[V1]]), "clang.arc.attachedcall"(i64 1) ] +; CHECK: %[[CALL:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "funclet"(token %[[V1]]), "clang.arc.attachedcall"() ] ; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL]]) [ "funclet"(token %[[V1]]) ] define dso_local void @"?test_attr_claimRV@@YAXXZ"() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { @@ -64,12 +64,12 @@ entry: to label %invoke.cont unwind label %ehcleanup invoke.cont: ; preds = %entry - %call.i4 = tail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "clang.arc.attachedcall"(i64 1) ] + %call.i4 = tail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] ret void ehcleanup: ; preds = %entry %0 = cleanuppad within none [] - %call.i = call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "funclet"(token %0), "clang.arc.attachedcall"(i64 1) ] + %call.i = call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "funclet"(token %0), "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] cleanupret from %0 unwind to caller } diff --git a/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll b/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll index 18bc00b62db8d..d601e988fdb32 100644 --- a/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll +++ b/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll @@ -2,30 +2,30 @@ ; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s ; CHECK-LABEL: define void @test0() { -; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"() ] ; CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]]) define void @test0() { - %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i64 0) ] + %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret void } ; CHECK-LABEL: define void @test1() { -; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i64 1) ] +; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"() ] ; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL]]) define void @test1() { - %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i64 1) ] + %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] ret void } ; CHECK-LABEL:define i8* @test2( -; CHECK: %[[CALL1:.*]] = invoke i8* @foo() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[CALL1:.*]] = invoke i8* @foo() [ "clang.arc.attachedcall"() ] ; CHECK: %[[V0:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]]) ; CHECK-NEXT: br -; CHECK: %[[CALL3:.*]] = invoke i8* @foo() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[CALL3:.*]] = invoke i8* @foo() [ "clang.arc.attachedcall"() ] ; CHECK: %[[V2:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL3]]) ; CHECK-NEXT: br @@ -38,7 +38,7 @@ entry: br i1 %b, label %if.then, label %if.end if.then: - %call1 = invoke i8* @foo() [ "clang.arc.attachedcall"(i64 0) ] + %call1 = invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] to label %cleanup unwind label %lpad lpad: @@ -47,7 +47,7 @@ lpad: resume { i8*, i32 } undef if.end: - %call3 = invoke i8* @foo() [ "clang.arc.attachedcall"(i64 0) ] + %call3 = invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] to label %cleanup unwind label %lpad cleanup: @@ -55,18 +55,21 @@ cleanup: ret i8* %retval.0 } +; "clang.arc.attachedcall" is ignored if the return type of the called function is void. ; CHECK-LABEL: define void @test3( -; CHECK: call void @foo2() #[[ATTR1:.*]] [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: call void @foo2() #[[ATTR1:.*]] [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK-NEXT: ret void define void @test3() { - call void @foo2() #0 [ "clang.arc.attachedcall"(i64 0) ] + call void @foo2() #0 [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret void } declare i8* @foo() declare void @foo2() declare i32 @__gxx_personality_v0(...) +declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) +declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*) !llvm.module.flags = !{!0} diff --git a/llvm/test/Transforms/ObjCARC/rv.ll b/llvm/test/Transforms/ObjCARC/rv.ll index 29017222ebb11..7fda98cf122ca 100644 --- a/llvm/test/Transforms/ObjCARC/rv.ll +++ b/llvm/test/Transforms/ObjCARC/rv.ll @@ -461,19 +461,19 @@ bb1: ; CHECK-NEXT: ret i8* %[[CALL]] define i8* @test31() { - %call = tail call i8* @returner() [ "clang.arc.attachedcall"(i64 0) ] + %call = tail call i8* @returner() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] call void (...) @llvm.objc.clang.arc.noop.use(i8* %call) %1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) ret i8* %1 } ; CHECK-LABEL: define i8* @test32( -; CHECK: %[[CALL:.*]] = call i8* @returner() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK: %[[CALL:.*]] = call i8* @returner() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK: call void (...) @llvm.objc.clang.arc.noop.use(i8* %[[CALL]]) ; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(i8* %[[CALL]]) define i8* @test32() { - %call = call i8* @returner() [ "clang.arc.attachedcall"(i64 0) ] + %call = call i8* @returner() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] call void (...) @llvm.objc.clang.arc.noop.use(i8* %call) %1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %call) ret i8* %1 diff --git a/llvm/test/Transforms/SCCP/clang-arc-rv.ll b/llvm/test/Transforms/SCCP/clang-arc-rv.ll index bb8f45b41c136..7ac2eb0ae3bbd 100644 --- a/llvm/test/Transforms/SCCP/clang-arc-rv.ll +++ b/llvm/test/Transforms/SCCP/clang-arc-rv.ll @@ -16,9 +16,10 @@ define internal i8* @foo() { ; CHECK call void (...) @llvm.objc.clang.arc.noop.use(i8* %[[R]]) define void @test() { - %r = call i8* @foo() [ "clang.arc.attachedcall"(i64 1) ] + %r = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] call void (...) @llvm.objc.clang.arc.noop.use(i8* %r) ret void } +declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*) declare void @llvm.objc.clang.arc.noop.use(...) diff --git a/llvm/test/Transforms/TailCallElim/deopt-bundle.ll b/llvm/test/Transforms/TailCallElim/deopt-bundle.ll index a075849421716..310ecc1a8ee17 100644 --- a/llvm/test/Transforms/TailCallElim/deopt-bundle.ll +++ b/llvm/test/Transforms/TailCallElim/deopt-bundle.ll @@ -62,6 +62,8 @@ exit: declare i8* @getObj() define i8* @test_clang_arc_attachedcall() { - %r = call i8* @getObj() [ "clang.arc.attachedcall"(i64 0) ] + %r = call i8* @getObj() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ret i8* %r } + +declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) diff --git a/llvm/test/Verifier/invoke.ll b/llvm/test/Verifier/invoke.ll index 12c1a259520ff..efc7d4d11edf2 100644 --- a/llvm/test/Verifier/invoke.ll +++ b/llvm/test/Verifier/invoke.ll @@ -46,7 +46,7 @@ contb: define i8 @f2() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { entry: -; CHECK: Cannot invoke an intrinsic other than donothing, patchpoint, statepoint, coro_resume or coro_destroy +; CHECK: Cannot invoke an intrinsic other than donothing, patchpoint, statepoint, coro_resume, coro_destroy or clang.arc.attachedcall invoke void @llvm.trap() to label %cont unwind label %lpad diff --git a/llvm/test/Verifier/operand-bundles.ll b/llvm/test/Verifier/operand-bundles.ll index d7d7b4f0f7820..06b452de910c4 100644 --- a/llvm/test/Verifier/operand-bundles.ll +++ b/llvm/test/Verifier/operand-bundles.ll @@ -67,18 +67,40 @@ define void @f_gc_transition(i32* %ptr) { define void @f_clang_arc_attachedcall() { ; CHECK: Multiple "clang.arc.attachedcall" operand bundles -; CHECK-NEXT: call %0* @foo0() [ "clang.arc.attachedcall"(i64 0), "clang.arc.attachedcall"(i64 0) ] +; CHECK-NEXT: call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue), "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK-NEXT: must call a function returning a pointer -; CHECK-NEXT: call i8 @foo1() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK-NEXT: call i8 @foo1() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK-NEXT: or a non-returning function -; CHECK-NEXT: call void @g() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK-NEXT: call void @g() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +; CHECK-NEXT: can take either no arguments +; CHECK-NEXT: call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* null) ] +; CHECK-NEXT: can take either no arguments +; CHECK-NEXT: call %0* @foo0() [ "clang.arc.attachedcall"(i64 0) ] +; CHECK-NEXT: invalid function argument +; CHECK-NEXT: call %0* @foo0() [ "clang.arc.attachedcall"(i8 ()* @foo1) ] +; CHECK-NEXT: invalid function argument +; CHECK-NEXT: call %0* @foo0() [ "clang.arc.attachedcall"(void (i1)* @llvm.assume) ] + call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] + call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] + call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_unsafeClaimAutoreleasedReturnValue) ] + call %0* @foo0() [ "clang.arc.attachedcall"() ] + call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue), "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + call i8 @foo1() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + call void @noreturn_func() #0 [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + call void @g() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + call %0* @foo0() [ "clang.arc.attachedcall"(i8* (i8*)* null) ] call %0* @foo0() [ "clang.arc.attachedcall"(i64 0) ] - call %0* @foo0() [ "clang.arc.attachedcall"(i64 0), "clang.arc.attachedcall"(i64 0) ] - call i8 @foo1() [ "clang.arc.attachedcall"(i64 0) ] - call void @noreturn_func() #0 [ "clang.arc.attachedcall"(i64 0) ] - call void @g() [ "clang.arc.attachedcall"(i64 0) ] + call %0* @foo0() [ "clang.arc.attachedcall"(i8 ()* @foo1) ] + call %0* @foo0() [ "clang.arc.attachedcall"(void (i1)* @llvm.assume) ] ret void } +declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) +declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*) +declare i8* @objc_retainAutoreleasedReturnValue(i8*) +declare i8* @objc_unsafeClaimAutoreleasedReturnValue(i8*) +declare void @llvm.assume(i1) + attributes #0 = { noreturn } From 3e4d39ec39a44899680dd0038a1329a80f4a9ced Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 9 Nov 2021 12:56:22 +0000 Subject: [PATCH 020/293] [SimplifyCFG] Add early bailout if Use is not in same BB. Without this patch, passingValueIsAlwaysUndefined will iterate over all instructions from I to the end of the basic block, even if the use is outside the block. This patch adds an early bail out, if the use instruction is outside I's BB. This can greatly reduce compile-time in cases where very large basic blocks are involved, with a large number of PHI nodes and incoming values. Note that the refactoring makes the handling of the case where I is a phi and Use is in PHI more explicit as well: for phi nodes, we can also directly bail out. In the existing code, we would iterate until we reach the end and return false. Based on an earlier patch by Matt Wala. Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D113293 (cherry-picked from 2ead34716a8e) --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 47c5a8f2d2c8a..a096ef4eb65ee 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -6465,19 +6465,21 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu if (C->isNullValue() || isa(C)) { // Only look at the first use, avoid hurting compile time with long uselists - User *Use = *I->user_begin(); + auto *Use = cast(*I->user_begin()); + // Bail out if Use is not in the same BB as I or Use == I or Use comes + // before I in the block. The latter two can be the case if Use is a PHI + // node. + if (Use->getParent() != I->getParent() || Use == I || Use->comesBefore(I)) + return false; // Now make sure that there are no instructions in between that can alter // control flow (eg. calls) - for (BasicBlock::iterator - i = ++BasicBlock::iterator(I), - UI = BasicBlock::iterator(dyn_cast(Use)); - i != UI; ++i) { - if (i == I->getParent()->end()) - return false; - if (!isGuaranteedToTransferExecutionToSuccessor(&*i)) - return false; - } + auto InstrRange = + make_range(std::next(I->getIterator()), Use->getIterator()); + if (any_of(InstrRange, [](Instruction &I) { + return !isGuaranteedToTransferExecutionToSuccessor(&I); + })) + return false; // Look through GEPs. A load from a GEP derived from NULL is still undefined if (GetElementPtrInst *GEP = dyn_cast(Use)) From e19254f93a59c69322bc1ff11f241d5ab9dd1ba8 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 10 Nov 2021 17:06:19 -0800 Subject: [PATCH 021/293] Add support for "clang.arc.attachedcall" on x86-64 (#3527) * Refactor code in ObjCARC.cpp. NFC This is in preparation for another patch I'm planning to send later. (cherry picked from commit 392a2a554cdef684b27d2bf0abc4a736602e89c1) * [ObjC][ARC] Handle operand bundle "clang.arc.attachedcall" on targets that don't use the inline asm marker This patch makes the changes to the ARC middle-end passes that are needed to handle operand bundle "clang.arc.attachedcall" on targets that don't use the inline asm marker for the retainRV/autoreleaseRV handshake (e.g., x86-64). Note that anyone who wants to use the operand bundle on their target has to teach their backend to handle the operand bundle. The x86-64 backend already knows about the operand bundle (see https://reviews.llvm.org/D94597). Differential Revision: https://reviews.llvm.org/D111334 (cherry picked from commit 8f8d9f743d317ca05ed2fac241fd9abc806d4c26) * [ObjC][ARC] Use operand bundle "clang.arc.attachedcall" on x86-64 https://reviews.llvm.org/D92808 made clang use the operand bundle instead of emitting retainRV/claimRV calls on arm64. This commit makes changes to clang that are needed to use the operand bundle on x86-64. Differential Revision: https://reviews.llvm.org/D111331 (cherry picked from commit d61eb6c5d97b6fb8af206bd533db6a0810f75285) * [ObjC][ARC] Replace uses of ObjC intrinsics that are arguments of operand bundle "clang.arc.attachedcall" with ObjC runtime functions The existing code only handles the case where the intrinsic being rewritten is used as the called function pointer of a call/invoke. (cherry picked from commit 1fe8993ad81900eea4d0f5603dffd239e520c31d) --- clang/lib/CodeGen/CGObjC.cpp | 7 +- clang/test/CodeGenObjC/arc-blocks.m | 22 ++-- clang/test/CodeGenObjC/arc-bridged-cast.m | 12 +-- clang/test/CodeGenObjC/arc-literals.m | 29 ++--- clang/test/CodeGenObjC/arc-precise-lifetime.m | 64 +++++------ clang/test/CodeGenObjC/arc-rv-attr.m | 1 + clang/test/CodeGenObjC/arc-ternary-op.m | 4 +- clang/test/CodeGenObjC/arc-unsafeclaim.m | 41 +++++++ clang/test/CodeGenObjC/arc.m | 100 ++++++++---------- .../nsvalue-objc-boxable-mac-arc.m | 18 ++-- clang/test/CodeGenObjC/os_log.m | 28 ++--- .../arc-forwarded-lambda-call.mm | 12 +-- clang/test/CodeGenObjCXX/arc-globals.mm | 8 +- clang/test/CodeGenObjCXX/arc-references.mm | 12 +-- clang/test/CodeGenObjCXX/arc.mm | 43 +++----- clang/test/CodeGenObjCXX/literals.mm | 26 ++--- llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 16 ++- llvm/lib/Transforms/ObjCARC/ObjCARC.cpp | 22 ++-- llvm/lib/Transforms/ObjCARC/ObjCARC.h | 6 +- .../Transforms/ObjCARC/ObjCARCContract.cpp | 20 ++-- llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 2 +- .../contract-attached-call-no-marker.ll | 24 +++++ .../PreISelIntrinsicLowering/objc-arc.ll | 34 ++++++ 23 files changed, 317 insertions(+), 234 deletions(-) create mode 100644 llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index accc926dbde16..e86865ef632d5 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -2348,9 +2348,12 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value, : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue; EP = getARCIntrinsic(IID, CGF.CGM); - // FIXME: Do this when the target isn't aarch64. + llvm::Triple::ArchType Arch = CGF.CGM.getTriple().getArch(); + + // FIXME: Do this on all targets and at -O0 too. This can be enabled only if + // the target backend knows how to handle the operand bundle. if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && - CGF.CGM.getTarget().getTriple().isAArch64()) { + (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) { llvm::Value *bundleArgs[] = {EP}; llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs); auto *oldCall = cast(value); diff --git a/clang/test/CodeGenObjC/arc-blocks.m b/clang/test/CodeGenObjC/arc-blocks.m index ab0ee3789cba8..f4366936dd726 100644 --- a/clang/test/CodeGenObjC/arc-blocks.m +++ b/clang/test/CodeGenObjC/arc-blocks.m @@ -125,9 +125,9 @@ void test4(void) { // 0x02000000 - has copy/dispose helpers strong // CHECK-NEXT: store i32 838860800, i32* [[T0]] // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 - // CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]] + // CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) + // CHECK-NEXT: store i8* [[T0]], i8** [[SLOT]] // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT // CHECK: store i32 -1040187392, @@ -179,8 +179,8 @@ void test5(void) { // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]]) - // CHECK: [[T0:%.*]] = call i8* @test5_source() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test5_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: store i8* [[T1]], i8** [[VAR]], // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT @@ -210,8 +210,8 @@ void test6(void) { // 0x02000000 - has copy/dispose helpers weak // CHECK-NEXT: store i32 1107296256, i32* [[T0]] // CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 - // CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @test6_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[SLOT]], i8* [[T1]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6 @@ -256,8 +256,8 @@ void test7(void) { // CHECK-LABEL: define{{.*}} void @test7() // CHECK: [[VAR:%.*]] = alloca i8*, // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], - // CHECK: [[T0:%.*]] = call i8* @test7_source() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test7_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[VAR]], i8* [[T1]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) // 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT @@ -324,8 +324,8 @@ id test9(void) { // CHECK-NEXT: tail call i8* @llvm.objc.autoreleaseReturnValue // CHECK-NEXT: ret i8* -// CHECK: call i8* @test9_produce() -// CHECK-NEXT: call i8* @llvm.objc.retain +// CHECK: call i8* @test9_produce() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( // CHECK-NEXT: ret i8* } diff --git a/clang/test/CodeGenObjC/arc-bridged-cast.m b/clang/test/CodeGenObjC/arc-bridged-cast.m index c8a9d9988f581..da8f0e5e81acc 100644 --- a/clang/test/CodeGenObjC/arc-bridged-cast.m +++ b/clang/test/CodeGenObjC/arc-bridged-cast.m @@ -40,9 +40,8 @@ void bridge_transfer_from_cf(int *i) { void bridge_from_cf(int *i) { // CHECK: store i32 7 *i = 7; - // CHECK: call i8* @CFCreateSomething() + // CHECK: call i8* @CFCreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj1 = (__bridge id)CFCreateSomething(); - // CHECK: llvm.objc.retainAutoreleasedReturnValue // CHECK: store i32 11 *i = 11; // CHECK: call i8* @CFCreateSomething() @@ -60,14 +59,12 @@ void bridge_from_cf(int *i) { // CHECK-LABEL: define{{.*}} void @bridge_retained_of_cf void bridge_retained_of_cf(int *i) { *i = 7; - // CHECK: call i8* @CreateSomething() + // CHECK: call i8* @CreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething(); - // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue // CHECK: store i32 11 *i = 11; - // CHECK: call i8* @CreateSomething() + // CHECK: call i8* @CreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] (__bridge_retained CFTypeRef)CreateSomething(), *i = 13; - // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue // CHECK: store i32 13 // CHECK: store i32 17 *i = 17; @@ -99,8 +96,7 @@ void bridge_of_cf(int *i) { // CHECK-LABEL: define{{.*}} %struct.__CFString* @bridge_of_paren_expr() CFStringRef bridge_of_paren_expr() { - // CHECK-NOT: call i8* @llvm.objc.retainAutoreleasedReturnValue( - // CHECK-NOT: call void @llvm.objc.release( + // CHECK-NOT: "@llvm.objc" CFStringRef r = (__bridge CFStringRef)(CreateNSString()); r = (__bridge CFStringRef)((NSString *)(CreateNSString())); return r; diff --git a/clang/test/CodeGenObjC/arc-literals.m b/clang/test/CodeGenObjC/arc-literals.m index a42c4b18f5c82..0266a62ea53ca 100644 --- a/clang/test/CodeGenObjC/arc-literals.m +++ b/clang/test/CodeGenObjC/arc-literals.m @@ -14,17 +14,13 @@ // CHECK-LABEL: define{{.*}} void @test_numeric() void test_numeric() { - // CHECK: {{call.*objc_msgSend.*i32 17}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{call.*objc_msgSend.*i32 17.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}} id ilit = @17; - // CHECK: {{call.*objc_msgSend.*i32 25}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{call.*objc_msgSend.*i32 25.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}} id ulit = @25u; - // CHECK: {{call.*objc_msgSend.*i64 42}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{call.*objc_msgSend.*i64 42.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}} id ulllit = @42ull; - // CHECK: {{call.*objc_msgSend.*i8 signext 97}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{call.*objc_msgSend.*i8 signext 97.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}} id charlit = @'a'; // CHECK: call void @llvm.objc.release // CHECK: call void @llvm.lifetime.end @@ -58,8 +54,7 @@ void test_array(id a, id b) { // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** - // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) - // CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] // CHECK: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]]) id arr = @[a, b]; @@ -102,8 +97,8 @@ void test_dictionary(id k1, id o1, id k2, id o2) { // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8** // CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8** - // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) - // CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) + // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]]) // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]]) id dict = @{ k1 : o1, k2 : o2 }; @@ -133,10 +128,8 @@ void test_property(B *b) { // Invoke 'prop' // CHECK: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES // CHECK-NEXT: [[T1:%.*]] = bitcast - // CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8* - // CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) - // CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]* + // CHECK-NEXT: [[V0:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[B]]* [[V0]]) // CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8* // Store to array. @@ -147,8 +140,8 @@ void test_property(B *b) { // CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES // CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8* // CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8** - // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) - // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]]) + // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T3]]) // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V1]]) // CHECK-NEXT: bitcast // CHECK-NEXT: bitcast diff --git a/clang/test/CodeGenObjC/arc-precise-lifetime.m b/clang/test/CodeGenObjC/arc-precise-lifetime.m index c1bad4bf56217..04c3f1b46f1d9 100644 --- a/clang/test/CodeGenObjC/arc-precise-lifetime.m +++ b/clang/test/CodeGenObjC/arc-precise-lifetime.m @@ -41,11 +41,9 @@ void test1a_message(void) { // CHECK: [[C:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** @@ -75,11 +73,9 @@ void test1a_property(void) { // CHECK: [[C:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** @@ -109,11 +105,9 @@ void test1b_message(void) { // CHECK: [[C:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** @@ -140,11 +134,9 @@ void test1b_property(void) { // CHECK: [[C:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** @@ -171,11 +163,9 @@ void test1c_message(void) { // CHECK: [[PC:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** @@ -204,11 +194,9 @@ void test1c_property(void) { // CHECK: [[PC:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** @@ -237,11 +225,9 @@ void test1d_message(void) { // CHECK: [[PC:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** @@ -267,11 +253,9 @@ void test1d_property(void) { // CHECK: [[PC:%.*]] = alloca i8*, align 8 // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8* // CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]]) - // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* - // CHECK-NEXT: store [[TEST1]]* [[T3]] + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]]) + // CHECK-NEXT: store [[TEST1]]* [[T0]] // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]]) // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** diff --git a/clang/test/CodeGenObjC/arc-rv-attr.m b/clang/test/CodeGenObjC/arc-rv-attr.m index f341f735d720e..6e3dcf1986d1e 100644 --- a/clang/test/CodeGenObjC/arc-rv-attr.m +++ b/clang/test/CodeGenObjC/arc-rv-attr.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK +// RUN: %clang_cc1 -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK @class A; diff --git a/clang/test/CodeGenObjC/arc-ternary-op.m b/clang/test/CodeGenObjC/arc-ternary-op.m index c75f5d9b63b50..13f529c5e9dde 100644 --- a/clang/test/CodeGenObjC/arc-ternary-op.m +++ b/clang/test/CodeGenObjC/arc-ternary-op.m @@ -131,8 +131,8 @@ void test2(int cond) { // CHECK-NEXT: store i1 false, i1* [[RUN_CLEANUP]] // CHECK-NEXT: br i1 // Within true branch, cleanup enabled. - // CHECK: [[T0:%.*]] = call i8* @test2_producer() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test2_producer() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_SAVE]] // CHECK-NEXT: store i1 true, i1* [[RUN_CLEANUP]] // CHECK-NEXT: br label diff --git a/clang/test/CodeGenObjC/arc-unsafeclaim.m b/clang/test/CodeGenObjC/arc-unsafeclaim.m index 08ff8eca8da51..ca82bbe946bc3 100644 --- a/clang/test/CodeGenObjC/arc-unsafeclaim.m +++ b/clang/test/CodeGenObjC/arc-unsafeclaim.m @@ -1,6 +1,8 @@ // Make sure it works on x86-64. // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=NOTAIL-CALL +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s -check-prefix=ATTACHED-CALL + // Make sure it works on x86-32. // RUN: %clang_cc1 -triple i386-apple-darwin11 -fobjc-runtime=macosx-fragile-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL @@ -43,6 +45,10 @@ void test_assign() { // DISABLED-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // DISABLED-NEXT: [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) +// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_assign_assign() { __unsafe_unretained id x, y; x = y = makeA(); @@ -65,6 +71,10 @@ void test_assign_assign() { // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_strong_assign_assign() { __strong id x; __unsafe_unretained id y; @@ -92,6 +102,10 @@ void test_strong_assign_assign() { // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_assign_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_assign_strong_assign() { __unsafe_unretained id x; __strong id y; @@ -119,6 +133,10 @@ void test_assign_strong_assign() { // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_strong_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_init() { __unsafe_unretained id x = makeA(); } @@ -136,6 +154,10 @@ void test_init() { // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_init() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_init_assignment() { __unsafe_unretained id x; __unsafe_unretained id y = x = makeA(); @@ -158,6 +180,10 @@ void test_init_assignment() { // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_init_assignment() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_strong_init_assignment() { __unsafe_unretained id x; __strong id y = x = makeA(); @@ -182,6 +208,10 @@ void test_strong_init_assignment() { // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_init_assignment() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_init_strong_assignment() { __strong id x; __unsafe_unretained id y = x = makeA(); @@ -208,6 +238,10 @@ void test_init_strong_assignment() { // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_init_strong_assignment() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_ignored() { makeA(); } @@ -220,6 +254,10 @@ void test_ignored() { // CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_ignored() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_cast_to_void() { (void) makeA(); } @@ -232,6 +270,9 @@ void test_cast_to_void() { // CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_cast_to_void() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) // This is always at the end of the module. diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m index c335e76e0399a..a57f1bf21dcce 100644 --- a/clang/test/CodeGenObjC/arc.m +++ b/clang/test/CodeGenObjC/arc.m @@ -316,16 +316,12 @@ void test10() { // CHECK-NEXT: load [[TEST10]]*, [[TEST10]]** [[X]], align // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}} // CHECK-NEXT: bitcast - // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[V:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* + // CHECK-NEXT: [[V:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[V]]) // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}} // CHECK-NEXT: bitcast - // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* + // CHECK-NEXT: [[T3:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[T3]]) // CHECK-NEXT: [[T4:%.*]] = bitcast [[TEST10]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST10]]* [[V]] to i8* @@ -370,14 +366,14 @@ void test12(void) { __weak id x = test12_helper(); // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) - // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @test12_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[X]], i8* [[T1]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) x = test12_helper(); - // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @test12_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T1]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) @@ -513,8 +509,8 @@ void test19() { extern id test19_helper(void); x[2] = test19_helper(); - // CHECK-NEXT: [[CALL:%.*]] = call i8* @test19_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) [[NUW]] + // CHECK-NEXT: [[T1:%.*]] = call i8* @test19_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[X]], i64 0, i64 2 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]] // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]] @@ -875,8 +871,8 @@ - (Test30_helper*) initHelper { __attribute__((ns_returns_retained)) id test32(void) { // CHECK-LABEL: define{{.*}} i8* @test32() -// CHECK: [[CALL:%.*]] = call i8* @test32_helper() -// CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) +// CHECK: [[T0:%.*]] = call i8* @test32_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T0]] extern id test32_helper(void); return test32_helper(); @@ -1044,8 +1040,8 @@ @implementation Test43 - (id) test __attribute__((ns_returns_retained)) { extern id test43_produce(void); return test43_produce(); - // CHECK: call i8* @test43_produce() - // CHECK-NEXT: notail call i8* @llvm.objc.retainAutoreleasedReturnValue( + // CHECK: call i8* @test43_produce(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( // CHECK-NEXT: ret } @end @@ -1066,8 +1062,8 @@ void test46(__weak id *wp, __weak volatile id *wvp) { // TODO: this is sub-optimal, we should retain at the actual call site. - // CHECK: [[T0:%.*]] = call i8* @test46_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test46_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) @@ -1075,8 +1071,8 @@ void test46(__weak id *wp, __weak volatile id *wvp) { // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id x = *wp = test46_helper(); - // CHECK: [[T0:%.*]] = call i8* @test46_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test46_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) @@ -1095,8 +1091,8 @@ void test47(void) { // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: [[CALL:%.*]] = call i8* @test47_helper() - // CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @test47_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* [[T0]], i8** [[X]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) @@ -1119,8 +1115,8 @@ void test48(void) { // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.initWeak(i8** [[X]], i8* null) - // CHECK-NEXT: [[T1:%.*]] = call i8* @test48_helper() - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @test48_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T2]]) // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T2]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T3]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) @@ -1138,10 +1134,10 @@ void test49(void) { // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: [[CALL:%.*]] = call i8* @test49_helper() - // CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @test49_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.autorelease(i8* [[T0]]) - // CHECK-NEXT: store i8* [[T2]], i8** [[X]] + // CHECK-NEXT: store i8* [[T1]], i8** [[X]] // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) // CHECK-NEXT: store i8* [[T3]], i8** [[X]] // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* @@ -1207,8 +1203,8 @@ void test53(void) { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) -// CHECK-NEXT: [[T0:%.*]] = call i8* @test53_helper() -// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @test53_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: store i8* [[T1]], i8** [[Y]], // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]], // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) @@ -1260,8 +1256,8 @@ @implementation Test56 // CHECK: define internal i8* @"\01+[Test56 make]"( + (id) make { extern id test56_helper(void); - // CHECK: [[T0:%.*]] = call i8* @test56_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test56_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: ret i8* [[T1]] return test56_helper(); } @@ -1327,8 +1323,8 @@ void test59(void) { } // CHECK-LABEL: define{{.*}} void @test59() - // CHECK: [[T0:%.*]] = call i8* @test59_getlock() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test59_getlock(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: call i32 @objc_sync_enter(i8* [[T1]]) // CHECK-NEXT: call void @test59_body() // CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T1]]) @@ -1349,8 +1345,8 @@ void test61(void) { extern id test61_make(void); - // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) @@ -1359,12 +1355,12 @@ void test61(void) { // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) - // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @test61_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ - // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) - // CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) + // CHECK-NEXT: [[T5:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T5]]) // CHECK-NEXT: store i8* [[T5]], i8** [[Y]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id y = [test61_make() performSelector: @selector(test61_id)]; @@ -1399,8 +1395,8 @@ void test62(void) { // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]] // CHECK-NEXT: br i1 [[T1]], - // CHECK: [[T0:%.*]] = call i8* @test62_make() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test62_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]] // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]] // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null @@ -1453,19 +1449,17 @@ void test66(void) { [test66_receiver() consume: test66_arg()]; } // CHECK-LABEL: define{{.*}} void @test66() -// CHECK: [[T0:%.*]] = call [[TEST66:%.*]]* @test66_receiver() -// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST66]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) -// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST66]]* -// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg() -// CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) +// CHECK: [[T3:%.*]] = call [[TEST66:%.*]]* @test66_receiver(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST66]]* [[T3]]) +// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]]) // CHECK-NEXT: [[T6:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES // CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* // CHECK-NEXT: [[SIX:%.*]] = icmp eq i8* [[T7]], null // CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label [[CALL:%.*]] -// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T5]]) +// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T4]]) // CHECK-NEXT: br label [[CONT:%.*]] -// CHECK: call void @llvm.objc.release(i8* [[T5]]) [[NUW]] +// CHECK: call void @llvm.objc.release(i8* [[T4]]) [[NUW]] // CHECK-NEXT: br label [[CONT:%.*]] // CHECK: [[T8:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* // CHECK-NEXT: call void @llvm.objc.release(i8* [[T8]]) @@ -1494,8 +1488,8 @@ void test68(void) { // CHECK: [[CL:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CLPTR1]]) -// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper() -// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @test67_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: store i8* [[T1]], i8** [[CL]], align 8 // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[CL]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) diff --git a/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m b/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m index 3b4c71d54ffb4..79db492eb1ee7 100644 --- a/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m +++ b/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m @@ -24,8 +24,7 @@ void doRange() { // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSRange ns_range = { .location = 0, .length = 42 }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *range = @(ns_range); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -43,8 +42,7 @@ void doPoint() { // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSPoint ns_point = { .x = 42, .y = 24 }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *point = @(ns_point); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -62,8 +60,7 @@ void doSize() { // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSSize ns_size = { .width = 42, .height = 24 }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *size = @(ns_size); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -83,8 +80,7 @@ void doRect() { NSPoint ns_point = { .x = 42, .y = 24 }; NSSize ns_size = { .width = 42, .height = 24 }; NSRect ns_rect = { .origin = ns_point, .size = ns_size }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *rect = @(ns_rect); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -102,8 +98,7 @@ void doNSEdgeInsets() { // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSEdgeInsets ns_edge_insets; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *edge_insets = @(ns_edge_insets); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -121,8 +116,7 @@ void doRangeRValue() { // CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}} // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *range_rvalue = @(getRange()); // CHECK: call void @llvm.objc.release // CHECK: ret void diff --git a/clang/test/CodeGenObjC/os_log.m b/clang/test/CodeGenObjC/os_log.m index fc03f0e6a8db9..542d9c79f7e8d 100644 --- a/clang/test/CodeGenObjC/os_log.m +++ b/clang/test/CodeGenObjC/os_log.m @@ -26,10 +26,11 @@ + (id)m1; // CHECK-O2: %[[V0:.*]] = call i8* @llvm.objc.retain( // CHECK-O2: store i8* %[[V0]], i8** %[[A_ADDR]], align 8, // CHECK-O0: call void @llvm.objc.storeStrong(i8** %[[A_ADDR]], i8* %{{.*}}) -// CHECK: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() -// CHECK: %[[V2:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* -// CHECK: %[[V3:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V2]]) -// CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to %{{.*}}* +// CHECK-O2: %[[V4:.*]] = call %{{.*}}* (...) @GenString() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() +// CHECK-O0: %[[V2:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* +// CHECK-O0: %[[V3:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V2]]) +// CHECK-O0: %[[V4:.*]] = bitcast i8* %[[V3]] to %{{.*}}* // CHECK: %[[V5:.*]] = bitcast %{{.*}}* %[[V4]] to i8* // CHECK: %[[V6:.*]] = call i8* @llvm.objc.retain(i8* %[[V5]]) // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to %{{.*}}* @@ -71,10 +72,11 @@ void test_builtin_os_log2(void *buf, id __unsafe_unretained a) { // CHECK-LABEL: define{{.*}} void @test_builtin_os_log3( // CHECK: alloca i8*, align 8 // CHECK: %[[OS_LOG_ARG:.*]] = alloca i8*, align 8 -// CHECK: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() -// CHECK: %[[V1:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* -// CHECK: %[[V2:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]]) -// CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to %{{.*}}* +// CHECK-O2: %[[V3:.*]] = call %{{.*}}* (...) @GenString() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() +// CHECK-O0: %[[V1:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* +// CHECK-O0: %[[V2:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]]) +// CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %{{.*}}* // CHECK: %[[V4:.*]] = bitcast %{{.*}}* %[[V3]] to i8* // CHECK: %[[V5:.*]] = call i8* @llvm.objc.retain(i8* %[[V4]]) // CHECK: store i8* %[[V5]], i8** %[[OS_LOG_ARG]], align 8 @@ -97,13 +99,15 @@ void test_builtin_os_log3(void *buf) { // CHECK: alloca i8*, align 8 // CHECK: %[[OS_LOG_ARG:.*]] = alloca i8*, align 8 // CHECK: %[[OS_LOG_ARG2:.*]] = alloca i8*, align 8 -// CHECK: %[[CALL:.*]] = call {{.*}} @objc_msgSend -// CHECK: %[[V4:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]]) +// CHECK-O2: %[[V4:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL:.*]] = call {{.*}} @objc_msgSend +// CHECK-O0: %[[V4:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]]) // CHECK: %[[V5:.*]] = call i8* @llvm.objc.retain(i8* %[[V4]]) // CHECK: store i8* %[[V5]], i8** %[[OS_LOG_ARG]], align 8 // CHECK: %[[V6:.*]] = ptrtoint i8* %[[V5]] to i64 -// CHECK: %[[CALL1:.*]] = call {{.*}} @objc_msgSend -// CHECK: %[[V10:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]]) +// CHECK-O2: %[[V10:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL1:.*]] = call {{.*}} @objc_msgSend +// CHECK-O0: %[[V10:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]]) // CHECK: %[[V11:.*]] = call i8* @llvm.objc.retain(i8* %[[V10]]) // CHECK: store i8* %[[V11]], i8** %[[OS_LOG_ARG2]], align 8 // CHECK: %[[V12:.*]] = ptrtoint i8* %[[V11]] to i64 diff --git a/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm b/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm index 37a68136dd56d..5bbdf8ba3ba0c 100644 --- a/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm +++ b/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm @@ -4,9 +4,9 @@ void test0(id x) { extern void test0_helper(id (^)(void)); test0_helper([=]() { return x; }); // CHECK-LABEL: define internal i8* @___Z5test0P11objc_object_block_invoke - // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv" - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]]) + // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv"{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) + // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T2]] } @@ -27,9 +27,9 @@ void test1() { extern void test1_helper(id (*)(void)); test1_helper([](){ return test1_rv; }); // CHECK-LABEL: define internal i8* @"_ZZ5test1vEN3$_18__invokeEv" - // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv" - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]]) + // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv"{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) + // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T2]] } diff --git a/clang/test/CodeGenObjCXX/arc-globals.mm b/clang/test/CodeGenObjCXX/arc-globals.mm index d5116ee96c93b..ae0ef68307679 100644 --- a/clang/test/CodeGenObjCXX/arc-globals.mm +++ b/clang/test/CodeGenObjCXX/arc-globals.mm @@ -6,15 +6,15 @@ id getObject(); // CHECK-LABEL: define internal void @__cxx_global_var_init -// CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue +// CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use // CHECK-NEXT: {{store i8*.*@global_obj}} // CHECK-NEXT: ret void id global_obj = getObject(); // CHECK-LABEL: define internal void @__cxx_global_var_init -// CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue +// CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use // CHECK-NEXT: {{store i8*.*@global_obj2}} // CHECK-NEXT: ret void id global_obj2 = getObject(); diff --git a/clang/test/CodeGenObjCXX/arc-references.mm b/clang/test/CodeGenObjCXX/arc-references.mm index 250e27d4c6dd7..fabdaa8fc10b4 100644 --- a/clang/test/CodeGenObjCXX/arc-references.mm +++ b/clang/test/CodeGenObjCXX/arc-references.mm @@ -9,13 +9,13 @@ @interface A // Lifetime extension for binding a reference to an rvalue // CHECK-LABEL: define{{.*}} void @_Z5test0v() void test0() { - // CHECK: call i8* @_Z9getObjectv - // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( const __strong id &ref1 = getObject(); // CHECK: call void @_Z6calleev callee(); - // CHECK: call i8* @_Z9getObjectv - // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( // CHECK-NEXT: call i8* @llvm.objc.autorelease const __autoreleasing id &ref2 = getObject(); // CHECK: call void @_Z6calleev @@ -84,8 +84,8 @@ void test5(__strong id &x) { } // CHECK-LABEL: define internal void @__cxx_global_var_init( -// CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue +// CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( const __strong id &global_ref = getObject(); // Note: we intentionally don't release the object. diff --git a/clang/test/CodeGenObjCXX/arc.mm b/clang/test/CodeGenObjCXX/arc.mm index bb576b051161d..abf4cbeb66f79 100644 --- a/clang/test/CodeGenObjCXX/arc.mm +++ b/clang/test/CodeGenObjCXX/arc.mm @@ -19,8 +19,8 @@ void test0(__weak id *wp, __weak volatile id *wvp) { // TODO: this is sub-optimal, we should retain at the actual call site. // TODO: in the non-volatile case, we do not need to be reloading. - // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @_Z12test0_helperv() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) @@ -28,8 +28,8 @@ void test0(__weak id *wp, __weak volatile id *wvp) { // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id x = *wp = test0_helper(); - // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @_Z12test0_helperv() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T2]]) @@ -163,25 +163,20 @@ void test35(Test35_Helper x0, Test35_Helper *x0p) { // CHECK-LABEL: define{{.*}} void @_Z7test35b13Test35_HelperPS_ void test35b(Test35_Helper x0, Test35_Helper *x0p) { // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* @_ZN13Test35_Helper11makeObject3Ev - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @_ZN13Test35_Helper11makeObject3Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj1 = Test35_Helper::makeObject3(); // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj2 = x0.makeObject4(); // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj3 = x0p->makeObject4(); id (Test35_Helper::*pmf)() = &Test35_Helper::makeObject4; // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* % - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* %{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj4 = (x0.*pmf)(); // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* % - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* %{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj5 = (x0p->*pmf)(); // CHECK: call void @llvm.objc.release @@ -222,26 +217,24 @@ - (NSArray *) array; extern template void test37(Test37 *a); template void test37(Test37 *a); // CHECK-LABEL: define weak_odr void @_Z6test37I6Test37EvPT_( -// CHECK: [[T0:%.*]] = call [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)( -// CHECK-NEXT: [[T1:%.*]] = bitcast [[NSARRAY]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) -// CHECK-NEXT: [[COLL:%.*]] = bitcast i8* [[T2]] to [[NSARRAY]]* +// CHECK: [[T2:%.*]] = call [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)({{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T2]]) // Make sure it's not immediately released before starting the iteration. // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_ -// CHECK-NEXT: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK-NEXT: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: @objc_msgSend // This bitcast is for the mutation check. -// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: @objc_enumerationMutation // This bitcast is for the 'next' message send. -// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: @objc_msgSend // This bitcast is for the final release. -// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) template @@ -250,10 +243,8 @@ void send_release() { } // CHECK-LABEL: define weak_odr void @_Z12send_releaseIiEvv( -// CHECK: call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend -// CHECK-NEXT: bitcast -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue -// CHECK-NEXT: bitcast +// CHECK: call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( // CHECK-NEXT: bitcast // CHECK-NEXT: call void @llvm.objc.release // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenObjCXX/literals.mm b/clang/test/CodeGenObjCXX/literals.mm index 3cdde2089de83..9a76382b7d61a 100644 --- a/clang/test/CodeGenObjCXX/literals.mm +++ b/clang/test/CodeGenObjCXX/literals.mm @@ -28,22 +28,19 @@ void test_array() { // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPX]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]]) // CHECK-NEXT: call void @_ZN1XC1Ev({{.*}} [[TMPX]]) - // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv - // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]]) - // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] + // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT0]], i8** [[ELEMENT0]] // Initializing the second element // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1 // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPY]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]]) // CHECK-NEXT: invoke void @_ZN1YC1Ev({{.*}} [[TMPY]]) - // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv - // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]]) - // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] + // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT1]], i8** [[ELEMENT1]] // Build the array - // CHECK: {{invoke.*@objc_msgSend}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id arr = @[ X(), Y() ]; // Destroy temporaries @@ -82,20 +79,17 @@ void test_array_instantiation() { // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]]) // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0 // CHECK: call void @_ZN1XC1Ev - // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv - // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]]) - // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] + // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT0]], i8** [[ELEMENT0]] // Initializing the second element // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1 // CHECK: invoke void @_ZN1YC1Ev - // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv - // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]]) - // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] + // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT1]], i8** [[ELEMENT1]] // Build the array - // CHECK: {{invoke.*@objc_msgSend}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id arr = @[ X(), Y() ]; // Destroy temporaries diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp index 80c38f3ec341d..845e316047ec2 100644 --- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp +++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp @@ -13,6 +13,7 @@ #include "llvm/CodeGen/PreISelIntrinsicLowering.h" #include "llvm/Analysis/ObjCARCInstKind.h" +#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -91,7 +92,20 @@ static bool lowerObjCCall(Function &F, const char *NewFn, CallInst::TailCallKind OverridingTCK = getOverridingTailCallKind(F); for (auto I = F.use_begin(), E = F.use_end(); I != E;) { - auto *CI = cast(I->getUser()); + auto *CB = cast(I->getUser()); + + if (CB->getCalledFunction() != &F) { + objcarc::ARCInstKind Kind = objcarc::getAttachedARCFunctionKind(CB); + (void)Kind; + assert((Kind == objcarc::ARCInstKind::RetainRV || + Kind == objcarc::ARCInstKind::ClaimRV) && + "use expected to be the argument of operand bundle " + "\"clang.arc.attachedcall\""); + I++->set(FCache.getCallee()); + continue; + } + + auto *CI = cast(CB); assert(CI->getCalledFunction() && "Cannot lower an indirect call!"); ++I; diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp index 296610eedccd9..1ca6ddabac5bc 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp @@ -114,8 +114,8 @@ CallInst *BundledRetainClaimRVs::insertRVCallWithColors( } BundledRetainClaimRVs::~BundledRetainClaimRVs() { - if (ContractPass) { - for (auto P : RVCalls) { + for (auto P : RVCalls) { + if (ContractPass) { CallBase *CB = P.second; // At this point, we know that the annotated calls can't be tail calls // as they are followed by marker instructions and retainRV/claimRV @@ -124,14 +124,18 @@ BundledRetainClaimRVs::~BundledRetainClaimRVs() { if (auto *CI = dyn_cast(CB)) CI->setTailCallKind(CallInst::TCK_NoTail); - // Remove the ARC intrinsic function operand from the operand bundle. - OperandBundleDef OB("clang.arc.attachedcall", None); - auto *NewCB = CallBase::Create(CB, OB, CB); - CB->replaceAllUsesWith(NewCB); - CB->eraseFromParent(); + if (UseMarker) { + // Remove the retainRV/claimRV function operand from the operand bundle + // to reflect the fact that the backend is responsible for emitting only + // the marker instruction, but not the retainRV/claimRV call. + OperandBundleDef OB("clang.arc.attachedcall", None); + auto *NewCB = CallBase::Create(CB, OB, CB); + CB->replaceAllUsesWith(NewCB); + CB->eraseFromParent(); + } } - } else { - for (auto P : RVCalls) + + if (!ContractPass || !UseMarker) EraseInstruction(P.first); } diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.h b/llvm/lib/Transforms/ObjCARC/ObjCARC.h index 62f88a8cc02ba..2b47bec7ffe82 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARC.h +++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.h @@ -105,7 +105,8 @@ CallInst *createCallInstWithColors( class BundledRetainClaimRVs { public: - BundledRetainClaimRVs(bool ContractPass) : ContractPass(ContractPass) {} + BundledRetainClaimRVs(bool ContractPass, bool UseMarker) + : ContractPass(ContractPass), UseMarker(UseMarker) {} ~BundledRetainClaimRVs(); /// Insert a retainRV/claimRV call to the normal destination blocks of invokes @@ -155,6 +156,9 @@ class BundledRetainClaimRVs { DenseMap RVCalls; bool ContractPass; + + /// Indicates whether the target uses a special inline-asm marker. + bool UseMarker; }; } // end namespace objcarc diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp index 185a19fc47f40..c2ed94e8e1f62 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -434,13 +434,21 @@ bool ObjCARCContract::tryToPeepholeInstruction( LLVM_FALLTHROUGH; case ARCInstKind::RetainRV: case ARCInstKind::ClaimRV: { - // If we're compiling for a target which needs a special inline-asm - // marker to do the return value optimization and the retainRV/claimRV call - // wasn't bundled with a call, insert the marker now. + bool IsInstContainedInBundle = BundledInsts->contains(Inst); + + // Return now if the target doesn't need a special inline-asm marker. Return + // true if this is a bundled retainRV/claimRV call, which is going to be + // erased at the end of this pass, to avoid undoing objc-arc-expand and + // replacing uses of the retainRV/claimRV call's argument with its result. if (!RVInstMarker) - return false; + return IsInstContainedInBundle; + + // The target needs a special inline-asm marker. - if (BundledInsts->contains(Inst)) + // We don't have to emit the marker if this is a bundled call since the + // backend is responsible for emitting it. Return false to undo + // objc-arc-expand. + if (IsInstContainedInBundle) return false; BasicBlock::iterator BBI = Inst->getIterator(); @@ -540,7 +548,7 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) { AA = A; DT = D; PA.setAA(A); - BundledRetainClaimRVs BRV(true); + BundledRetainClaimRVs BRV(true, RVInstMarker); BundledInsts = &BRV; std::pair R = BundledInsts->insertAfterInvokes(F, DT); diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 89e62267389f2..53373f857d5e0 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -2462,7 +2462,7 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) { return false; Changed = CFGChanged = false; - BundledRetainClaimRVs BRV(false); + BundledRetainClaimRVs BRV(false, objcarc::getRVInstMarker(*F.getParent())); BundledInsts = &BRV; LLVM_DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName() diff --git a/llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll b/llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll new file mode 100644 index 0000000000000..4fc238d7407d6 --- /dev/null +++ b/llvm/test/Transforms/ObjCARC/contract-attached-call-no-marker.ll @@ -0,0 +1,24 @@ +; RUN: opt -objc-arc-contract -S < %s | FileCheck %s +; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s + +; CHECK-LABEL: define void @test0() { +; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +; CHECK-NEXT: ret void + +define void @test0() { + %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + ret void +} + +; CHECK-LABEL: define void @test1() { +; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] +; CHECK-NEXT: ret void + +define void @test1() { + %call1 = call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] + ret void +} + +declare i8* @foo() +declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) +declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*) diff --git a/llvm/test/Transforms/PreISelIntrinsicLowering/objc-arc.ll b/llvm/test/Transforms/PreISelIntrinsicLowering/objc-arc.ll index aff01910cd9b3..67d8ff697e60d 100644 --- a/llvm/test/Transforms/PreISelIntrinsicLowering/objc-arc.ll +++ b/llvm/test/Transforms/PreISelIntrinsicLowering/objc-arc.ll @@ -3,6 +3,9 @@ ; Make sure calls to the objc intrinsics are translated to calls in to the ; runtime +declare i8* @foo() +declare i32 @__gxx_personality_v0(...) + define i8* @test_objc_autorelease(i8* %arg0) { ; CHECK-LABEL: test_objc_autorelease ; CHECK-NEXT: entry @@ -153,6 +156,30 @@ entry: ret i8* %0 } +define void @test_objc_retainAutoreleasedReturnValue_bundle() { +; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue_bundle( +; CHECK-NEXT: call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] + call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + ret void +} + +define void @test_objc_retainAutoreleasedReturnValue_bundle_invoke() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue_bundle_invoke( +; CHECK-NEXT: entry +; CHECK-NEXT: invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ] +entry: + invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + to label %invoke.cont unwind label %lpad + +invoke.cont: + ret void + +lpad: + %1 = landingpad { i8*, i32 } + cleanup + resume { i8*, i32 } %1 +} + define i8* @test_objc_retainBlock(i8* %arg0) { ; CHECK-LABEL: test_objc_retainBlock ; CHECK-NEXT: entry @@ -193,6 +220,13 @@ entry: ret i8* %0 } +define void @test_objc_unsafeClaimAutoreleasedReturnValue_bundle() { +; CHECK-LABEL: test_objc_unsafeClaimAutoreleasedReturnValue_bundle( +; CHECK-NEXT: call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_unsafeClaimAutoreleasedReturnValue) ] + call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] + ret void +} + define i8* @test_objc_retainedObject(i8* %arg0) { ; CHECK-LABEL: test_objc_retainedObject ; CHECK-NEXT: entry From a160e45e45cd094327ed2881529559632f6dac19 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 10 Nov 2021 18:58:26 +0000 Subject: [PATCH 022/293] [AArch64] Add missing tests for i8 vector to half conversions. Conflicts: llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll (cherry-picked from c6258a20ef418ea8b636ecafa910c2ae28cbdd9d) --- .../CodeGen/AArch64/fp16-v8-instructions.ll | 128 +++++++++++++++--- 1 file changed, 106 insertions(+), 22 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll b/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll index bb2b450d173a0..873f91ca8bf30 100644 --- a/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll +++ b/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll @@ -277,21 +277,64 @@ define <8 x i16> @bitcast_h_to_i(float, <8 x half> %a) { ret <8 x i16> %2 } - -define <8 x half> @sitofp_i8(<8 x i8> %a) #0 { -; CHECK-LABEL: sitofp_i8: -; CHECK-NEXT: sshll v[[REG1:[0-9]+]].8h, v0.8b, #0 -; CHECK-NEXT: sshll2 [[LO:v[0-9]+\.4s]], v[[REG1]].8h, #0 -; CHECK-NEXT: sshll [[HI:v[0-9]+\.4s]], v[[REG1]].4h, #0 -; CHECK-DAG: scvtf [[HIF:v[0-9]+\.4s]], [[HI]] -; CHECK-DAG: scvtf [[LOF:v[0-9]+\.4s]], [[LO]] -; CHECK-DAG: fcvtn v[[LOREG:[0-9]+]].4h, [[LOF]] -; CHECK-DAG: fcvtn v0.4h, [[HIF]] -; CHECK: mov v0.d[1], v[[LOREG]].d[0] +define <4 x half> @sitofp_v4i8(<4 x i8> %a) #0 { +; CHECK-CVT-LABEL: sitofp_v4i8: +; CHECK-CVT-NEXT: shl v0.4h, v0.4h, #8 +; CHECK-CVT-NEXT: sshr v0.4h, v0.4h, #8 +; CHECK-CVT-NEXT: sshll v0.4s, v0.4h, #0 +; CHECK-CVT-NEXT: scvtf v0.4s, v0.4s +; CHECK-CVT-NEXT: fcvtn v0.4h, v0.4s +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: sitofp_v4i8: +; CHECK-FP16-NEXT: shl v0.4h, v0.4h, #8 +; CHECK-FP16-NEXT: sshr v0.4h, v0.4h, #8 +; CHECK-FP16-NEXT: scvtf v0.4h, v0.4h +; CHECK-FP16-NEXT: ret +; + %1 = sitofp <4 x i8> %a to <4 x half> + ret <4 x half> %1 +} + +define <8 x half> @sitofp_v8i8(<8 x i8> %a) #0 { +; CHECK-LABEL: sitofp_v8i8: +; CHECK-NEXT: sshll v0.8h, v0.8b, #0 +; CHECK-NEXT: sshll2 v1.4s, v0.8h, #0 +; CHECK-NEXT: sshll v0.4s, v0.4h, #0 +; CHECK-NEXT: scvtf v1.4s, v1.4s +; CHECK-NEXT: scvtf v0.4s, v0.4s +; CHECK-NEXT: fcvtn v1.4h, v1.4s +; CHECK-NEXT: fcvtn v0.4h, v0.4s +; CHECK-NEXT: mov v0.d[1], v1.d[0] +; CHECK-NEXT: ret +; %1 = sitofp <8 x i8> %a to <8 x half> ret <8 x half> %1 } +define <16 x half> @sitofp_v16i8(<16 x i8> %a) #0 { +; CHECK-LABEL: sitofp_v16i8: +; CHECK-NEXT: sshll2 v1.8h, v0.16b, #0 +; CHECK-NEXT: sshll2 v2.4s, v1.8h, #0 +; CHECK-NEXT: sshll v1.4s, v1.4h, #0 +; CHECK-NEXT: scvtf v2.4s, v2.4s +; CHECK-NEXT: scvtf v1.4s, v1.4s +; CHECK-NEXT: sshll v0.8h, v0.8b, #0 +; CHECK-NEXT: fcvtn v2.4h, v2.4s +; CHECK-NEXT: fcvtn v1.4h, v1.4s +; CHECK-NEXT: mov v1.d[1], v2.d[0] +; CHECK-NEXT: sshll2 v2.4s, v0.8h, #0 +; CHECK-NEXT: sshll v0.4s, v0.4h, #0 +; CHECK-NEXT: scvtf v2.4s, v2.4s +; CHECK-NEXT: scvtf v0.4s, v0.4s +; CHECK-NEXT: fcvtn v2.4h, v2.4s +; CHECK-NEXT: fcvtn v0.4h, v0.4s +; CHECK-NEXT: mov v0.d[1], v2.d[0] +; CHECK-NEXT: ret +; + %1 = sitofp <16 x i8> %a to <16 x half> + ret <16 x half> %1 +} define <8 x half> @sitofp_i16(<8 x i16> %a) #0 { ; CHECK-LABEL: sitofp_i16: @@ -307,7 +350,6 @@ define <8 x half> @sitofp_i16(<8 x i16> %a) #0 { ret <8 x half> %1 } - define <8 x half> @sitofp_i32(<8 x i32> %a) #0 { ; CHECK-LABEL: sitofp_i32: ; CHECK-DAG: scvtf [[OP1:v[0-9]+\.4s]], v0.4s @@ -331,20 +373,62 @@ define <8 x half> @sitofp_i64(<8 x i64> %a) #0 { ret <8 x half> %1 } -define <8 x half> @uitofp_i8(<8 x i8> %a) #0 { -; CHECK-LABEL: uitofp_i8: -; CHECK-NEXT: ushll v[[REG1:[0-9]+]].8h, v0.8b, #0 -; CHECK-NEXT: ushll2 [[LO:v[0-9]+\.4s]], v[[REG1]].8h, #0 -; CHECK-NEXT: ushll [[HI:v[0-9]+\.4s]], v[[REG1]].4h, #0 -; CHECK-DAG: ucvtf [[HIF:v[0-9]+\.4s]], [[HI]] -; CHECK-DAG: ucvtf [[LOF:v[0-9]+\.4s]], [[LO]] -; CHECK-DAG: fcvtn v[[LOREG:[0-9]+]].4h, [[LOF]] -; CHECK-DAG: fcvtn v0.4h, [[HIF]] -; CHECK: mov v0.d[1], v[[LOREG]].d[0] +define <4 x half> @uitofp_v4i8(<4 x i8> %a) #0 { +; CHECK-CVT-LABEL: uitofp_v4i8: +; CHECK-CVT-NEXT: bic v0.4h, #255, lsl #8 +; CHECK-CVT-NEXT: ushll v0.4s, v0.4h, #0 +; CHECK-CVT-NEXT: ucvtf v0.4s, v0.4s +; CHECK-CVT-NEXT: fcvtn v0.4h, v0.4s +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: uitofp_v4i8: +; CHECK-FP16-NEXT: bic v0.4h, #255, lsl #8 +; CHECK-FP16-NEXT: ucvtf v0.4h, v0.4h +; CHECK-FP16-NEXT: ret +; + %1 = uitofp <4 x i8> %a to <4 x half> + ret <4 x half> %1 +} + +define <8 x half> @uitofp_v8i8(<8 x i8> %a) #0 { +; CHECK-LABEL: uitofp_v8i8: +; CHECK-NEXT: ushll v0.8h, v0.8b, #0 +; CHECK-NEXT: ushll2 v1.4s, v0.8h, #0 +; CHECK-NEXT: ushll v0.4s, v0.4h, #0 +; CHECK-NEXT: ucvtf v1.4s, v1.4s +; CHECK-NEXT: ucvtf v0.4s, v0.4s +; CHECK-NEXT: fcvtn v1.4h, v1.4s +; CHECK-NEXT: fcvtn v0.4h, v0.4s +; CHECK-NEXT: mov v0.d[1], v1.d[0] +; CHECK-NEXT: ret +; %1 = uitofp <8 x i8> %a to <8 x half> ret <8 x half> %1 } +define <16 x half> @uitofp_v16i8(<16 x i8> %a) #0 { +; CHECK-LABEL: uitofp_v16i8: +; CHECK-NEXT: ushll2 v1.8h, v0.16b, #0 +; CHECK-NEXT: ushll2 v2.4s, v1.8h, #0 +; CHECK-NEXT: ushll v1.4s, v1.4h, #0 +; CHECK-NEXT: ucvtf v2.4s, v2.4s +; CHECK-NEXT: ucvtf v1.4s, v1.4s +; CHECK-NEXT: ushll v0.8h, v0.8b, #0 +; CHECK-NEXT: fcvtn v2.4h, v2.4s +; CHECK-NEXT: fcvtn v1.4h, v1.4s +; CHECK-NEXT: mov v1.d[1], v2.d[0] +; CHECK-NEXT: ushll2 v2.4s, v0.8h, #0 +; CHECK-NEXT: ushll v0.4s, v0.4h, #0 +; CHECK-NEXT: ucvtf v2.4s, v2.4s +; CHECK-NEXT: ucvtf v0.4s, v0.4s +; CHECK-NEXT: fcvtn v2.4h, v2.4s +; CHECK-NEXT: fcvtn v0.4h, v0.4s +; CHECK-NEXT: mov v0.d[1], v2.d[0] +; CHECK-NEXT: ret +; + %1 = uitofp <16 x i8> %a to <16 x half> + ret <16 x half> %1 +} define <8 x half> @uitofp_i16(<8 x i16> %a) #0 { ; CHECK-LABEL: uitofp_i16: From 93bcb8342e7352fc07979dd420a01bde1f30adfd Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 11 Nov 2021 08:47:15 +0000 Subject: [PATCH 023/293] [AArch64] Use custom lowering for {U,S}INT_TO_FP with i8. With fullfp16, it is cheaper to cast the {U,S}INT_TO_FP operand to i16 first, rather than promoting it to i32. The custom lowering for {U,S}INT_TO_FP already supports that, it just needs to be used. Reviewed By: dmgreen Differential Revision: https://reviews.llvm.org/D113601 (cherry-picked from c2ed9fd054797b2ba1fadb2e202e3afa5ec28d0b) --- .../Target/AArch64/AArch64ISelLowering.cpp | 12 +- .../CodeGen/AArch64/fp16-v8-instructions.ll | 134 ++++++++++-------- 2 files changed, 86 insertions(+), 60 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 987b27d480867..b4b82ffd635f4 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -1003,10 +1003,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, // elements smaller than i32, so promote the input to i32 first. setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v4i8, MVT::v4i32); setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v4i8, MVT::v4i32); - setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v8i8, MVT::v8i32); - setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v8i8, MVT::v8i32); - setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v16i8, MVT::v16i32); - setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v16i8, MVT::v16i32); // Similarly, there is no direct i32 -> f64 vector conversion instruction. setOperationAction(ISD::SINT_TO_FP, MVT::v2i32, Custom); @@ -1019,6 +1015,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, setOperationAction(ISD::UINT_TO_FP, MVT::v4i32, Custom); if (Subtarget->hasFullFP16()) { + setOperationAction(ISD::SINT_TO_FP, MVT::v8i8, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::v8i8, Custom); + setOperationAction(ISD::SINT_TO_FP, MVT::v16i8, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::v16i8, Custom); setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Custom); setOperationAction(ISD::UINT_TO_FP, MVT::v4i16, Custom); setOperationAction(ISD::SINT_TO_FP, MVT::v8i16, Custom); @@ -1026,6 +1026,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, } else { // when AArch64 doesn't have fullfp16 support, promote the input // to i32 first. + setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v8i8, MVT::v8i32); + setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v8i8, MVT::v8i32); + setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v16i8, MVT::v16i32); + setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v16i8, MVT::v16i32); setOperationPromotedToType(ISD::UINT_TO_FP, MVT::v4i16, MVT::v4i32); setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v4i16, MVT::v4i32); setOperationPromotedToType(ISD::SINT_TO_FP, MVT::v8i16, MVT::v8i32); diff --git a/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll b/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll index 873f91ca8bf30..8931e6238d243 100644 --- a/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll +++ b/llvm/test/CodeGen/AArch64/fp16-v8-instructions.ll @@ -297,41 +297,51 @@ define <4 x half> @sitofp_v4i8(<4 x i8> %a) #0 { } define <8 x half> @sitofp_v8i8(<8 x i8> %a) #0 { -; CHECK-LABEL: sitofp_v8i8: -; CHECK-NEXT: sshll v0.8h, v0.8b, #0 -; CHECK-NEXT: sshll2 v1.4s, v0.8h, #0 -; CHECK-NEXT: sshll v0.4s, v0.4h, #0 -; CHECK-NEXT: scvtf v1.4s, v1.4s -; CHECK-NEXT: scvtf v0.4s, v0.4s -; CHECK-NEXT: fcvtn v1.4h, v1.4s -; CHECK-NEXT: fcvtn v0.4h, v0.4s -; CHECK-NEXT: mov v0.d[1], v1.d[0] -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: sitofp_v8i8: +; CHECK-CVT-NEXT: sshll v0.8h, v0.8b, #0 +; CHECK-CVT-NEXT: sshll2 v1.4s, v0.8h, #0 +; CHECK-CVT-NEXT: sshll v0.4s, v0.4h, #0 +; CHECK-CVT-NEXT: scvtf v1.4s, v1.4s +; CHECK-CVT-NEXT: scvtf v0.4s, v0.4s +; CHECK-CVT-NEXT: fcvtn v1.4h, v1.4s +; CHECK-CVT-NEXT: fcvtn v0.4h, v0.4s +; CHECK-CVT-NEXT: mov v0.d[1], v1.d[0] +; CHECK-CVT-NEXT: ret ; +; CHECK-FP16-LABEL: sitofp_v8i8: +; CHECK-FP16-NEXT: sshll v0.8h, v0.8b, #0 +; CHECK-FP16-NEXT: scvtf v0.8h, v0.8h +; CHECK-FP16-NEXT: ret %1 = sitofp <8 x i8> %a to <8 x half> ret <8 x half> %1 } define <16 x half> @sitofp_v16i8(<16 x i8> %a) #0 { -; CHECK-LABEL: sitofp_v16i8: -; CHECK-NEXT: sshll2 v1.8h, v0.16b, #0 -; CHECK-NEXT: sshll2 v2.4s, v1.8h, #0 -; CHECK-NEXT: sshll v1.4s, v1.4h, #0 -; CHECK-NEXT: scvtf v2.4s, v2.4s -; CHECK-NEXT: scvtf v1.4s, v1.4s -; CHECK-NEXT: sshll v0.8h, v0.8b, #0 -; CHECK-NEXT: fcvtn v2.4h, v2.4s -; CHECK-NEXT: fcvtn v1.4h, v1.4s -; CHECK-NEXT: mov v1.d[1], v2.d[0] -; CHECK-NEXT: sshll2 v2.4s, v0.8h, #0 -; CHECK-NEXT: sshll v0.4s, v0.4h, #0 -; CHECK-NEXT: scvtf v2.4s, v2.4s -; CHECK-NEXT: scvtf v0.4s, v0.4s -; CHECK-NEXT: fcvtn v2.4h, v2.4s -; CHECK-NEXT: fcvtn v0.4h, v0.4s -; CHECK-NEXT: mov v0.d[1], v2.d[0] -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: sitofp_v16i8: +; CHECK-CVT-NEXT: sshll2 v1.8h, v0.16b, #0 +; CHECK-CVT-NEXT: sshll2 v2.4s, v1.8h, #0 +; CHECK-CVT-NEXT: sshll v1.4s, v1.4h, #0 +; CHECK-CVT-NEXT: scvtf v2.4s, v2.4s +; CHECK-CVT-NEXT: scvtf v1.4s, v1.4s +; CHECK-CVT-NEXT: sshll v0.8h, v0.8b, #0 +; CHECK-CVT-NEXT: fcvtn v2.4h, v2.4s +; CHECK-CVT-NEXT: fcvtn v1.4h, v1.4s +; CHECK-CVT-NEXT: mov v1.d[1], v2.d[0] +; CHECK-CVT-NEXT: sshll2 v2.4s, v0.8h, #0 +; CHECK-CVT-NEXT: sshll v0.4s, v0.4h, #0 +; CHECK-CVT-NEXT: scvtf v2.4s, v2.4s +; CHECK-CVT-NEXT: scvtf v0.4s, v0.4s +; CHECK-CVT-NEXT: fcvtn v2.4h, v2.4s +; CHECK-CVT-NEXT: fcvtn v0.4h, v0.4s +; CHECK-CVT-NEXT: mov v0.d[1], v2.d[0] +; CHECK-CVT-NEXT: ret ; +; CHECK-FP16-LABEL: sitofp_v16i8: +; CHECK-FP16-NEXT: sshll2 v1.8h, v0.16b, #0 +; CHECK-FP16-NEXT: sshll v0.8h, v0.8b, #0 +; CHECK-FP16-NEXT: scvtf v1.8h, v1.8h +; CHECK-FP16-NEXT: scvtf v0.8h, v0.8h +; CHECK-FP16-NEXT: ret %1 = sitofp <16 x i8> %a to <16 x half> ret <16 x half> %1 } @@ -391,40 +401,52 @@ define <4 x half> @uitofp_v4i8(<4 x i8> %a) #0 { } define <8 x half> @uitofp_v8i8(<8 x i8> %a) #0 { -; CHECK-LABEL: uitofp_v8i8: -; CHECK-NEXT: ushll v0.8h, v0.8b, #0 -; CHECK-NEXT: ushll2 v1.4s, v0.8h, #0 -; CHECK-NEXT: ushll v0.4s, v0.4h, #0 -; CHECK-NEXT: ucvtf v1.4s, v1.4s -; CHECK-NEXT: ucvtf v0.4s, v0.4s -; CHECK-NEXT: fcvtn v1.4h, v1.4s -; CHECK-NEXT: fcvtn v0.4h, v0.4s -; CHECK-NEXT: mov v0.d[1], v1.d[0] -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: uitofp_v8i8: +; CHECK-CVT-NEXT: ushll v0.8h, v0.8b, #0 +; CHECK-CVT-NEXT: ushll2 v1.4s, v0.8h, #0 +; CHECK-CVT-NEXT: ushll v0.4s, v0.4h, #0 +; CHECK-CVT-NEXT: ucvtf v1.4s, v1.4s +; CHECK-CVT-NEXT: ucvtf v0.4s, v0.4s +; CHECK-CVT-NEXT: fcvtn v1.4h, v1.4s +; CHECK-CVT-NEXT: fcvtn v0.4h, v0.4s +; CHECK-CVT-NEXT: mov v0.d[1], v1.d[0] +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: uitofp_v8i8: +; CHECK-FP16-NEXT: ushll v0.8h, v0.8b, #0 +; CHECK-FP16-NEXT: ucvtf v0.8h, v0.8h +; CHECK-FP16-NEXT: ret ; %1 = uitofp <8 x i8> %a to <8 x half> ret <8 x half> %1 } define <16 x half> @uitofp_v16i8(<16 x i8> %a) #0 { -; CHECK-LABEL: uitofp_v16i8: -; CHECK-NEXT: ushll2 v1.8h, v0.16b, #0 -; CHECK-NEXT: ushll2 v2.4s, v1.8h, #0 -; CHECK-NEXT: ushll v1.4s, v1.4h, #0 -; CHECK-NEXT: ucvtf v2.4s, v2.4s -; CHECK-NEXT: ucvtf v1.4s, v1.4s -; CHECK-NEXT: ushll v0.8h, v0.8b, #0 -; CHECK-NEXT: fcvtn v2.4h, v2.4s -; CHECK-NEXT: fcvtn v1.4h, v1.4s -; CHECK-NEXT: mov v1.d[1], v2.d[0] -; CHECK-NEXT: ushll2 v2.4s, v0.8h, #0 -; CHECK-NEXT: ushll v0.4s, v0.4h, #0 -; CHECK-NEXT: ucvtf v2.4s, v2.4s -; CHECK-NEXT: ucvtf v0.4s, v0.4s -; CHECK-NEXT: fcvtn v2.4h, v2.4s -; CHECK-NEXT: fcvtn v0.4h, v0.4s -; CHECK-NEXT: mov v0.d[1], v2.d[0] -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: uitofp_v16i8: +; CHECK-CVT-NEXT: ushll2 v1.8h, v0.16b, #0 +; CHECK-CVT-NEXT: ushll2 v2.4s, v1.8h, #0 +; CHECK-CVT-NEXT: ushll v1.4s, v1.4h, #0 +; CHECK-CVT-NEXT: ucvtf v2.4s, v2.4s +; CHECK-CVT-NEXT: ucvtf v1.4s, v1.4s +; CHECK-CVT-NEXT: ushll v0.8h, v0.8b, #0 +; CHECK-CVT-NEXT: fcvtn v2.4h, v2.4s +; CHECK-CVT-NEXT: fcvtn v1.4h, v1.4s +; CHECK-CVT-NEXT: mov v1.d[1], v2.d[0] +; CHECK-CVT-NEXT: ushll2 v2.4s, v0.8h, #0 +; CHECK-CVT-NEXT: ushll v0.4s, v0.4h, #0 +; CHECK-CVT-NEXT: ucvtf v2.4s, v2.4s +; CHECK-CVT-NEXT: ucvtf v0.4s, v0.4s +; CHECK-CVT-NEXT: fcvtn v2.4h, v2.4s +; CHECK-CVT-NEXT: fcvtn v0.4h, v0.4s +; CHECK-CVT-NEXT: mov v0.d[1], v2.d[0] +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: uitofp_v16i8: +; CHECK-FP16-NEXT: ushll2 v1.8h, v0.16b, #0 +; CHECK-FP16-NEXT: ushll v0.8h, v0.8b, #0 +; CHECK-FP16-NEXT: ucvtf v1.8h, v1.8h +; CHECK-FP16-NEXT: ucvtf v0.8h, v0.8h +; CHECK-FP16-NEXT: ret ; %1 = uitofp <16 x i8> %a to <16 x half> ret <16 x half> %1 From 74973c3a97fd45e10fcc63775e9bbd2f1f972b7c Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 12 Nov 2021 13:54:19 +0100 Subject: [PATCH 024/293] [lldb] Fix that the embedded Python REPL crashes if it receives SIGINT When LLDB receives a SIGINT while running the embedded Python REPL it currently just crashes in `ScriptInterpreterPythonImpl::Interrupt` with an error such as the one below: ``` Fatal Python error: PyThreadState_Get: the function must be called with the GIL held, but the GIL is released (the current Python thread state is NULL) ``` The faulty code that causes this error is this part of `ScriptInterpreterPythonImpl::Interrupt`: ``` PyThreadState *state = PyThreadState_GET(); if (!state) state = GetThreadState(); if (state) { long tid = state->thread_id; PyThreadState_Swap(state); int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); ``` The obvious fix I tried is to just acquire the GIL before this code is running which fixes the crash but the `KeyboardInterrupt` we want to raise immediately is actually just queued and would only be raised once the next line of input has been parsed (which e.g. won't interrupt Python code that is currently waiting on a timer or IO from what I can see). Also none of the functions we call here is marked as safe to be called from a signal handler from what I can see, so we might still end up crashing here with some bad timing. Python 3.2 introduced `PyErr_SetInterrupt` to solve this and the function takes care of all the details and avoids doing anything that isn't safe to do inside a signal handler. The only thing we need to do is to manually setup our own fake SIGINT handler that behaves the same way as the standalone Python REPL signal handler (which raises a KeyboardInterrupt). From what I understand the old code used to work with Python 2 so I kept the old code around until we officially drop support for Python 2. There is a small gap here with Python 3.0->3.1 where we might still be crashing, but those versions have reached their EOL more than a decade ago so I think we don't need to bother about them. Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D104886 (cherry picked from commit cef1e07cc6d00b5b429d77133201e1f404a8023c) --- .../Python/ScriptInterpreterPython.cpp | 59 +++++++++++++++ .../sigint/TestIOHandlerPythonREPLSigint.py | 73 +++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 7ad63722c31cf..b918706e93c36 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1050,6 +1050,23 @@ void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() { } bool ScriptInterpreterPythonImpl::Interrupt() { + // PyErr_SetInterrupt was introduced in 3.2. +#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3) + // If the interpreter isn't evaluating any Python at the moment then return + // false to signal that this function didn't handle the interrupt and the + // next component should try handling it. + if (!IsExecutingPython()) + return false; + + // Tell Python that it should pretend to have received a SIGINT. + PyErr_SetInterrupt(); + // PyErr_SetInterrupt has no way to return an error so we can only pretend the + // signal got successfully handled and return true. + // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but + // the error handling is limited to checking the arguments which would be + // just our (hardcoded) input signal code SIGINT, so that's not useful at all. + return true; +#else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); if (IsExecutingPython()) { @@ -1071,6 +1088,7 @@ bool ScriptInterpreterPythonImpl::Interrupt() { "ScriptInterpreterPythonImpl::Interrupt() python code not running, " "can't interrupt"); return false; +#endif } bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn( @@ -3276,6 +3294,28 @@ ScriptInterpreterPythonImpl::AcquireInterpreterLock() { return py_lock; } +namespace { +/// Saves the current signal handler for the specified signal and restores +/// it at the end of the current scope. +struct RestoreSignalHandlerScope { + /// The signal handler. + struct sigaction m_prev_handler; + int m_signal_code; + RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) { + // Initialize sigaction to their default state. + std::memset(&m_prev_handler, 0, sizeof(m_prev_handler)); + // Don't install a new handler, just read back the old one. + struct sigaction *new_handler = nullptr; + int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler); + lldbassert(signal_err == 0 && "sigaction failed to read handler"); + } + ~RestoreSignalHandlerScope() { + int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr); + lldbassert(signal_err == 0 && "sigaction failed to restore old handler"); + } +}; +} // namespace + void ScriptInterpreterPythonImpl::InitializePrivate() { if (g_initialized) return; @@ -3311,6 +3351,25 @@ void ScriptInterpreterPythonImpl::InitializePrivate() { "lldb.embedded_interpreter; from " "lldb.embedded_interpreter import run_python_interpreter; " "from lldb.embedded_interpreter import run_one_line"); + +#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3) + // Python will not just overwrite its internal SIGINT handler but also the + // one from the process. Backup the current SIGINT handler to prevent that + // Python deletes it. + RestoreSignalHandlerScope save_sigint(SIGINT); + + // Setup a default SIGINT signal handler that works the same way as the + // normal Python REPL signal handler which raises a KeyboardInterrupt. + // Also make sure to not pollute the user's REPL with the signal module nor + // our utility function. + PyRun_SimpleString("def lldb_setup_sigint_handler():\n" + " import signal;\n" + " def signal_handler(sig, frame):\n" + " raise KeyboardInterrupt()\n" + " signal.signal(signal.SIGINT, signal_handler);\n" + "lldb_setup_sigint_handler();\n" + "del lldb_setup_sigint_handler\n"); +#endif } void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location, diff --git a/lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py b/lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py new file mode 100644 index 0000000000000..7b01919d39526 --- /dev/null +++ b/lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py @@ -0,0 +1,73 @@ +""" +Test sending SIGINT to the embedded Python REPL. +""" + +import os + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbpexpect import PExpectTest + +class TestCase(PExpectTest): + + mydir = TestBase.compute_mydir(__file__) + + def start_python_repl(self): + """ Starts up the embedded Python REPL.""" + self.launch() + # Start the embedded Python REPL via the 'script' command. + self.child.send("script -l python --\n") + # Wait for the Python REPL prompt. + self.child.expect(">>>") + + # PExpect uses many timeouts internally and doesn't play well + # under ASAN on a loaded machine.. + @skipIfAsan + def test_while_evaluating_code(self): + """ Tests SIGINT handling while Python code is being evaluated.""" + self.start_python_repl() + + # Start a long-running command that we try to abort with SIGINT. + # Note that we dont actually wait 10000s in this code as pexpect or + # lit will kill the test way before that. + self.child.send("import time; print('running' + 'now'); time.sleep(10000);\n") + + # Make sure the command is actually being evaluated at the moment by + # looking at the string that the command is printing. + # Don't check for a needle that also occurs in the program itself to + # prevent that echoing will make this check pass unintentionally. + self.child.expect("runningnow") + + # Send SIGINT to the LLDB process. + self.child.sendintr() + + # This should get transformed to a KeyboardInterrupt which is the same + # behaviour as the standalone Python REPL. It should also interrupt + # the evaluation of our sleep statement. + self.child.expect("KeyboardInterrupt") + # Send EOF to quit the Python REPL. + self.child.sendeof() + + self.quit() + + # PExpect uses many timeouts internally and doesn't play well + # under ASAN on a loaded machine.. + @skipIfAsan + # FIXME: On Linux the Python code that reads from stdin seems to block until + # it has finished reading a line before handling any queued signals. + @skipIfLinux + def test_while_waiting_on_input(self): + """ Tests SIGINT handling while the REPL is waiting on input from + stdin.""" + self.start_python_repl() + + # Send SIGINT to the LLDB process. + self.child.sendintr() + # This should get transformed to a KeyboardInterrupt which is the same + # behaviour as the standalone Python REPL. + self.child.expect("KeyboardInterrupt") + # Send EOF to quit the Python REPL. + self.child.sendeof() + + self.quit() From 55a9501651a0197d4666f5609e4b631b3b65ff95 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Sat, 13 Nov 2021 10:13:38 -0800 Subject: [PATCH 025/293] reland: [VFS] Use original path when falling back to external FS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit f0cf544d6f6fe6cbca4c07772998272d6bb433d8. Just a small change to fix: ``` /home/buildbot/as-builder-4/llvm-clang-x86_64-expensive-checks-ubuntu/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp: In static member function ‘static llvm::ErrorOr > llvm::vfs::File::getWithPath(llvm::ErrorOr >, const llvm::Twine&)’: /home/buildbot/as-builder-4/llvm-clang-x86_64-expensive-checks-ubuntu/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp:2084:10: error: could not convert ‘F’ from ‘std::unique_ptr’ to ‘llvm::ErrorOr >’ return F; ^ ``` Differential Revision: https://reviews.llvm.org/D113832 (cherry picked from commit 86e2af8043c7728710a711b623f27425801a36c3) --- clang/test/VFS/relative-path-errors.c | 11 ++ llvm/include/llvm/Support/VirtualFileSystem.h | 17 ++- llvm/lib/Support/VirtualFileSystem.cpp | 107 ++++++++++++----- .../Support/VirtualFileSystemTest.cpp | 108 ++++++++++++++++++ 4 files changed, 215 insertions(+), 28 deletions(-) create mode 100644 clang/test/VFS/relative-path-errors.c diff --git a/clang/test/VFS/relative-path-errors.c b/clang/test/VFS/relative-path-errors.c new file mode 100644 index 0000000000000..8d3773a5eb592 --- /dev/null +++ b/clang/test/VFS/relative-path-errors.c @@ -0,0 +1,11 @@ +// RUN: mkdir -p %t +// RUN: cd %t +// RUN: cp %s main.c +// RUN: not %clang_cc1 main.c 2>&1 | FileCheck %s +// RUN: echo '{"roots": [],"version": 0}' > %t.yaml +// RUN: not %clang_cc1 -ivfsoverlay %t.yaml main.c 2>&1 | FileCheck %s +// RUN: echo '{"version": 0,"roots":[{"type":"directory","name":"%/t","contents":[{"type":"file","name":"vfsname", "external-contents":"main.c"}]}]}' > %t.yaml +// RUN: not %clang_cc1 -ivfsoverlay %t.yaml vfsname 2>&1 | FileCheck %s + +// CHECK: {{^}}main.c:[[# @LINE + 1]]:1: error: +foobarbaz diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h index 323e6719645d9..04576f7b0196e 100644 --- a/llvm/include/llvm/Support/VirtualFileSystem.h +++ b/llvm/include/llvm/Support/VirtualFileSystem.h @@ -121,6 +121,14 @@ class File { /// Closes the file. virtual std::error_code close() = 0; + + // Get the same file with a different path. + static ErrorOr> + getWithPath(ErrorOr> Result, const Twine &P); + +protected: + // Set the file's underlying path. + virtual void setPath(const Twine &Path) {} }; /// A member of a directory, yielded by a directory_iterator. @@ -746,6 +754,12 @@ class RedirectingFileSystem : public vfs::FileSystem { /// with the given error code on a path associated with the provided Entry. bool shouldFallBackToExternalFS(std::error_code EC, Entry *E = nullptr) const; + /// Get the File status, or error, from the underlying external file system. + /// This returns the status with the originally requested name, while looking + /// up the entry using the canonical path. + ErrorOr getExternalStatus(const Twine &CanonicalPath, + const Twine &OriginalPath) const; + // In a RedirectingFileSystem, keys can be specified in Posix or Windows // style (or even a mixture of both), so this comparison helper allows // slashes (representing a root) to match backslashes (and vice versa). Note @@ -808,7 +822,8 @@ class RedirectingFileSystem : public vfs::FileSystem { Entry *From) const; /// Get the status for a path with the provided \c LookupResult. - ErrorOr status(const Twine &Path, const LookupResult &Result); + ErrorOr status(const Twine &CanonicalPath, const Twine &OriginalPath, + const LookupResult &Result); public: /// Looks up \p Path in \c Roots and returns a LookupResult giving the diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index 15bb54e618173..792ff3a8df91e 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -193,6 +193,7 @@ class RealFile : public File { bool RequiresNullTerminator, bool IsVolatile) override; std::error_code close() override; + void setPath(const Twine &Path) override; }; } // namespace @@ -228,6 +229,12 @@ std::error_code RealFile::close() { return EC; } +void RealFile::setPath(const Twine &Path) { + RealName = Path.str(); + if (auto Status = status()) + S = Status.get().copyWithNewName(Status.get(), Path); +} + namespace { /// A file system according to your operating system. @@ -638,6 +645,8 @@ class InMemoryFileAdaptor : public File { } std::error_code close() override { return {}; } + + void setPath(const Twine &Path) override { RequestedName = Path.str(); } }; } // namespace @@ -1207,7 +1216,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir, } // Use status to make sure the path exists and refers to a directory. - ErrorOr S = status(Path, *Result); + ErrorOr S = status(Path, Dir, *Result); if (!S) { if (shouldFallBackToExternalFS(S.getError(), Result->E)) return ExternalFS->dir_begin(Dir, EC); @@ -1933,47 +1942,68 @@ RedirectingFileSystem::lookupPathImpl( return make_error_code(llvm::errc::no_such_file_or_directory); } -static Status getRedirectedFileStatus(const Twine &Path, bool UseExternalNames, +static Status getRedirectedFileStatus(const Twine &OriginalPath, + bool UseExternalNames, Status ExternalStatus) { Status S = ExternalStatus; if (!UseExternalNames) - S = Status::copyWithNewName(S, Path); + S = Status::copyWithNewName(S, OriginalPath); S.IsVFSMapped = true; return S; } ErrorOr RedirectingFileSystem::status( - const Twine &Path, const RedirectingFileSystem::LookupResult &Result) { + const Twine &CanonicalPath, const Twine &OriginalPath, + const RedirectingFileSystem::LookupResult &Result) { if (Optional ExtRedirect = Result.getExternalRedirect()) { - ErrorOr S = ExternalFS->status(*ExtRedirect); + SmallString<256> CanonicalRemappedPath((*ExtRedirect).str()); + if (std::error_code EC = makeCanonical(CanonicalRemappedPath)) + return EC; + + ErrorOr S = ExternalFS->status(CanonicalRemappedPath); if (!S) return S; + S = Status::copyWithNewName(*S, *ExtRedirect); auto *RE = cast(Result.E); - return getRedirectedFileStatus(Path, RE->useExternalName(UseExternalNames), - *S); + return getRedirectedFileStatus(OriginalPath, + RE->useExternalName(UseExternalNames), *S); } auto *DE = cast(Result.E); - return Status::copyWithNewName(DE->getStatus(), Path); + return Status::copyWithNewName(DE->getStatus(), CanonicalPath); } -ErrorOr RedirectingFileSystem::status(const Twine &Path_) { - SmallString<256> Path; - Path_.toVector(Path); +ErrorOr +RedirectingFileSystem::getExternalStatus(const Twine &CanonicalPath, + const Twine &OriginalPath) const { + if (auto Result = ExternalFS->status(CanonicalPath)) { + return Result.get().copyWithNewName(Result.get(), OriginalPath); + } else { + return Result.getError(); + } +} - if (std::error_code EC = makeCanonical(Path)) +ErrorOr RedirectingFileSystem::status(const Twine &OriginalPath) { + SmallString<256> CanonicalPath; + OriginalPath.toVector(CanonicalPath); + + if (std::error_code EC = makeCanonical(CanonicalPath)) return EC; - ErrorOr Result = lookupPath(Path); + ErrorOr Result = + lookupPath(CanonicalPath); if (!Result) { - if (shouldFallBackToExternalFS(Result.getError())) - return ExternalFS->status(Path); + if (shouldFallBackToExternalFS(Result.getError())) { + return getExternalStatus(CanonicalPath, OriginalPath); + } return Result.getError(); } - ErrorOr S = status(Path, *Result); - if (!S && shouldFallBackToExternalFS(S.getError(), Result->E)) - S = ExternalFS->status(Path); + ErrorOr S = status(CanonicalPath, OriginalPath, *Result); + if (!S && shouldFallBackToExternalFS(S.getError(), Result->E)) { + return getExternalStatus(CanonicalPath, OriginalPath); + } + return S; } @@ -1998,22 +2028,39 @@ class FileWithFixedStatus : public File { } std::error_code close() override { return InnerFile->close(); } + + void setPath(const Twine &Path) override { S = S.copyWithNewName(S, Path); } }; } // namespace ErrorOr> -RedirectingFileSystem::openFileForRead(const Twine &Path_) { - SmallString<256> Path; - Path_.toVector(Path); +File::getWithPath(ErrorOr> Result, const Twine &P) { + if (!Result) + return Result; - if (std::error_code EC = makeCanonical(Path)) + ErrorOr> F = std::move(*Result); + auto Name = F->get()->getName(); + if (Name && Name.get() != P.str()) + F->get()->setPath(P); + return F; +} + +ErrorOr> +RedirectingFileSystem::openFileForRead(const Twine &OriginalPath) { + SmallString<256> CanonicalPath; + OriginalPath.toVector(CanonicalPath); + + if (std::error_code EC = makeCanonical(CanonicalPath)) return EC; - ErrorOr Result = lookupPath(Path); + ErrorOr Result = + lookupPath(CanonicalPath); if (!Result) { if (shouldFallBackToExternalFS(Result.getError())) - return ExternalFS->openFileForRead(Path); + return File::getWithPath(ExternalFS->openFileForRead(CanonicalPath), + OriginalPath); + return Result.getError(); } @@ -2021,12 +2068,18 @@ RedirectingFileSystem::openFileForRead(const Twine &Path_) { return make_error_code(llvm::errc::invalid_argument); StringRef ExtRedirect = *Result->getExternalRedirect(); + SmallString<256> CanonicalRemappedPath(ExtRedirect.str()); + if (std::error_code EC = makeCanonical(CanonicalRemappedPath)) + return EC; + auto *RE = cast(Result->E); - auto ExternalFile = ExternalFS->openFileForRead(ExtRedirect); + auto ExternalFile = File::getWithPath( + ExternalFS->openFileForRead(CanonicalRemappedPath), ExtRedirect); if (!ExternalFile) { if (shouldFallBackToExternalFS(ExternalFile.getError(), Result->E)) - return ExternalFS->openFileForRead(Path); + return File::getWithPath(ExternalFS->openFileForRead(CanonicalPath), + OriginalPath); return ExternalFile; } @@ -2036,7 +2089,7 @@ RedirectingFileSystem::openFileForRead(const Twine &Path_) { // FIXME: Update the status with the name and VFSMapped. Status S = getRedirectedFileStatus( - Path, RE->useExternalName(UseExternalNames), *ExternalStatus); + OriginalPath, RE->useExternalName(UseExternalNames), *ExternalStatus); return std::unique_ptr( std::make_unique(std::move(*ExternalFile), S)); } diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp index 6aa2189374857..b06b41b5cde8f 100644 --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -1607,6 +1607,114 @@ TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlayNoFallthrough) { EXPECT_EQ(0, NumDiagnostics); } +TEST_F(VFSFromYAMLTest, ReturnsRequestedPathVFSMiss) { + IntrusiveRefCntPtr BaseFS( + new vfs::InMemoryFileSystem); + BaseFS->addFile("//root/foo/a", 0, + MemoryBuffer::getMemBuffer("contents of a")); + ASSERT_FALSE(BaseFS->setCurrentWorkingDirectory("//root/foo")); + auto RemappedFS = vfs::RedirectingFileSystem::create( + {}, /*UseExternalNames=*/false, *BaseFS); + + auto OpenedF = RemappedFS->openFileForRead("a"); + ASSERT_FALSE(OpenedF.getError()); + llvm::ErrorOr Name = (*OpenedF)->getName(); + ASSERT_FALSE(Name.getError()); + EXPECT_EQ("a", Name.get()); + + auto OpenedS = (*OpenedF)->status(); + ASSERT_FALSE(OpenedS.getError()); + EXPECT_EQ("a", OpenedS->getName()); + EXPECT_FALSE(OpenedS->IsVFSMapped); + + auto DirectS = RemappedFS->status("a"); + ASSERT_FALSE(DirectS.getError()); + EXPECT_EQ("a", DirectS->getName()); + EXPECT_FALSE(DirectS->IsVFSMapped); + + EXPECT_EQ(0, NumDiagnostics); +} + +TEST_F(VFSFromYAMLTest, ReturnsExternalPathVFSHit) { + IntrusiveRefCntPtr BaseFS( + new vfs::InMemoryFileSystem); + BaseFS->addFile("//root/foo/realname", 0, + MemoryBuffer::getMemBuffer("contents of a")); + auto FS = + getFromYAMLString("{ 'use-external-names': true,\n" + " 'roots': [\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '//root/foo',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'vfsname',\n" + " 'external-contents': 'realname'\n" + " }\n" + " ]\n" + "}]}", + BaseFS); + ASSERT_FALSE(FS->setCurrentWorkingDirectory("//root/foo")); + + auto OpenedF = FS->openFileForRead("vfsname"); + ASSERT_FALSE(OpenedF.getError()); + llvm::ErrorOr Name = (*OpenedF)->getName(); + ASSERT_FALSE(Name.getError()); + EXPECT_EQ("realname", Name.get()); + + auto OpenedS = (*OpenedF)->status(); + ASSERT_FALSE(OpenedS.getError()); + EXPECT_EQ("realname", OpenedS->getName()); + EXPECT_TRUE(OpenedS->IsVFSMapped); + + auto DirectS = FS->status("vfsname"); + ASSERT_FALSE(DirectS.getError()); + EXPECT_EQ("realname", DirectS->getName()); + EXPECT_TRUE(DirectS->IsVFSMapped); + + EXPECT_EQ(0, NumDiagnostics); +} + +TEST_F(VFSFromYAMLTest, ReturnsInternalPathVFSHit) { + IntrusiveRefCntPtr BaseFS( + new vfs::InMemoryFileSystem); + BaseFS->addFile("//root/foo/realname", 0, + MemoryBuffer::getMemBuffer("contents of a")); + auto FS = + getFromYAMLString("{ 'use-external-names': false,\n" + " 'roots': [\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '//root/foo',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'vfsname',\n" + " 'external-contents': 'realname'\n" + " }\n" + " ]\n" + "}]}", + BaseFS); + ASSERT_FALSE(FS->setCurrentWorkingDirectory("//root/foo")); + + auto OpenedF = FS->openFileForRead("vfsname"); + ASSERT_FALSE(OpenedF.getError()); + llvm::ErrorOr Name = (*OpenedF)->getName(); + ASSERT_FALSE(Name.getError()); + EXPECT_EQ("vfsname", Name.get()); + + auto OpenedS = (*OpenedF)->status(); + ASSERT_FALSE(OpenedS.getError()); + EXPECT_EQ("vfsname", OpenedS->getName()); + EXPECT_TRUE(OpenedS->IsVFSMapped); + + auto DirectS = FS->status("vfsname"); + ASSERT_FALSE(DirectS.getError()); + EXPECT_EQ("vfsname", DirectS->getName()); + EXPECT_TRUE(DirectS->IsVFSMapped); + + EXPECT_EQ(0, NumDiagnostics); +} + TEST_F(VFSFromYAMLTest, CaseInsensitive) { IntrusiveRefCntPtr Lower(new DummyFileSystem()); Lower->addRegularFile("//root/foo/bar/a"); From 3e4b7fda857992534eb3c0fc540445d86aae2aa7 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Wed, 6 Oct 2021 00:09:20 +0000 Subject: [PATCH 026/293] [lldb/Plugins] Add support for ScriptedThread in ScriptedProcess This patch introduces the `ScriptedThread` class with its python interface. When used with `ScriptedProcess`, `ScriptedThreaad` can provide various information such as the thread state, stop reason or even its register context. This can be used to reconstruct the program stack frames using lldb's unwinder. rdar://74503836 Differential Revision: https://reviews.llvm.org/D107585 Signed-off-by: Med Ismail Bennani --- lldb/bindings/python/python-wrapper.swig | 57 +++++ .../scripted_process/my_scripted_process.py | 44 +++- .../scripted_process/scripted_process.py | 160 +++++++++++++ .../lldb/Interpreter/ScriptedInterface.h | 40 ++++ .../Interpreter/ScriptedProcessInterface.h | 39 ++++ lldb/include/lldb/lldb-forward.h | 3 + .../Plugins/Process/scripted/CMakeLists.txt | 1 + .../Process/scripted/ScriptedProcess.cpp | 38 +++- .../Process/scripted/ScriptedProcess.h | 4 + .../Process/scripted/ScriptedThread.cpp | 210 ++++++++++++++++++ .../Plugins/Process/scripted/ScriptedThread.h | 68 ++++++ .../ScriptInterpreter/Python/CMakeLists.txt | 1 + .../Python/SWIGPythonBridge.h | 4 + .../Python/ScriptedProcessPythonInterface.cpp | 78 +++---- .../Python/ScriptedProcessPythonInterface.h | 5 + .../Python/ScriptedPythonInterface.cpp | 8 + .../Python/ScriptedPythonInterface.h | 34 +-- .../Python/ScriptedThreadPythonInterface.cpp | 136 ++++++++++++ .../Python/ScriptedThreadPythonInterface.h | 48 ++++ .../scripted_process/TestScriptedProcess.py | 22 ++ .../Python/PythonTestSuite.cpp | 6 + 21 files changed, 932 insertions(+), 74 deletions(-) create mode 100644 lldb/source/Plugins/Process/scripted/ScriptedThread.cpp create mode 100644 lldb/source/Plugins/Process/scripted/ScriptedThread.h create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp create mode 100644 lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index a148ec3544ab8..feb4e54240bc1 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -340,6 +340,63 @@ LLDBSwigPythonCreateScriptedProcess Py_RETURN_NONE; } +SWIGEXPORT void* +LLDBSwigPythonCreateScriptedThread +( + const char *python_class_name, + const char *session_dictionary_name, + const lldb::TargetSP& target_sp, + std::string &error_string +) +{ + if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) + Py_RETURN_NONE; + + PyErr_Cleaner py_err_cleaner(true); + + auto dict = PythonModule::MainModule().ResolveName(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary(python_class_name, dict); + + if (!pfunc.IsAllocated()) { + error_string.append("could not find script class: "); + error_string.append(python_class_name); + return nullptr; + } + + // I do not want the SBTarget to be deallocated when going out of scope + // because python has ownership of it and will manage memory for this + // object by itself + PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBTarget(target_sp))); + + if (!target_arg.IsAllocated()) + Py_RETURN_NONE; + + llvm::Expected arg_info = pfunc.GetArgInfo(); + if (!arg_info) { + llvm::handleAllErrors( + arg_info.takeError(), + [&](PythonException &E) { + error_string.append(E.ReadBacktrace()); + }, + [&](const llvm::ErrorInfoBase &E) { + error_string.append(E.message()); + }); + Py_RETURN_NONE; + } + + PythonObject result = {}; + if (arg_info.get().max_positional_args == 1) { + result = pfunc(target_arg); + } else { + error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); + Py_RETURN_NONE; + } + + if (result.IsAllocated()) + return result.release(); + Py_RETURN_NONE; +} + SWIGEXPORT void* LLDBSwigPythonCreateScriptedThreadPlan ( diff --git a/lldb/examples/python/scripted_process/my_scripted_process.py b/lldb/examples/python/scripted_process/my_scripted_process.py index 429531e80e1e0..9257cd9c85126 100644 --- a/lldb/examples/python/scripted_process/my_scripted_process.py +++ b/lldb/examples/python/scripted_process/my_scripted_process.py @@ -1,7 +1,10 @@ -import os +import os,struct,signal + +from typing import Any, Dict import lldb from lldb.plugins.scripted_process import ScriptedProcess +from lldb.plugins.scripted_process import ScriptedThread class MyScriptedProcess(ScriptedProcess): def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData): @@ -35,6 +38,45 @@ def should_stop(self) -> bool: def is_alive(self) -> bool: return True + def get_scripted_thread_plugin(self): + return MyScriptedThread.__module__ + "." + MyScriptedThread.__name__ + + +class MyScriptedThread(ScriptedThread): + def __init__(self, target): + super().__init__(target) + + def get_thread_id(self) -> int: + return 0x19 + + def get_name(self) -> str: + return MyScriptedThread.__name__ + ".thread-1" + + def get_stop_reason(self) -> Dict[str, Any]: + return { "type": lldb.eStopReasonSignal, "data": { + "signal": signal.SIGINT + } } + + def get_stackframes(self): + class ScriptedStackFrame: + def __init__(idx, cfa, pc, symbol_ctx): + self.idx = idx + self.cfa = cfa + self.pc = pc + self.symbol_ctx = symbol_ctx + + + symbol_ctx = lldb.SBSymbolContext() + frame_zero = ScriptedStackFrame(0, 0x42424242, 0x5000000, symbol_ctx) + self.frames.append(frame_zero) + + return self.frame_zero[0:0] + + def get_register_context(self) -> str: + return struct.pack( + '21Q', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + + def __lldb_init_module(debugger, dict): if not 'SKIP_SCRIPTED_PROCESS_LAUNCH' in os.environ: debugger.HandleCommand( diff --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/scripted_process/scripted_process.py index 72dce5c1e3bb0..d3474fbcf0a08 100644 --- a/lldb/examples/python/scripted_process/scripted_process.py +++ b/lldb/examples/python/scripted_process/scripted_process.py @@ -163,3 +163,163 @@ def is_alive(self): bool: True if scripted process is alive. False otherwise. """ pass + + @abstractmethod + def get_scripted_thread_plugin(self): + """ Get scripted thread plugin name. + + Returns: + str: Name of the scripted thread plugin. + """ + return None + +@six.add_metaclass(ABCMeta) +class ScriptedThread: + + """ + The base class for a scripted thread. + + Most of the base class methods are `@abstractmethod` that need to be + overwritten by the inheriting class. + + DISCLAIMER: THIS INTERFACE IS STILL UNDER DEVELOPMENT AND NOT STABLE. + THE METHODS EXPOSED MIGHT CHANGE IN THE FUTURE. + """ + + @abstractmethod + def __init__(self, target): + """ Construct a scripted thread. + + Args: + target (lldb.SBTarget): The target launching the scripted process. + args (lldb.SBStructuredData): A Dictionary holding arbitrary + key/value pairs used by the scripted process. + """ + self.target = None + self.args = None + if isinstance(target, lldb.SBTarget) and target.IsValid(): + self.target = target + + self.id = None + self.name = None + self.queue = None + self.state = None + self.stop_reason = None + self.register_info = None + self.register_ctx = [] + self.frames = [] + + @abstractmethod + def get_thread_id(self): + """ Get the scripted thread identifier. + + Returns: + int: The identifier of the scripted thread. + """ + pass + + @abstractmethod + def get_name(self): + """ Get the scripted thread name. + + Returns: + str: The name of the scripted thread. + """ + pass + + def get_state(self): + """ Get the scripted thread state type. + + eStateStopped, ///< Process or thread is stopped and can be examined. + eStateRunning, ///< Process or thread is running and can't be examined. + eStateStepping, ///< Process or thread is in the process of stepping and can + /// not be examined. + + Returns: + int: The state type of the scripted thread. + Returns lldb.eStateStopped by default. + """ + return lldb.eStateStopped + + def get_queue(self): + """ Get the scripted thread associated queue name. + This method is optional. + + Returns: + str: The queue name associated with the scripted thread. + """ + pass + + @abstractmethod + def get_stop_reason(self): + """ Get the dictionary describing the stop reason type with some data. + This method is optional. + + Returns: + Dict: The dictionary holding the stop reason type and the possibly + the stop reason data. + """ + pass + + def get_stackframes(self): + """ Get the list of stack frames for the scripted thread. + + ``` + class ScriptedStackFrame: + def __init__(idx, cfa, pc, symbol_ctx): + self.idx = idx + self.cfa = cfa + self.pc = pc + self.symbol_ctx = symbol_ctx + ``` + + Returns: + List[ScriptedFrame]: A list of `ScriptedStackFrame` + containing for each entry, the frame index, the canonical + frame address, the program counter value for that frame + and a symbol context. + None if the list is empty. + """ + return 0 + + def get_register_info(self): + if self.register_info is None: + self.register_info = dict() + triple = self.target.triple + if triple: + arch = triple.split('-')[0] + if arch == 'x86_64': + self.register_info['sets'] = ['GPR', 'FPU', 'EXC'] + self.register_info['registers'] = [ + {'name': 'rax', 'bitsize': 64, 'offset': 0, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0, 'dwarf': 0}, + {'name': 'rbx', 'bitsize': 64, 'offset': 8, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 3, 'dwarf': 3}, + {'name': 'rcx', 'bitsize': 64, 'offset': 16, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 2, 'dwarf': 2, 'generic': 'arg4', 'alt-name': 'arg4', }, + {'name': 'rdx', 'bitsize': 64, 'offset': 24, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 1, 'dwarf': 1, 'generic': 'arg3', 'alt-name': 'arg3', }, + {'name': 'rdi', 'bitsize': 64, 'offset': 32, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 5, 'dwarf': 5, 'generic': 'arg1', 'alt-name': 'arg1', }, + {'name': 'rsi', 'bitsize': 64, 'offset': 40, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 4, 'dwarf': 4, 'generic': 'arg2', 'alt-name': 'arg2', }, + {'name': 'rbp', 'bitsize': 64, 'offset': 48, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 6, 'dwarf': 6, 'generic': 'fp', 'alt-name': 'fp', }, + {'name': 'rsp', 'bitsize': 64, 'offset': 56, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 7, 'dwarf': 7, 'generic': 'sp', 'alt-name': 'sp', }, + {'name': 'r8', 'bitsize': 64, 'offset': 64, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 8, 'dwarf': 8, 'generic': 'arg5', 'alt-name': 'arg5', }, + {'name': 'r9', 'bitsize': 64, 'offset': 72, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 9, 'dwarf': 9, 'generic': 'arg6', 'alt-name': 'arg6', }, + {'name': 'r10', 'bitsize': 64, 'offset': 80, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 10, 'dwarf': 10}, + {'name': 'r11', 'bitsize': 64, 'offset': 88, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 11, 'dwarf': 11}, + {'name': 'r12', 'bitsize': 64, 'offset': 96, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 12, 'dwarf': 12}, + {'name': 'r13', 'bitsize': 64, 'offset': 104, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 13, 'dwarf': 13}, + {'name': 'r14', 'bitsize': 64, 'offset': 112, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 14, 'dwarf': 14}, + {'name': 'r15', 'bitsize': 64, 'offset': 120, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 15, 'dwarf': 15}, + {'name': 'rip', 'bitsize': 64, 'offset': 128, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 16, 'dwarf': 16, 'generic': 'pc', 'alt-name': 'pc'}, + {'name': 'rflags', 'bitsize': 64, 'offset': 136, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'generic': 'flags', 'alt-name': 'flags'}, + {'name': 'cs', 'bitsize': 64, 'offset': 144, 'encoding': 'uint', 'format': 'hex', 'set': 0}, + {'name': 'fs', 'bitsize': 64, 'offset': 152, 'encoding': 'uint', 'format': 'hex', 'set': 0}, + {'name': 'gs', 'bitsize': 64, 'offset': 160, 'encoding': 'uint', 'format': 'hex', 'set': 0}, + ] + return self.register_info + + @abstractmethod + def get_register_context(self): + """ Get the scripted thread register context + + Returns: + str: A byte representing all register's value. + """ + pass diff --git a/lldb/include/lldb/Interpreter/ScriptedInterface.h b/lldb/include/lldb/Interpreter/ScriptedInterface.h index 7cd0c6a1a7772..38164739bab57 100644 --- a/lldb/include/lldb/Interpreter/ScriptedInterface.h +++ b/lldb/include/lldb/Interpreter/ScriptedInterface.h @@ -11,6 +11,8 @@ #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" #include "lldb/lldb-private.h" #include @@ -25,6 +27,44 @@ class ScriptedInterface { CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp) = 0; + template + Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, + Status &error, + uint32_t log_caterogy = LIBLLDB_LOG_PROCESS) { + LLDB_LOGF(GetLogIfAllCategoriesSet(log_caterogy), "%s ERROR = %s", + caller_name.data(), error_msg.data()); + error.SetErrorString(llvm::Twine(caller_name + llvm::Twine(" ERROR = ") + + llvm::Twine(error_msg)) + .str()); + return {}; + } + + template + bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) { + if (!obj) { + return ErrorWithMessage(caller, + llvm::Twine("Null StructuredData object (" + + llvm::Twine(error.AsCString()) + + llvm::Twine(").")) + .str(), + error); + } + + if (!obj->IsValid()) { + return ErrorWithMessage( + caller, + llvm::Twine("Invalid StructuredData object (" + + llvm::Twine(error.AsCString()) + llvm::Twine(").")) + .str(), + error); + } + + if (error.Fail()) + return ErrorWithMessage(caller, error.AsCString(), error); + + return true; + } + protected: StructuredData::GenericSP m_object_instance_sp; }; diff --git a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h index 9682ba76383b7..31d6e1476a6ed 100644 --- a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h +++ b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -57,6 +57,45 @@ class ScriptedProcessInterface : virtual public ScriptedInterface { virtual lldb::pid_t GetProcessID() { return LLDB_INVALID_PROCESS_ID; } virtual bool IsAlive() { return true; } + + virtual llvm::Optional GetScriptedThreadPluginName() { + return llvm::None; + } + +protected: + friend class ScriptedThread; + virtual lldb::ScriptedThreadInterfaceSP GetScriptedThreadInterface() { + return nullptr; + } + + lldb::ScriptedThreadInterfaceSP m_scripted_thread_interface_sp = nullptr; +}; + +class ScriptedThreadInterface : virtual public ScriptedInterface { +public: + StructuredData::GenericSP + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) override { + return nullptr; + } + + virtual lldb::tid_t GetThreadID() { return LLDB_INVALID_THREAD_ID; } + + virtual llvm::Optional GetName() { return llvm::None; } + + virtual lldb::StateType GetState() { return lldb::eStateInvalid; } + + virtual llvm::Optional GetQueue() { return llvm::None; } + + virtual StructuredData::DictionarySP GetStopReason() { return nullptr; } + + virtual StructuredData::ArraySP GetStackFrames() { return nullptr; } + + virtual StructuredData::DictionarySP GetRegisterInfo() { return nullptr; } + + virtual llvm::Optional GetRegisterContext() { + return llvm::None; + } }; } // namespace lldb_private diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 2206f575fb08c..3e2d81b53963f 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -175,6 +175,7 @@ class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; class ScriptedProcessInterface; +class ScriptedThreadInterface; class ScriptedSyntheticChildren; class SearchFilter; class Section; @@ -394,6 +395,8 @@ typedef std::shared_ptr ScriptInterpreterSP; typedef std::unique_ptr ScriptInterpreterUP; typedef std::unique_ptr ScriptedProcessInterfaceUP; +typedef std::shared_ptr + ScriptedThreadInterfaceSP; typedef std::shared_ptr SectionSP; typedef std::unique_ptr SectionListUP; typedef std::weak_ptr SectionWP; diff --git a/lldb/source/Plugins/Process/scripted/CMakeLists.txt b/lldb/source/Plugins/Process/scripted/CMakeLists.txt index e2cfd058e2783..600ef31d032eb 100644 --- a/lldb/source/Plugins/Process/scripted/CMakeLists.txt +++ b/lldb/source/Plugins/Process/scripted/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_library(lldbPluginScriptedProcess PLUGIN ScriptedProcess.cpp + ScriptedThread.cpp LINK_LIBS lldbCore diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index 93b8d5f457a49..467872c90938f 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -21,8 +21,6 @@ #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/RegisterContext.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/State.h" #include @@ -236,14 +234,9 @@ bool ScriptedProcess::IsAlive() { size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) { - - auto error_with_message = [&error](llvm::StringRef message) { - error.SetErrorString(message); - return 0; - }; - if (!m_interpreter) - return error_with_message("No interpreter."); + return GetInterface().ErrorWithMessage(__PRETTY_FUNCTION__, + "No interpreter.", error); lldb::DataExtractorSP data_extractor_sp = GetInterface().ReadMemoryAtAddress(addr, size, error); @@ -255,7 +248,8 @@ size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder()); if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET) - return error_with_message("Failed to copy read memory to buffer."); + return GetInterface().ErrorWithMessage( + __PRETTY_FUNCTION__, "Failed to copy read memory to buffer.", error); return size; } @@ -294,6 +288,30 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, // This is supposed to get the current set of threads, if any of them are in // old_thread_list then they get copied to new_thread_list, and then any // actually new threads will get added to new_thread_list. + + CheckInterpreterAndScriptObject(); + + Status error; + ScriptLanguage language = m_interpreter->GetLanguage(); + + if (language != eScriptLanguagePython) + return GetInterface().ErrorWithMessage( + __PRETTY_FUNCTION__, + llvm::Twine("ScriptInterpreter language (" + + llvm::Twine(m_interpreter->LanguageToString(language)) + + llvm::Twine(") not supported.")) + .str(), + error); + + lldb::ThreadSP thread_sp; + thread_sp = std::make_shared(*this, error); + + if (!thread_sp || error.Fail()) + return GetInterface().ErrorWithMessage(__PRETTY_FUNCTION__, + error.AsCString(), error); + + new_thread_list.AddThread(thread_sp); + return new_thread_list.GetSize(false) > 0; } diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h index 98c1a1ca4fe9f..f527244746322 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -13,6 +13,8 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" +#include "ScriptedThread.h" + #include namespace lldb_private { @@ -103,6 +105,8 @@ class ScriptedProcess : public Process { ThreadList &new_thread_list) override; private: + friend class ScriptedThread; + void CheckInterpreterAndScriptObject() const; ScriptedProcessInterface &GetInterface() const; static bool IsScriptLanguageSupported(lldb::ScriptLanguage language); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp new file mode 100644 index 0000000000000..11db89bfc3977 --- /dev/null +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -0,0 +1,210 @@ +//===-- ScriptedThread.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ScriptedThread.h" + +#include "Plugins/Process/Utility/RegisterContextThreadMemory.h" +#include "lldb/Target/OperatingSystem.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Unwind.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +void ScriptedThread::CheckInterpreterAndScriptObject() const { + lldbassert(m_script_object_sp && "Invalid Script Object."); + lldbassert(GetInterface() && "Invalid Scripted Thread Interface."); +} + +ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error) + : Thread(process, LLDB_INVALID_THREAD_ID), m_scripted_process(process) { + if (!process.IsValid()) { + error.SetErrorString("Invalid scripted process"); + return; + } + + process.CheckInterpreterAndScriptObject(); + + auto scripted_thread_interface = GetInterface(); + if (!scripted_thread_interface) { + error.SetErrorString("Failed to get scripted thread interface."); + return; + } + + llvm::Optional class_name = + process.GetInterface().GetScriptedThreadPluginName(); + if (!class_name || class_name->empty()) { + error.SetErrorString("Failed to get scripted thread class name."); + return; + } + + ExecutionContext exe_ctx(process); + + StructuredData::GenericSP object_sp = + scripted_thread_interface->CreatePluginObject( + class_name->c_str(), exe_ctx, + process.m_scripted_process_info.GetDictionarySP()); + if (!object_sp || !object_sp->IsValid()) { + error.SetErrorString("Failed to create valid script object"); + return; + } + + m_script_object_sp = object_sp; + + SetID(scripted_thread_interface->GetThreadID()); + + llvm::Optional reg_data = + scripted_thread_interface->GetRegisterContext(); + if (!reg_data) { + error.SetErrorString("Failed to get scripted thread registers data."); + return; + } + + DataBufferSP data_sp( + std::make_shared(reg_data->c_str(), reg_data->size())); + + if (!data_sp->GetByteSize()) { + error.SetErrorString("Failed to copy raw registers data."); + return; + } + + std::shared_ptr reg_ctx_memory = + std::make_shared( + *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); + if (!reg_ctx_memory) { + error.SetErrorString("Failed to create a register context."); + return; + } + + reg_ctx_memory->SetAllRegisterData(data_sp); + m_reg_context_sp = reg_ctx_memory; +} + +ScriptedThread::~ScriptedThread() { DestroyThread(); } + +const char *ScriptedThread::GetName() { + CheckInterpreterAndScriptObject(); + llvm::Optional thread_name = GetInterface()->GetName(); + if (!thread_name) + return nullptr; + return ConstString(thread_name->c_str()).AsCString(); +} + +const char *ScriptedThread::GetQueueName() { + CheckInterpreterAndScriptObject(); + llvm::Optional queue_name = GetInterface()->GetQueue(); + if (!queue_name) + return nullptr; + return ConstString(queue_name->c_str()).AsCString(); +} + +void ScriptedThread::WillResume(StateType resume_state) {} + +void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); } + +RegisterContextSP ScriptedThread::GetRegisterContext() { + if (!m_reg_context_sp) { + m_reg_context_sp = std::make_shared( + *this, LLDB_INVALID_ADDRESS); + GetInterface()->GetRegisterContext(); + } + return m_reg_context_sp; +} + +RegisterContextSP +ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { + uint32_t concrete_frame_idx = frame ? frame->GetConcreteFrameIndex() : 0; + + if (concrete_frame_idx == 0) + return GetRegisterContext(); + return GetUnwinder().CreateRegisterContextForFrame(frame); +} + +bool ScriptedThread::CalculateStopInfo() { + StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason(); + + Status error; + lldb::StopInfoSP stop_info_sp; + lldb::StopReason stop_reason_type; + + if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type)) + return GetInterface()->ErrorWithMessage( + __PRETTY_FUNCTION__, + "Couldn't find value for key 'type' in stop reason dictionary.", error); + + StructuredData::Dictionary *data_dict; + if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict)) + return GetInterface()->ErrorWithMessage( + __PRETTY_FUNCTION__, + "Couldn't find value for key 'type' in stop reason dictionary.", error); + + switch (stop_reason_type) { + case lldb::eStopReasonNone: + break; + case lldb::eStopReasonBreakpoint: { + lldb::break_id_t break_id; + data_dict->GetValueForKeyAsInteger("break_id", break_id, + LLDB_INVALID_BREAK_ID); + stop_info_sp = + StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id); + } break; + case lldb::eStopReasonSignal: { + int signal; + llvm::StringRef description; + data_dict->GetValueForKeyAsInteger("signal", signal, + LLDB_INVALID_SIGNAL_NUMBER); + data_dict->GetValueForKeyAsString("desc", description); + stop_info_sp = + StopInfo::CreateStopReasonWithSignal(*this, signal, description.data()); + } break; + default: + return GetInterface()->ErrorWithMessage( + __PRETTY_FUNCTION__, + llvm::Twine("Unsupported stop reason type (" + + llvm::Twine(stop_reason_type) + llvm::Twine(").")) + .str(), + error); + } + + SetStopInfo(stop_info_sp); + return true; +} + +void ScriptedThread::RefreshStateAfterStop() { + // TODO: Implement + if (m_reg_context_sp) + m_reg_context_sp->InvalidateAllRegisters(); +} + +lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const { + return m_scripted_process.GetInterface().GetScriptedThreadInterface(); +} + +std::shared_ptr ScriptedThread::GetDynamicRegisterInfo() { + CheckInterpreterAndScriptObject(); + + if (!m_register_info_sp) { + StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo(); + if (!reg_info) + return nullptr; + + m_register_info_sp = std::make_shared( + *reg_info, m_scripted_process.GetTarget().GetArchitecture()); + assert(m_register_info_sp->GetNumRegisters() > 0); + assert(m_register_info_sp->GetNumRegisterSets() > 0); + } + + return m_register_info_sp; +} diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/lldb/source/Plugins/Process/scripted/ScriptedThread.h new file mode 100644 index 0000000000000..cdcd543702a48 --- /dev/null +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -0,0 +1,68 @@ +//===-- ScriptedThread.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SCRIPTED_THREAD_H +#define LLDB_SOURCE_PLUGINS_SCRIPTED_THREAD_H + +#include + +#include "ScriptedProcess.h" + +#include "Plugins/Process/Utility/RegisterContextMemory.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target//DynamicRegisterInfo.h" +#include "lldb/Target/Thread.h" + +namespace lldb_private { +class ScriptedProcess; +} + +namespace lldb_private { + +class ScriptedThread : public lldb_private::Thread { +public: + ScriptedThread(ScriptedProcess &process, Status &error); + + ~ScriptedThread() override; + + lldb::RegisterContextSP GetRegisterContext() override; + + lldb::RegisterContextSP + CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; + + bool CalculateStopInfo() override; + + const char *GetInfo() override { return nullptr; } + + const char *GetName() override; + + const char *GetQueueName() override; + + void WillResume(lldb::StateType resume_state) override; + + void RefreshStateAfterStop() override; + + void ClearStackFrames() override; + +private: + void CheckInterpreterAndScriptObject() const; + lldb::ScriptedThreadInterfaceSP GetInterface() const; + + ScriptedThread(const ScriptedThread &) = delete; + const ScriptedThread &operator=(const ScriptedThread &) = delete; + + std::shared_ptr GetDynamicRegisterInfo(); + + const ScriptedProcess &m_scripted_process; + std::shared_ptr m_register_info_sp = nullptr; + lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_THREAD_H diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt index 98dc552ba6489..f3c20a741c1f4 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt @@ -13,6 +13,7 @@ add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN ScriptInterpreterPython.cpp ScriptedPythonInterface.cpp ScriptedProcessPythonInterface.cpp + ScriptedThreadPythonInterface.cpp SWIGPythonBridge.cpp LINK_LIBS diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 1ef792bcf303b..8d6e7dc4ee789 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -46,6 +46,10 @@ extern "C" void *LLDBSwigPythonCreateScriptedProcess( const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl, std::string &error_string); +extern "C" void *LLDBSwigPythonCreateScriptedThread( + const char *python_class_name, const char *session_dictionary_name, + const lldb::TargetSP &target_sp, std::string &error_string); + extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data); extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data); extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data); diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp index 7cc74803bd613..32be169f0d1de 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -19,6 +19,7 @@ #include "SWIGPythonBridge.h" #include "ScriptInterpreterPythonImpl.h" #include "ScriptedProcessPythonInterface.h" +#include "ScriptedThreadPythonInterface.h" using namespace lldb; using namespace lldb_private; @@ -71,18 +72,8 @@ bool ScriptedProcessPythonInterface::ShouldStop() { Status error; StructuredData::ObjectSP obj = Dispatch("is_alive", error); - auto error_with_message = [](llvm::StringRef message) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), - "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); - return false; - }; - - if (!obj || !obj->IsValid() || error.Fail()) { - return error_with_message(llvm::Twine("Null or invalid object (" + - llvm::Twine(error.AsCString()) + - llvm::Twine(").")) - .str()); - } + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; return obj->GetBooleanValue(); } @@ -100,24 +91,11 @@ ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { - Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); - - auto error_with_message = [](llvm::StringRef message) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), - "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); - return StructuredData::DictionarySP(); - }; - Status error; StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid); - if (!obj || !obj->IsValid() || error.Fail()) { - return error_with_message(llvm::Twine("Null or invalid object (" + - llvm::Twine(error.AsCString()) + - llvm::Twine(").")) - .str()); - } + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; StructuredData::DictionarySP dict{obj->GetAsDictionary()}; @@ -145,18 +123,8 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { Status error; StructuredData::ObjectSP obj = Dispatch("get_process_id", error); - auto error_with_message = [](llvm::StringRef message) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), - "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) return LLDB_INVALID_PROCESS_ID; - }; - - if (!obj || !obj->IsValid() || error.Fail()) { - return error_with_message(llvm::Twine("Null or invalid object (" + - llvm::Twine(error.AsCString()) + - llvm::Twine(").")) - .str()); - } return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID); } @@ -165,20 +133,30 @@ bool ScriptedProcessPythonInterface::IsAlive() { Status error; StructuredData::ObjectSP obj = Dispatch("is_alive", error); - auto error_with_message = [](llvm::StringRef message) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), - "ScriptedProcess::%s ERROR = %s", __FUNCTION__, message.data()); - return false; - }; - - if (!obj || !obj->IsValid() || error.Fail()) { - return error_with_message(llvm::Twine("Null or invalid object (" + - llvm::Twine(error.AsCString()) + - llvm::Twine(").")) - .str()); - } + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; return obj->GetBooleanValue(); } +llvm::Optional +ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; + + return obj->GetStringValue().str(); +} + +lldb::ScriptedThreadInterfaceSP +ScriptedProcessPythonInterface::GetScriptedThreadInterface() { + if (!m_scripted_thread_interface_sp) + m_scripted_thread_interface_sp = + std::make_shared(m_interpreter); + + return m_scripted_thread_interface_sp; +} + #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h index 3ad1cdf6e18a8..eb3d2f3424436 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -50,6 +50,11 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface, lldb::pid_t GetProcessID() override; bool IsAlive() override; + + llvm::Optional GetScriptedThreadPluginName() override; + +private: + lldb::ScriptedThreadInterfaceSP GetScriptedThreadInterface() override; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp index a38cb104c0c63..e8fb38e6492f1 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp @@ -35,6 +35,14 @@ ScriptedPythonInterface::GetStatusFromMethod(llvm::StringRef method_name) { return error; } +template <> +StructuredData::DictionarySP +ScriptedPythonInterface::ExtractValueFromPythonObject< + StructuredData::DictionarySP>(python::PythonObject &p, Status &error) { + python::PythonDictionary result_dict(python::PyRefType::Borrowed, p.get()); + return result_dict.CreateStructuredDictionary(); +} + template <> Status ScriptedPythonInterface::ExtractValueFromPythonObject( python::PythonObject &p, Status &error) { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h index bac4efbe76d8d..9f76ed8fba687 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h @@ -38,15 +38,13 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { using namespace python; using Locker = ScriptInterpreterPythonImpl::Locker; - auto error_with_message = [&method_name, &error](llvm::StringRef message) { - error.SetErrorStringWithFormatv( - "ScriptedPythonInterface::{0} ({1}) ERROR = {2}", __FUNCTION__, - method_name, message); - return T(); - }; - + std::string caller_signature = + llvm::Twine(__PRETTY_FUNCTION__ + llvm::Twine(" (") + + llvm::Twine(method_name) + llvm::Twine(")")) + .str(); if (!m_object_instance_sp) - return error_with_message("Python object ill-formed"); + return ErrorWithMessage(caller_signature, "Python object ill-formed", + error); Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); @@ -55,7 +53,8 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { (PyObject *)m_object_instance_sp->GetValue()); if (!implementor.IsAllocated()) - return error_with_message("Python implementor not allocated."); + return ErrorWithMessage(caller_signature, + "Python implementor not allocated.", error); PythonObject pmeth( PyRefType::Owned, @@ -65,12 +64,14 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { PyErr_Clear(); if (!pmeth.IsAllocated()) - return error_with_message("Python method not allocated."); + return ErrorWithMessage(caller_signature, + "Python method not allocated.", error); if (PyCallable_Check(pmeth.get()) == 0) { if (PyErr_Occurred()) PyErr_Clear(); - return error_with_message("Python method not callable."); + return ErrorWithMessage(caller_signature, + "Python method not callable.", error); } if (PyErr_Occurred()) @@ -96,11 +97,13 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); - return error_with_message("Python method could not be called."); + return ErrorWithMessage(caller_signature, + "Python method could not be called.", error); } if (!py_return.IsAllocated()) - return error_with_message("Returned object is null."); + return ErrorWithMessage(caller_signature, "Returned object is null.", + error); return ExtractValueFromPythonObject(py_return, error); } @@ -123,6 +126,11 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { ScriptInterpreterPythonImpl &m_interpreter; }; +template <> +StructuredData::DictionarySP +ScriptedPythonInterface::ExtractValueFromPythonObject< + StructuredData::DictionarySP>(python::PythonObject &p, Status &error); + template <> Status ScriptedPythonInterface::ExtractValueFromPythonObject( python::PythonObject &p, Status &error); diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp new file mode 100644 index 0000000000000..c2aa4381a1cee --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -0,0 +1,136 @@ +//===-- ScriptedThreadPythonInterface.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// LLDB Python header must be included first +#include "lldb-python.h" + +#include "SWIGPythonBridge.h" +#include "ScriptInterpreterPythonImpl.h" +#include "ScriptedThreadPythonInterface.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::python; +using Locker = ScriptInterpreterPythonImpl::Locker; + +ScriptedThreadPythonInterface::ScriptedThreadPythonInterface( + ScriptInterpreterPythonImpl &interpreter) + : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {} + +StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( + const llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) { + + if (class_name.empty()) + return {}; + + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + std::string error_string; + + TargetSP target_sp = exe_ctx.GetTargetSP(); + + void *ret_val = LLDBSwigPythonCreateScriptedThread( + class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, + error_string); + + if (!ret_val) + return {}; + + m_object_instance_sp = + StructuredData::GenericSP(new StructuredPythonObject(ret_val)); + + return m_object_instance_sp; +} + +lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_thread_id", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return LLDB_INVALID_THREAD_ID; + + return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID); +} + +llvm::Optional ScriptedThreadPythonInterface::GetName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_name", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; + + return obj->GetStringValue().str(); +} + +lldb::StateType ScriptedThreadPythonInterface::GetState() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_state", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return eStateInvalid; + + return static_cast(obj->GetIntegerValue(eStateInvalid)); +} + +llvm::Optional ScriptedThreadPythonInterface::GetQueue() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_queue", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; + + return obj->GetStringValue().str(); +} + +StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() { + Status error; + StructuredData::DictionarySP dict = + Dispatch("get_stop_reason", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, dict, error)) + return {}; + + return dict; +} + +StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() { + return nullptr; +} + +StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() { + Status error; + StructuredData::DictionarySP dict = + Dispatch("get_register_info", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, dict, error)) + return {}; + + return dict; +} + +llvm::Optional +ScriptedThreadPythonInterface::GetRegisterContext() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_register_context", error); + + if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + return {}; + + return obj->GetAsString()->GetValue().str(); +} + +#endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h new file mode 100644 index 0000000000000..996b8d43136bb --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h @@ -0,0 +1,48 @@ +//===-- ScriptedThreadPythonInterface.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H + +#include "lldb/Host/Config.h" + +#if LLDB_ENABLE_PYTHON + +#include "ScriptedPythonInterface.h" +#include "lldb/Interpreter/ScriptedProcessInterface.h" + +namespace lldb_private { +class ScriptedThreadPythonInterface : public ScriptedThreadInterface, + public ScriptedPythonInterface { +public: + ScriptedThreadPythonInterface(ScriptInterpreterPythonImpl &interpreter); + + StructuredData::GenericSP + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) override; + + lldb::tid_t GetThreadID() override; + + llvm::Optional GetName() override; + + lldb::StateType GetState() override; + + llvm::Optional GetQueue() override; + + StructuredData::DictionarySP GetStopReason() override; + + StructuredData::ArraySP GetStackFrames() override; + + StructuredData::DictionarySP GetRegisterInfo() override; + + llvm::Optional GetRegisterContext() override; +}; +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSTHREADINTERFACE_H diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 5cf49ab37791b..70ee1a4d6592b 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -72,6 +72,28 @@ def test_launch_scripted_process_sbapi(self): self.assertTrue(error.Success(), "Failed to read memory from scripted process.") self.assertEqual(hello_world, memory_read) + self.assertEqual(process.GetNumThreads(), 1) + + thread = process.GetSelectedThread() + self.assertTrue(thread, "Invalid thread.") + self.assertEqual(thread.GetThreadID(), 0x19) + self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1") + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) + + self.assertGreater(thread.GetNumFrames(), 0) + + frame = thread.GetFrameAtIndex(0) + register_set = frame.registers # Returns an SBValueList. + for regs in register_set: + if 'GPR' in regs.name: + registers = regs + break + + self.assertTrue(registers, "Invalid General Purpose Registers Set") + self.assertEqual(registers.GetNumChildren(), 21) + for idx, reg in enumerate(registers, start=1): + self.assertEqual(idx, int(reg.value, 16)) + def test_launch_scripted_process_cli(self): """Test that we can launch an lldb scripted process from the command line, check its process ID and read string from memory.""" diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index eb02ce2243eca..e636b8cf597ee 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -223,6 +223,12 @@ extern "C" void *LLDBSwigPythonCreateScriptedProcess( return nullptr; } +extern "C" void *LLDBSwigPythonCreateScriptedThread( + const char *python_class_name, const char *session_dictionary_name, + const lldb::TargetSP &target_sp, std::string &error_string) { + return nullptr; +} + extern "C" void * LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, const char *session_dictionary_name) { From a66550e11e0cce27b993514cec1816481850a970 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Fri, 8 Oct 2021 12:25:04 +0000 Subject: [PATCH 027/293] [lldb/Plugins] Add memory region support in ScriptedProcess This patch adds support for memory regions in Scripted Processes. This is necessary to read the stack memory region in order to reconstruct each stackframe of the program. In order to do so, this patch makes some changes to the SBAPI, namely: - Add a new constructor for `SBMemoryRegionInfo` that takes arguments such as the memory region name, address range, permissions ... This is used when reading memory at some address to compute the offset in the binary blob provided by the user. - Add a `GetMemoryRegionContainingAddress` method to `SBMemoryRegionInfoList` to simplify the access to a specific memory region. With these changes, lldb is now able to unwind the stack and reconstruct each frame. On top of that, reloading the target module at offset 0 allows lldb to symbolicate the `ScriptedProcess` using debug info, similarly to an ordinary Process. To test this, I wrote a simple program with multiple function calls, ran it in lldb, stopped at a leaf function and read the registers values and copied the stack memory into a binary file. These are then used in the python script. Differential Revision: https://reviews.llvm.org/D108953 Signed-off-by: Med Ismail Bennani --- lldb/bindings/interface/SBMemoryRegionInfo.i | 3 + .../interface/SBMemoryRegionInfoList.i | 3 + lldb/bindings/python/python-wrapper.swig | 16 ++++ .../python/scripted_process/main.stack-dump | Bin 0 -> 8192 bytes .../scripted_process/my_scripted_process.py | 61 ++++++++++-- .../scripted_process/scripted_process.py | 7 +- lldb/include/lldb/API/SBMemoryRegionInfo.h | 6 ++ .../include/lldb/API/SBMemoryRegionInfoList.h | 3 + .../lldb/Interpreter/ScriptInterpreter.h | 4 + .../Interpreter/ScriptedProcessInterface.h | 8 +- lldb/source/API/SBMemoryRegionInfo.cpp | 21 ++++ lldb/source/API/SBMemoryRegionInfoList.cpp | 23 +++++ lldb/source/Interpreter/ScriptInterpreter.cpp | 8 ++ .../Process/scripted/ScriptedProcess.cpp | 28 ++++-- .../Python/SWIGPythonBridge.h | 1 + .../Python/ScriptedProcessPythonInterface.cpp | 15 ++- .../Python/ScriptedProcessPythonInterface.h | 5 +- .../Python/ScriptedPythonInterface.cpp | 21 +++- .../Python/ScriptedPythonInterface.h | 5 + .../scripted_process/TestScriptedProcess.py | 45 +++++---- .../dummy_scripted_process.py | 90 ++++++++++++++++++ .../functionalities/scripted_process/main.c | 11 ++- .../Python/PythonTestSuite.cpp | 4 + 23 files changed, 340 insertions(+), 48 deletions(-) create mode 100644 lldb/examples/python/scripted_process/main.stack-dump create mode 100644 lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py diff --git a/lldb/bindings/interface/SBMemoryRegionInfo.i b/lldb/bindings/interface/SBMemoryRegionInfo.i index 3460dc0d06e22..0316c5a5be1d8 100644 --- a/lldb/bindings/interface/SBMemoryRegionInfo.i +++ b/lldb/bindings/interface/SBMemoryRegionInfo.i @@ -20,6 +20,9 @@ public: SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs); + SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin, + lldb::addr_t end, uint32_t permissions, bool mapped, bool stack_memory); + ~SBMemoryRegionInfo (); void diff --git a/lldb/bindings/interface/SBMemoryRegionInfoList.i b/lldb/bindings/interface/SBMemoryRegionInfoList.i index c2e74f1cd0dcd..0097512775421 100644 --- a/lldb/bindings/interface/SBMemoryRegionInfoList.i +++ b/lldb/bindings/interface/SBMemoryRegionInfoList.i @@ -24,6 +24,9 @@ public: uint32_t GetSize () const; + bool + GetMemoryRegionContainingAddress (lldb::addr_t addr, SBMemoryRegionInfo ®ion_info); + bool GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo ®ion_info); diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index feb4e54240bc1..5a950e259e993 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -974,6 +974,22 @@ LLDBSWIGPython_CastPyObjectToSBValue return sb_ptr; } +SWIGEXPORT void* +LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo +( + PyObject* data +) +{ + lldb::SBMemoryRegionInfo* sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + SWIGEXPORT bool LLDBSwigPythonCallCommand ( diff --git a/lldb/examples/python/scripted_process/main.stack-dump b/lldb/examples/python/scripted_process/main.stack-dump new file mode 100644 index 0000000000000000000000000000000000000000..3df66384f4431dbb7296b964bed918e51a6846a7 GIT binary patch literal 8192 zcmcgxeT*AN72kfSX-R|vs?<=9)=5*Eme^}wd>^^ornhJBo!zs~#vhlvYs+T6UfbJS zd!60&#TO1Ww1J|OKZ1xv5dlS|2#QL%w4t;m5K>_e|@Fmx-^C*82=X+#5jCY|NV*|7ocLMJF z1mGF;!@+gXKJ5VvehTpDlYrM^|0Mdi3;lay2K*aD|IVWwi${R(4Ept2#31_jJlb;x z^;(1e&7gnpLjT6lzvu4&d3p5jBKqkVuHWhXFz%p#H=}>QivB%@@=u~&htMxCJq~jEJu?XX2hqQep?~MmzZvxJBF0A-+A)v*4WfS!p?|~ZU*^B+HCMUuxt3ey;(^;C zUU%LG{@ipL+7Qhgw}xAFBm4e;;Nf3_USzIeI^Q*CK%e86LBD4s=(%$z;AL)HxNrA$ z;wI?-U+K!?jLAE-B>(au(s}2fLBCyyjBYt(`jhd?hsf*sKLP(q!~-{j{%gq?eK72y zaS`t>q&;v8`U%_Z{=FCVK8yZk_Epyd-)+dp^tifBhf@!9_V~L_xrBT!VN%w zYU2;5XufnGvd5YK*?K4b4nBG3n@4WX)%tplB)<2T^~S4@(>SKju|RU;{*TT)!}#95 z9pv&g+u{v9$LHsaJfS;vEA(G|4&)Npw}K8yEz z75aJh-1l91@7@RPpIHwDX+LY1`0uo|?;iVx+dk~>9*)~YiRr@v3R>@ZSGR+mb+pgp zhc<^eiT#Z6R`!A8$8r1z-v)oQ$Jq;}b~Vkc)EmF3p1$z(fr?()5tuD)MW@ z3Hg>~Gk1?Fm+hjQvovLfJMqqSq?=pK9o^X9`}%(RO`mm`_n2MWCRo=Y#9MLw+x6eZ z;^Jn^Pe{+^0qNw;`pKt<{GNXI<8B;L`B#zlaU5s3fckha|Nh}W5HFKWa!6=!zs2^t z&w#!S|C2E~K7{ei{C@!D9%A+q8uuZ@l%D;rd=kD{c=V&3zr6}}HueejvvCi$UwH!f zS^M`g+Yd0^5a#KfNWUWo? z*R;;Su*{pq5#wXX)`L3^{$h32kMo@-i%xUs5Vr3pd5Y@B>h4#_deU)Le;;idr}k5o zs<`eizXbfW@BN-8yWD*=@G|gKG0&exeYm|S53z}Fh{`{Re20;*K~D$C(~v{znV+<8 zK>E#yF3}};?L~id63t?pjve>GeqnSs^3d)_3?mwd^N2q}d=Bw6;yJ`FKgjVS_8|@< zW)W+M4~}MSK(S--y?32fEFOMZ|f;{fN&XzJ|!+Dv5FSCiede z@p?ReBoGb6hY^2;_*XFVrfkqnj1Q&>dZ~d0Vygs-xxQs%5I0ZS#uHtT`Na ziRFi-iH;_4vBc=O7?%WM7^&f*k>Oe;Z)nlHR&n%#u33U=mVHXKYG}TUW|ehf2p35Z zh9!l$L@b=#5pL@F02gu6ctjizh2?NGEe^*d*%j#LV(CyKmPnRmnHlD7h@AMg>luPR6pMav~C+nodUq%gp8GteS0WhQXU9Z+XtU$1ZU(aeP$J zDsndM%VtKr{ajK?MH69Ri=UIi(M%#G%<5$>7LvtStc4Dw4@bwFZS(D^8nq&y(<@5~ zO(i4JxICVX3jsfuPDf-hn~BKjL}*OltCl{iI2!MitNfBP4TS_oDetq!rn>|EddQ#T zW4i5V6%u6)xefog@&!Ma6i20$V34?JqDi%Ar&UTyMa^>~Nih>?9_bvmdDAKAL?91V zm33RCT9WmqQELw@E%P#q+9n{U*cuO8;^LW=nqwNKl3&@ZHAgoteoj~6d(7O*<}}RW z${2NXWqhh>X)EKThF&x$TM-%)Wu=n8c>gvenAMd*X^Yfeb1bTlz8bo;t}K`tE%iJ^!j!#f?FmV_Sv zCsGQCYgVqB?``AQ`$h@c` z#OG?dk>}%PzGf&EmmZ5I<;hSYEXn9!nRu1t?~ba5r4cb3%Yb8*99vG!^@^NKB}P+X zTo7s5lpAG}tzS5iajTcl$L$c)@l2Fdv$m4T`*tgK+0n}yElZ)yRI=3-)cI^0rmqkT z1~^&;n^N}D7HK%V5fXDW8ajtX(IjD_t1|<-s<~*BNH%EOR#n4rU@LNeq*C=*12xl}evL#e`pSw@#F%z9e;w_UPM<*eY$t2U*3Hcx#Z9N@;Csjo)X&gCSBxB-~ zFhGt$cpxLj$3?OQ$@#$zu{2p{x;3L=vP4@$lGGjWj%*DLdxL!=TfD=4{vNN`EA<6? z!-1Zy!C~g0Y$_&{9H&YWDPPo`QZ45r2@j7Lu>NdDcEll@f}C$4Yc=92oehO(q(M9p z&EWiFmpoq8vw`Fsk2mL;_mI;Y?YPC(98bX!NS*RHw$SgXm}N6h-Uc~X5vbHWZki&m zTDcW=alc&ESN@~-j@A-ezvhGTm^ySKa@)Rq4hHvb7F-%HR^SzQsKa)_NQHq-FTRNI#(|F(! z9IK`^(iiO>$xcsC$#F3giZs>k2;9)aPbzdIpF<`r{~pdq-z~pSZ+Wbu77Ds}wb% z!$f68ugJDTmZj5Z2L`vR=`Sku#z_rS{Q(*Wer2=2p6d^)h5l}i{(ngBL{Nao?+*mJ Q^MO9jDalpSa!`f;0!D`8qW}N^ literal 0 HcmV?d00001 diff --git a/lldb/examples/python/scripted_process/my_scripted_process.py b/lldb/examples/python/scripted_process/my_scripted_process.py index 9257cd9c85126..224b772845a7f 100644 --- a/lldb/examples/python/scripted_process/my_scripted_process.py +++ b/lldb/examples/python/scripted_process/my_scripted_process.py @@ -7,11 +7,22 @@ from lldb.plugins.scripted_process import ScriptedThread class MyScriptedProcess(ScriptedProcess): + memory_regions = [ + lldb.SBMemoryRegionInfo("stack", 0x1040b2000, 0x1040b4000, 0b110, True, + True) + ] + + stack_memory_dump = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'main.stack-dump') + def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData): super().__init__(target, args) def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo: - return self.memory_regions[0] + for region in self.memory_regions: + if region.GetRegionBase() <= addr < region.GetRegionEnd(): + return region + return None def get_thread_with_id(self, tid: int): return {} @@ -20,10 +31,25 @@ def get_registers_for_thread(self, tid: int): return {} def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData: - data = lldb.SBData().CreateDataFromCString( + data = lldb.SBData() + + with open(self.stack_memory_dump, 'rb') as f: + stack_mem = f.read(-1) + if not stack_mem: + return data + + mem_region = self.get_memory_region_containing_address(addr) + + if not mem_region or addr + size > mem_region.GetRegionEnd(): + return data + + offset = addr - mem_region.GetRegionBase() + shrunk_stack_mem = stack_mem[offset:offset + size] + + error = lldb.SBError() + data.SetData(error, shrunk_stack_mem, self.target.GetByteOrder(), - self.target.GetCodeByteSize(), - "Hello, world!") + self.target.GetAddressByteSize()) return data def get_loaded_images(self): @@ -43,6 +69,30 @@ def get_scripted_thread_plugin(self): class MyScriptedThread(ScriptedThread): + registers = { + "rax":0x00000000000006e4, + "rbx":0x00000001040b6060, + "rcx":0x00000001040b2e00, + "rdx":0x00000001040b2ba8, + "rdi":0x000000000000002a, + "rsi":0x00000001040b2b98, + "rbp":0x00000001040b2a20, + "rsp":0x00000001040b2a20, + "r8":0x00000000003e131e, + "r9":0xffffffff00000000, + "r10":0x0000000000000000, + "r11":0x0000000000000246, + "r12":0x000000010007c3a0, + "r13":0x00000001040b2b18, + "r14":0x0000000100003f90, + "r15":0x00000001040b2b88, + "rip":0x0000000100003f61, + "rflags":0x0000000000000206, + "cs":0x000000000000002b, + "fs":0x0000000000000000, + "gs":0x0000000000000000, + } + def __init__(self, target): super().__init__(target) @@ -73,8 +123,7 @@ def __init__(idx, cfa, pc, symbol_ctx): return self.frame_zero[0:0] def get_register_context(self) -> str: - return struct.pack( - '21Q', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + return struct.pack("{}Q".format(len(self.registers)), *self.registers.values()) def __lldb_init_module(debugger, dict): diff --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/scripted_process/scripted_process.py index d3474fbcf0a08..5869ca03e20bd 100644 --- a/lldb/examples/python/scripted_process/scripted_process.py +++ b/lldb/examples/python/scripted_process/scripted_process.py @@ -16,6 +16,10 @@ class ScriptedProcess: THE METHODS EXPOSED MIGHT CHANGE IN THE FUTURE. """ + memory_regions = None + stack_memory_dump = None + loaded_images = None + @abstractmethod def __init__(self, target, args): """ Construct a scripted process. @@ -91,7 +95,6 @@ def read_memory_at_address(addr, size): """ pass - @abstractmethod def get_loaded_images(self): """ Get the list of loaded images for the scripted process. @@ -110,7 +113,7 @@ def __init__(name, file_spec, uuid, load_address): an `lldb.SBFileSpec` and a load address. None if the list is empty. """ - pass + return self.loaded_images def get_process_id(self): """ Get the scripted process identifier. diff --git a/lldb/include/lldb/API/SBMemoryRegionInfo.h b/lldb/include/lldb/API/SBMemoryRegionInfo.h index 122226b9a0c5c..be55de4ead1fa 100644 --- a/lldb/include/lldb/API/SBMemoryRegionInfo.h +++ b/lldb/include/lldb/API/SBMemoryRegionInfo.h @@ -20,6 +20,10 @@ class LLDB_API SBMemoryRegionInfo { SBMemoryRegionInfo(const lldb::SBMemoryRegionInfo &rhs); + SBMemoryRegionInfo(const char *name, lldb::addr_t begin, lldb::addr_t end, + uint32_t permissions, bool mapped, + bool stack_memory = false); + ~SBMemoryRegionInfo(); const lldb::SBMemoryRegionInfo & @@ -117,6 +121,8 @@ class LLDB_API SBMemoryRegionInfo { friend class SBProcess; friend class SBMemoryRegionInfoList; + friend class lldb_private::ScriptInterpreter; + lldb_private::MemoryRegionInfo &ref(); const lldb_private::MemoryRegionInfo &ref() const; diff --git a/lldb/include/lldb/API/SBMemoryRegionInfoList.h b/lldb/include/lldb/API/SBMemoryRegionInfoList.h index a7122ee9108a3..1d939dff55faa 100644 --- a/lldb/include/lldb/API/SBMemoryRegionInfoList.h +++ b/lldb/include/lldb/API/SBMemoryRegionInfoList.h @@ -27,6 +27,9 @@ class LLDB_API SBMemoryRegionInfoList { uint32_t GetSize() const; + bool GetMemoryRegionContainingAddress(lldb::addr_t addr, + SBMemoryRegionInfo ®ion_info); + bool GetMemoryRegionAtIndex(uint32_t idx, SBMemoryRegionInfo ®ion_info); void Append(lldb::SBMemoryRegionInfo ®ion); diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 80a054b32ce65..56cfb5cb8dd54 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -11,6 +11,7 @@ #include "lldb/API/SBData.h" #include "lldb/API/SBError.h" +#include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/Communication.h" #include "lldb/Core/PluginInterface.h" @@ -564,6 +565,9 @@ class ScriptInterpreter : public PluginInterface { Status GetStatusFromSBError(const lldb::SBError &error) const; + llvm::Optional GetOpaqueTypeFromSBMemoryRegionInfo( + const lldb::SBMemoryRegionInfo &mem_region) const; + protected: Debugger &m_debugger; lldb::ScriptLanguage m_script_lang; diff --git a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h index 31d6e1476a6ed..26fd956f96bbc 100644 --- a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h +++ b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -12,6 +12,7 @@ #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Interpreter/ScriptedInterface.h" +#include "lldb/Target/MemoryRegionInfo.h" #include "lldb/lldb-private.h" @@ -34,9 +35,10 @@ class ScriptedProcessInterface : virtual public ScriptedInterface { virtual Status Stop() { return Status("ScriptedProcess did not stop"); } - virtual lldb::MemoryRegionInfoSP - GetMemoryRegionContainingAddress(lldb::addr_t address) { - return nullptr; + virtual llvm::Optional + GetMemoryRegionContainingAddress(lldb::addr_t address, Status &error) { + error.SetErrorString("ScriptedProcess have no memory region."); + return {}; } virtual StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) { diff --git a/lldb/source/API/SBMemoryRegionInfo.cpp b/lldb/source/API/SBMemoryRegionInfo.cpp index c0f5456223da5..9cf7874b54a3b 100644 --- a/lldb/source/API/SBMemoryRegionInfo.cpp +++ b/lldb/source/API/SBMemoryRegionInfo.cpp @@ -22,6 +22,24 @@ SBMemoryRegionInfo::SBMemoryRegionInfo() : m_opaque_up(new MemoryRegionInfo()) { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBMemoryRegionInfo); } +SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin, + lldb::addr_t end, uint32_t permissions, + bool mapped, bool stack_memory) + : SBMemoryRegionInfo() { + LLDB_RECORD_CONSTRUCTOR( + SBMemoryRegionInfo, + (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool), name, + begin, end, permissions, mapped, stack_memory); + m_opaque_up->SetName(name); + m_opaque_up->GetRange().SetRangeBase(begin); + m_opaque_up->GetRange().SetRangeEnd(end); + m_opaque_up->SetLLDBPermissions(permissions); + m_opaque_up->SetMapped(mapped ? MemoryRegionInfo::eYes + : MemoryRegionInfo::eNo); + m_opaque_up->SetIsStackMemory(stack_memory ? MemoryRegionInfo::eYes + : MemoryRegionInfo::eNo); +} + SBMemoryRegionInfo::SBMemoryRegionInfo(const MemoryRegionInfo *lldb_object_ptr) : m_opaque_up(new MemoryRegionInfo()) { if (lldb_object_ptr) @@ -178,6 +196,9 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo, ()); LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo, (const lldb::SBMemoryRegionInfo &)); + LLDB_REGISTER_CONSTRUCTOR( + SBMemoryRegionInfo, + (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool)); LLDB_REGISTER_METHOD( const lldb::SBMemoryRegionInfo &, SBMemoryRegionInfo, operator=,(const lldb::SBMemoryRegionInfo &)); diff --git a/lldb/source/API/SBMemoryRegionInfoList.cpp b/lldb/source/API/SBMemoryRegionInfoList.cpp index 0f3f9c1b8177f..cd8fc00ffce06 100644 --- a/lldb/source/API/SBMemoryRegionInfoList.cpp +++ b/lldb/source/API/SBMemoryRegionInfoList.cpp @@ -48,6 +48,17 @@ class MemoryRegionInfoListImpl { void Clear() { m_regions.clear(); } + bool GetMemoryRegionContainingAddress(lldb::addr_t addr, + MemoryRegionInfo ®ion_info) { + for (auto ®ion : m_regions) { + if (region.GetRange().Contains(addr)) { + region_info = region; + return true; + } + } + return false; + } + bool GetMemoryRegionInfoAtIndex(size_t index, MemoryRegionInfo ®ion_info) { if (index >= GetSize()) @@ -103,6 +114,15 @@ uint32_t SBMemoryRegionInfoList::GetSize() const { return m_opaque_up->GetSize(); } +bool SBMemoryRegionInfoList::GetMemoryRegionContainingAddress( + lldb::addr_t addr, SBMemoryRegionInfo ®ion_info) { + LLDB_RECORD_METHOD( + bool, SBMemoryRegionInfoList, GetMemoryRegionContainingAddress, + (lldb::addr_t, lldb::SBMemoryRegionInfo &), addr, region_info); + + return m_opaque_up->GetMemoryRegionContainingAddress(addr, region_info.ref()); +} + bool SBMemoryRegionInfoList::GetMemoryRegionAtIndex( uint32_t idx, SBMemoryRegionInfo ®ion_info) { LLDB_RECORD_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex, @@ -153,6 +173,9 @@ void RegisterMethods(Registry &R) { SBMemoryRegionInfoList, operator=,( const lldb::SBMemoryRegionInfoList &)); LLDB_REGISTER_METHOD_CONST(uint32_t, SBMemoryRegionInfoList, GetSize, ()); + LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList, + GetMemoryRegionContainingAddress, + (lldb::addr_t, lldb::SBMemoryRegionInfo &)); LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex, (uint32_t, lldb::SBMemoryRegionInfo &)); LLDB_REGISTER_METHOD(void, SBMemoryRegionInfoList, Clear, ()); diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index f26474836a68c..539a8fdf07b74 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -83,6 +83,14 @@ ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const { return Status(); } +llvm::Optional +ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo( + const lldb::SBMemoryRegionInfo &mem_region) const { + if (!mem_region.m_opaque_up) + return llvm::None; + return *mem_region.m_opaque_up.get(); +} + lldb::ScriptLanguage ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { if (language.equals_insensitive(LanguageToString(eScriptLanguageNone))) diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index 467872c90938f..c98044326a8fa 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -241,7 +241,7 @@ size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb::DataExtractorSP data_extractor_sp = GetInterface().ReadMemoryAtAddress(addr, size, error); - if (!data_extractor_sp || error.Fail()) + if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail()) return 0; offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData( @@ -260,24 +260,34 @@ ArchSpec ScriptedProcess::GetArchitecture() { Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo ®ion) { - // TODO: Implement - return Status(); + CheckInterpreterAndScriptObject(); + + Status error; + if (auto region_or_err = + GetInterface().GetMemoryRegionContainingAddress(load_addr, error)) + region = *region_or_err; + + return error; } Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos ®ion_list) { CheckInterpreterAndScriptObject(); + Status error; lldb::addr_t address = 0; - lldb::MemoryRegionInfoSP mem_region_sp = nullptr; - while ((mem_region_sp = - GetInterface().GetMemoryRegionContainingAddress(address))) { - auto range = mem_region_sp->GetRange(); + while (auto region_or_err = + GetInterface().GetMemoryRegionContainingAddress(address, error)) { + if (error.Fail()) + break; + + MemoryRegionInfo &mem_region = *region_or_err; + auto range = mem_region.GetRange(); address += range.GetRangeBase() + range.GetByteSize(); - region_list.push_back(*mem_region_sp.get()); + region_list.push_back(mem_region); } - return {}; + return error; } void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 8d6e7dc4ee789..81e25128b2c7d 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -53,6 +53,7 @@ extern "C" void *LLDBSwigPythonCreateScriptedThread( extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data); extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data); extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data); +extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data); } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp index 32be169f0d1de..ffaee26147933 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -82,11 +82,18 @@ Status ScriptedProcessPythonInterface::Stop() { return GetStatusFromMethod("stop"); } -lldb::MemoryRegionInfoSP +llvm::Optional ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( - lldb::addr_t address) { - // TODO: Implement - return {}; + lldb::addr_t address, Status &error) { + auto mem_region = Dispatch>( + "get_memory_region_containing_address", error, address); + + if (error.Fail()) { + return ErrorWithMessage(__PRETTY_FUNCTION__, + error.AsCString(), error); + } + + return mem_region; } StructuredData::DictionarySP diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h index eb3d2f3424436..421bdd59887ce 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -35,8 +35,9 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface, Status Stop() override; - lldb::MemoryRegionInfoSP - GetMemoryRegionContainingAddress(lldb::addr_t address) override; + llvm::Optional + GetMemoryRegionContainingAddress(lldb::addr_t address, + Status &error) override; StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp index e8fb38e6492f1..07bf952bf840e 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp @@ -63,11 +63,30 @@ ScriptedPythonInterface::ExtractValueFromPythonObject( LLDBSWIGPython_CastPyObjectToSBData(p.get())); if (!sb_data) { - error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status."); + error.SetErrorString( + "Couldn't cast lldb::SBData to lldb::DataExtractorSP."); return nullptr; } return m_interpreter.GetDataExtractorFromSBData(*sb_data); } +template <> +llvm::Optional +ScriptedPythonInterface::ExtractValueFromPythonObject< + llvm::Optional>(python::PythonObject &p, Status &error) { + + lldb::SBMemoryRegionInfo *sb_mem_reg_info = + reinterpret_cast( + LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get())); + + if (!sb_mem_reg_info) { + error.SetErrorString( + "Couldn't cast lldb::SBMemoryRegionInfo to lldb::MemoryRegionInfoSP."); + return {}; + } + + return m_interpreter.GetOpaqueTypeFromSBMemoryRegionInfo(*sb_mem_reg_info); +} + #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h index 9f76ed8fba687..9b81555dacb60 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h @@ -140,6 +140,11 @@ lldb::DataExtractorSP ScriptedPythonInterface::ExtractValueFromPythonObject( python::PythonObject &p, Status &error); +template <> +llvm::Optional +ScriptedPythonInterface::ExtractValueFromPythonObject< + llvm::Optional>(python::PythonObject &p, Status &error); + } // namespace lldb_private #endif // LLDB_ENABLE_PYTHON diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 70ee1a4d6592b..b595d3dba32e5 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -43,41 +43,35 @@ def test_python_plugin_package(self): self.expect('script dir(ScriptedProcess)', substrs=["launch"]) - def test_launch_scripted_process_sbapi(self): + def test_scripted_process_and_scripted_thread(self): """Test that we can launch an lldb scripted process using the SBAPI, - check its process ID and read string from memory.""" + check its process ID, read string from memory, check scripted thread + id, name stop reason and register context. + """ self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) - scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py'] + scripted_process_example_relpath = 'dummy_scripted_process.py' os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' self.runCmd("command script import " + os.path.join(self.getSourceDir(), - *scripted_process_example_relpath)) + scripted_process_example_relpath)) launch_info = lldb.SBLaunchInfo(None) launch_info.SetProcessPluginName("ScriptedProcess") - launch_info.SetScriptedProcessClassName("my_scripted_process.MyScriptedProcess") + launch_info.SetScriptedProcessClassName("dummy_scripted_process.DummyScriptedProcess") error = lldb.SBError() process = target.Launch(launch_info, error) self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) self.assertEqual(process.GetProcessID(), 42) - hello_world = "Hello, world!" - memory_read = process.ReadCStringFromMemory(0x50000000000, - len(hello_world) + 1, # NULL byte - error) - - self.assertTrue(error.Success(), "Failed to read memory from scripted process.") - self.assertEqual(hello_world, memory_read) - self.assertEqual(process.GetNumThreads(), 1) thread = process.GetSelectedThread() self.assertTrue(thread, "Invalid thread.") self.assertEqual(thread.GetThreadID(), 0x19) - self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1") + self.assertEqual(thread.GetName(), "DummyScriptedThread.thread-1") self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) self.assertGreater(thread.GetNumFrames(), 0) @@ -94,13 +88,21 @@ def test_launch_scripted_process_sbapi(self): for idx, reg in enumerate(registers, start=1): self.assertEqual(idx, int(reg.value, 16)) - def test_launch_scripted_process_cli(self): + def test_launch_scripted_process_stack_frames(self): """Test that we can launch an lldb scripted process from the command line, check its process ID and read string from memory.""" self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) + for module in target.modules: + if 'a.out' in module.GetFileSpec().GetFilename(): + main_module = module + + self.assertTrue(main_module, "Invalid main module.") + error = target.SetModuleLoadAddress(main_module, 0) + self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.") + scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py'] self.runCmd("command script import " + os.path.join(self.getSourceDir(), *scripted_process_example_relpath)) @@ -108,12 +110,21 @@ def test_launch_scripted_process_cli(self): process = target.GetProcess() self.assertTrue(process, PROCESS_IS_VALID) self.assertEqual(process.GetProcessID(), 42) + self.assertEqual(process.GetNumThreads(), 1) error = lldb.SBError() hello_world = "Hello, world!" memory_read = process.ReadCStringFromMemory(0x50000000000, len(hello_world) + 1, # NULL byte error) + thread = process.GetSelectedThread() + self.assertTrue(thread, "Invalid thread.") + self.assertEqual(thread.GetThreadID(), 0x19) + self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1") - self.assertTrue(error.Success(), "Failed to read memory from scripted process.") - self.assertEqual(hello_world, memory_read) + self.assertEqual(thread.GetNumFrames(), 4) + frame = thread.GetSelectedFrame() + self.assertTrue(frame, "Invalid frame.") + self.assertEqual(frame.GetFunctionName(), "bar") + self.assertEqual(int(frame.FindValue("i", lldb.eValueTypeVariableArgument).GetValue()), 42) + self.assertEqual(int(frame.FindValue("j", lldb.eValueTypeVariableLocal).GetValue()), 42 * 42) diff --git a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py new file mode 100644 index 0000000000000..31a52f28c6c00 --- /dev/null +++ b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py @@ -0,0 +1,90 @@ +import os,struct, signal + +from typing import Any, Dict + +import lldb +from lldb.plugins.scripted_process import ScriptedProcess +from lldb.plugins.scripted_process import ScriptedThread + +class DummyScriptedProcess(ScriptedProcess): + def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData): + super().__init__(target, args) + + def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo: + return None + + def get_thread_with_id(self, tid: int): + return {} + + def get_registers_for_thread(self, tid: int): + return {} + + def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData: + data = lldb.SBData().CreateDataFromCString( + self.target.GetByteOrder(), + self.target.GetCodeByteSize(), + "Hello, world!") + return data + + def get_loaded_images(self): + return self.loaded_images + + def get_process_id(self) -> int: + return 42 + + def should_stop(self) -> bool: + return True + + def is_alive(self) -> bool: + return True + + def get_scripted_thread_plugin(self): + return DummyScriptedThread.__module__ + "." + DummyScriptedThread.__name__ + + +class DummyScriptedThread(ScriptedThread): + def __init__(self, target): + super().__init__(target) + + def get_thread_id(self) -> int: + return 0x19 + + def get_name(self) -> str: + return DummyScriptedThread.__name__ + ".thread-1" + + def get_state(self) -> int: + return lldb.eStateStopped + + def get_stop_reason(self) -> Dict[str, Any]: + return { "type": lldb.eStopReasonSignal, "data": { + "signal": signal.SIGINT + } } + + def get_stackframes(self): + class ScriptedStackFrame: + def __init__(idx, cfa, pc, symbol_ctx): + self.idx = idx + self.cfa = cfa + self.pc = pc + self.symbol_ctx = symbol_ctx + + + symbol_ctx = lldb.SBSymbolContext() + frame_zero = ScriptedStackFrame(0, 0x42424242, 0x5000000, symbol_ctx) + self.frames.append(frame_zero) + + return self.frame_zero[0:0] + + def get_register_context(self) -> str: + return struct.pack( + '21Q', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + + +def __lldb_init_module(debugger, dict): + if not 'SKIP_SCRIPTED_PROCESS_LAUNCH' in os.environ: + debugger.HandleCommand( + "process launch -C %s.%s" % (__name__, + DummyScriptedProcess.__name__)) + else: + print("Name of the class that will manage the scripted process: '%s.%s'" + % (__name__, DummyScriptedProcess.__name__)) \ No newline at end of file diff --git a/lldb/test/API/functionalities/scripted_process/main.c b/lldb/test/API/functionalities/scripted_process/main.c index 3e82b70c8f4d3..67d3732441da2 100644 --- a/lldb/test/API/functionalities/scripted_process/main.c +++ b/lldb/test/API/functionalities/scripted_process/main.c @@ -1,5 +1,8 @@ -#include - -int main() { - return 0; // break here +int bar(int i) { + int j = i * i; + return j; // break here } + +int foo(int i) { return bar(i); } + +int main() { return foo(42); } diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index e636b8cf597ee..ea6d6be7dbd5e 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -166,6 +166,10 @@ extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data) { return nullptr; } +extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data) { + return nullptr; +} + extern lldb::ValueObjectSP LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data) { return nullptr; From 577d278dc5cf17cc8371686b3378a737fd04af22 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Fri, 8 Oct 2021 15:19:54 +0200 Subject: [PATCH 028/293] [lldb/test] Disable TestScriptedProcess.py unless Darwin This patch disables TestScriptedProcess.py on Linux and Windows while I investigate the OS specific failure: http://lab.llvm.org:8011/#/builders/68/builds/19793 Signed-off-by: Med Ismail Bennani --- .../API/functionalities/scripted_process/TestScriptedProcess.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index b595d3dba32e5..2341aa27e66b0 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -88,6 +88,7 @@ def test_scripted_process_and_scripted_thread(self): for idx, reg in enumerate(registers, start=1): self.assertEqual(idx, int(reg.value, 16)) + @skipUnlessDarwin def test_launch_scripted_process_stack_frames(self): """Test that we can launch an lldb scripted process from the command line, check its process ID and read string from memory.""" From 27e3dc650c0d63659c2140c2b69ff20167a08b19 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Fri, 8 Oct 2021 18:24:41 +0200 Subject: [PATCH 029/293] [lldb] Fix windows build failure due to undefined macro This should fix a build failure on Windows caused by the macro __PRETTY_FUNCTION__ not being defined. https://lab.llvm.org/buildbot/#/builders/83/builds/10836 https://reviews.llvm.org/D107585 Signed-off-by: Med Ismail Bennani --- lldb/include/lldb/Interpreter/ScriptedInterface.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lldb/include/lldb/Interpreter/ScriptedInterface.h b/lldb/include/lldb/Interpreter/ScriptedInterface.h index 38164739bab57..bd1ed11279f4e 100644 --- a/lldb/include/lldb/Interpreter/ScriptedInterface.h +++ b/lldb/include/lldb/Interpreter/ScriptedInterface.h @@ -9,6 +9,10 @@ #ifndef LLDB_INTERPRETER_SCRIPTEDINTERFACE_H #define LLDB_INTERPRETER_SCRIPTEDINTERFACE_H +#ifdef _MSC_VER +#define __PRETTY_FUNCTION__ __FUNCSIG__ +#endif + #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Log.h" From 8778f150097af65754974df01abb79e6d0961735 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Fri, 8 Oct 2021 18:48:02 +0000 Subject: [PATCH 030/293] [lldb/Plugins] Replace platform-specific macro with LLVM_PRETTY_FUNCTION (NFC) This patch refactors Scripted Process and Scripted Thread related classes to use LLVM_PRETTY_FUNCTION instead of the compiler macro. Differential Revision: https://reviews.llvm.org/D111452 Signed-off-by: Med Ismail Bennani --- lldb/include/lldb/Interpreter/ScriptedInterface.h | 6 ++---- .../Plugins/Process/scripted/ScriptedProcess.cpp | 8 ++++---- .../Plugins/Process/scripted/ScriptedThread.cpp | 6 +++--- .../Python/ScriptedProcessPythonInterface.cpp | 12 ++++++------ .../Python/ScriptedPythonInterface.h | 2 +- .../Python/ScriptedThreadPythonInterface.cpp | 14 +++++++------- 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/lldb/include/lldb/Interpreter/ScriptedInterface.h b/lldb/include/lldb/Interpreter/ScriptedInterface.h index bd1ed11279f4e..427fa3f4f793a 100644 --- a/lldb/include/lldb/Interpreter/ScriptedInterface.h +++ b/lldb/include/lldb/Interpreter/ScriptedInterface.h @@ -9,16 +9,14 @@ #ifndef LLDB_INTERPRETER_SCRIPTEDINTERFACE_H #define LLDB_INTERPRETER_SCRIPTEDINTERFACE_H -#ifdef _MSC_VER -#define __PRETTY_FUNCTION__ __FUNCSIG__ -#endif - #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/lldb-private.h" +#include "llvm/Support/Compiler.h" + #include namespace lldb_private { diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index c98044326a8fa..3cf17060b8156 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -235,7 +235,7 @@ bool ScriptedProcess::IsAlive() { size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) { if (!m_interpreter) - return GetInterface().ErrorWithMessage(__PRETTY_FUNCTION__, + return GetInterface().ErrorWithMessage(LLVM_PRETTY_FUNCTION, "No interpreter.", error); lldb::DataExtractorSP data_extractor_sp = @@ -249,7 +249,7 @@ size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET) return GetInterface().ErrorWithMessage( - __PRETTY_FUNCTION__, "Failed to copy read memory to buffer.", error); + LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error); return size; } @@ -306,7 +306,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, if (language != eScriptLanguagePython) return GetInterface().ErrorWithMessage( - __PRETTY_FUNCTION__, + LLVM_PRETTY_FUNCTION, llvm::Twine("ScriptInterpreter language (" + llvm::Twine(m_interpreter->LanguageToString(language)) + llvm::Twine(") not supported.")) @@ -317,7 +317,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, thread_sp = std::make_shared(*this, error); if (!thread_sp || error.Fail()) - return GetInterface().ErrorWithMessage(__PRETTY_FUNCTION__, + return GetInterface().ErrorWithMessage(LLVM_PRETTY_FUNCTION, error.AsCString(), error); new_thread_list.AddThread(thread_sp); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index 11db89bfc3977..de1203300e4b4 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -141,13 +141,13 @@ bool ScriptedThread::CalculateStopInfo() { if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type)) return GetInterface()->ErrorWithMessage( - __PRETTY_FUNCTION__, + LLVM_PRETTY_FUNCTION, "Couldn't find value for key 'type' in stop reason dictionary.", error); StructuredData::Dictionary *data_dict; if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict)) return GetInterface()->ErrorWithMessage( - __PRETTY_FUNCTION__, + LLVM_PRETTY_FUNCTION, "Couldn't find value for key 'type' in stop reason dictionary.", error); switch (stop_reason_type) { @@ -171,7 +171,7 @@ bool ScriptedThread::CalculateStopInfo() { } break; default: return GetInterface()->ErrorWithMessage( - __PRETTY_FUNCTION__, + LLVM_PRETTY_FUNCTION, llvm::Twine("Unsupported stop reason type (" + llvm::Twine(stop_reason_type) + llvm::Twine(").")) .str(), diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp index ffaee26147933..29680dab5a14a 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -72,7 +72,7 @@ bool ScriptedProcessPythonInterface::ShouldStop() { Status error; StructuredData::ObjectSP obj = Dispatch("is_alive", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetBooleanValue(); @@ -89,7 +89,7 @@ ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( "get_memory_region_containing_address", error, address); if (error.Fail()) { - return ErrorWithMessage(__PRETTY_FUNCTION__, + return ErrorWithMessage(LLVM_PRETTY_FUNCTION, error.AsCString(), error); } @@ -101,7 +101,7 @@ ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { Status error; StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; StructuredData::DictionarySP dict{obj->GetAsDictionary()}; @@ -130,7 +130,7 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { Status error; StructuredData::ObjectSP obj = Dispatch("get_process_id", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_PROCESS_ID; return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID); @@ -140,7 +140,7 @@ bool ScriptedProcessPythonInterface::IsAlive() { Status error; StructuredData::ObjectSP obj = Dispatch("is_alive", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetBooleanValue(); @@ -151,7 +151,7 @@ ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { Status error; StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetStringValue().str(); diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h index 9b81555dacb60..da112eb72022b 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h @@ -39,7 +39,7 @@ class ScriptedPythonInterface : virtual public ScriptedInterface { using Locker = ScriptInterpreterPythonImpl::Locker; std::string caller_signature = - llvm::Twine(__PRETTY_FUNCTION__ + llvm::Twine(" (") + + llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") + llvm::Twine(method_name) + llvm::Twine(")")) .str(); if (!m_object_instance_sp) diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp index c2aa4381a1cee..4d6903d567c52 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -60,7 +60,7 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() { Status error; StructuredData::ObjectSP obj = Dispatch("get_thread_id", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_THREAD_ID; return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID); @@ -70,7 +70,7 @@ llvm::Optional ScriptedThreadPythonInterface::GetName() { Status error; StructuredData::ObjectSP obj = Dispatch("get_name", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetStringValue().str(); @@ -80,7 +80,7 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() { Status error; StructuredData::ObjectSP obj = Dispatch("get_state", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return eStateInvalid; return static_cast(obj->GetIntegerValue(eStateInvalid)); @@ -90,7 +90,7 @@ llvm::Optional ScriptedThreadPythonInterface::GetQueue() { Status error; StructuredData::ObjectSP obj = Dispatch("get_queue", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetStringValue().str(); @@ -101,7 +101,7 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() { StructuredData::DictionarySP dict = Dispatch("get_stop_reason", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, dict, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; return dict; @@ -116,7 +116,7 @@ StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() { StructuredData::DictionarySP dict = Dispatch("get_register_info", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, dict, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; return dict; @@ -127,7 +127,7 @@ ScriptedThreadPythonInterface::GetRegisterContext() { Status error; StructuredData::ObjectSP obj = Dispatch("get_register_context", error); - if (!CheckStructuredDataObject(__PRETTY_FUNCTION__, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; return obj->GetAsString()->GetValue().str(); From 984f2c2c8c2856c2d1b6b3cfa17deb6b1c6858ff Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Sun, 10 Oct 2021 03:28:36 +0200 Subject: [PATCH 031/293] [lldb/test] Disable 'TestScriptedProcess.py' on macOS This is disabling 'TestScriptedProcess.py' on macOS since it fails on Green Dragon: https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/35974 Signed-off-by: Med Ismail Bennani --- .../functionalities/scripted_process/TestScriptedProcess.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 2341aa27e66b0..963ba060f949a 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -88,6 +88,7 @@ def test_scripted_process_and_scripted_thread(self): for idx, reg in enumerate(registers, start=1): self.assertEqual(idx, int(reg.value, 16)) + @skipIfDarwin @skipUnlessDarwin def test_launch_scripted_process_stack_frames(self): """Test that we can launch an lldb scripted process from the command @@ -113,11 +114,6 @@ def test_launch_scripted_process_stack_frames(self): self.assertEqual(process.GetProcessID(), 42) self.assertEqual(process.GetNumThreads(), 1) - error = lldb.SBError() - hello_world = "Hello, world!" - memory_read = process.ReadCStringFromMemory(0x50000000000, - len(hello_world) + 1, # NULL byte - error) thread = process.GetSelectedThread() self.assertTrue(thread, "Invalid thread.") self.assertEqual(thread.GetThreadID(), 0x19) From 3a083b5dc36b18ea8a8f591d69959dfd3655e0d3 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Wed, 10 Nov 2021 16:43:19 +0000 Subject: [PATCH 032/293] [lldb] Fix Scripted ProcessLaunchInfo Argument nullptr deref This patch adds a new `StructuredData::Dictionary` constructor that takes a `StructuredData::ObjectSP` as an argument. This is used to pass the opaque_ptr from the `SBStructuredData` used to initialize a ScriptedProecss, to the `ProcessLaunchInfo` class. This also updates `SBLaunchInfo::SetScriptedProcessDictionary` to reflect the formentionned changes which solves the nullptr deref. Differential Revision: https://reviews.llvm.org/D112107 Signed-off-by: Med Ismail Bennani --- lldb/include/lldb/Core/StructuredDataImpl.h | 2 ++ lldb/include/lldb/Utility/StructuredData.h | 11 +++++++++++ lldb/source/API/SBLaunchInfo.cpp | 14 ++++++++------ .../Plugins/Process/scripted/ScriptedProcess.cpp | 2 +- .../Plugins/Process/scripted/ScriptedProcess.h | 8 +++----- .../Plugins/Process/scripted/ScriptedThread.cpp | 2 +- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lldb/include/lldb/Core/StructuredDataImpl.h b/lldb/include/lldb/Core/StructuredDataImpl.h index 929ce21fb2f92..d6f64451e5c22 100644 --- a/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/lldb/include/lldb/Core/StructuredDataImpl.h @@ -152,6 +152,8 @@ class StructuredDataImpl { return (::snprintf(dst, dst_len, "%s", result.data())); } + StructuredData::ObjectSP GetObjectSP() const { return m_data_sp; } + private: lldb::StructuredDataPluginWP m_plugin_wp; StructuredData::ObjectSP m_data_sp; diff --git a/lldb/include/lldb/Utility/StructuredData.h b/lldb/include/lldb/Utility/StructuredData.h index 4d03af18e527b..c1d136db1c2ef 100644 --- a/lldb/include/lldb/Utility/StructuredData.h +++ b/lldb/include/lldb/Utility/StructuredData.h @@ -353,6 +353,17 @@ class StructuredData { public: Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {} + Dictionary(ObjectSP obj_sp) + : Object(lldb::eStructuredDataTypeDictionary), m_dict() { + if (!obj_sp || obj_sp->GetType() != lldb::eStructuredDataTypeDictionary) { + SetType(lldb::eStructuredDataTypeInvalid); + return; + } + + Dictionary *dict = obj_sp->GetAsDictionary(); + m_dict = dict->m_dict; + } + ~Dictionary() override = default; size_t GetSize() const { return m_dict.size(); } diff --git a/lldb/source/API/SBLaunchInfo.cpp b/lldb/source/API/SBLaunchInfo.cpp index 70cd1c6ecf744..0735e62a16cfd 100644 --- a/lldb/source/API/SBLaunchInfo.cpp +++ b/lldb/source/API/SBLaunchInfo.cpp @@ -380,16 +380,18 @@ lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const { void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) { LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary, (lldb::SBStructuredData), dict); + if (!dict.IsValid() || !dict.m_impl_up) + return; - SBStream stream; - SBError error = dict.GetAsJSON(stream); + StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP(); - if (error.Fail()) + if (!obj_sp) return; - StructuredData::DictionarySP dict_sp; - llvm::json::OStream s(stream.ref().AsRawOstream()); - dict_sp->Serialize(s); + StructuredData::DictionarySP dict_sp = + std::make_shared(obj_sp); + if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid) + return; m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp); } diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index 3cf17060b8156..3b8d37962bcd1 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -111,7 +111,7 @@ ScriptedProcess::ScriptedProcess( StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject( m_scripted_process_info.GetClassName().c_str(), exe_ctx, - m_scripted_process_info.GetDictionarySP()); + m_scripted_process_info.GetArgsSP()); if (!object_sp || !object_sp->IsValid()) { error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h index f527244746322..9db3860a10430 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -25,17 +25,15 @@ class ScriptedProcess : public Process { public: ScriptedProcessInfo(const ProcessLaunchInfo &launch_info) { m_class_name = launch_info.GetScriptedProcessClassName(); - m_dictionary_sp = launch_info.GetScriptedProcessDictionarySP(); + m_args_sp = launch_info.GetScriptedProcessDictionarySP(); } std::string GetClassName() const { return m_class_name; } - StructuredData::DictionarySP GetDictionarySP() const { - return m_dictionary_sp; - } + StructuredData::DictionarySP GetArgsSP() const { return m_args_sp; } private: std::string m_class_name; - StructuredData::DictionarySP m_dictionary_sp; + StructuredData::DictionarySP m_args_sp; }; public: diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index de1203300e4b4..dbe9e5019ff84 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -55,7 +55,7 @@ ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error) StructuredData::GenericSP object_sp = scripted_thread_interface->CreatePluginObject( class_name->c_str(), exe_ctx, - process.m_scripted_process_info.GetDictionarySP()); + process.m_scripted_process_info.GetArgsSP()); if (!object_sp || !object_sp->IsValid()) { error.SetErrorString("Failed to create valid script object"); return; From fd6b58b925450ed8f5a099cada0b03c4d7246fa3 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Tue, 19 Oct 2021 23:30:22 +0000 Subject: [PATCH 033/293] [lldb/bindings] Change ScriptedThread initializer parameters This patch changes the `ScriptedThread` initializer in couple of ways: - It replaces the `SBTarget` parameter by a `SBProcess` (pointing to the `ScriptedProcess` that "owns" the `ScriptedThread`). - It adds a reference to the `ScriptedProcessInfo` Dictionary, to pass arbitrary user-input to the `ScriptedThread`. This patch also fixes the SWIG bindings methods that call the `ScriptedProcess` and `ScriptedThread` initializers by passing all the arguments to the appropriate `PythonCallable` object. Differential Revision: https://reviews.llvm.org/D112046 Signed-off-by: Med Ismail Bennani --- lldb/bindings/python/python-wrapper.swig | 26 ++++++++----------- .../scripted_process/my_scripted_process.py | 4 +-- .../scripted_process/scripted_process.py | 12 +++++---- .../Python/SWIGPythonBridge.h | 3 ++- .../Python/ScriptedThreadPythonInterface.cpp | 16 +++++++----- .../dummy_scripted_process.py | 4 +-- .../Python/PythonTestSuite.cpp | 3 ++- 7 files changed, 36 insertions(+), 32 deletions(-) diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 5a950e259e993..698d7d12cebca 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -322,16 +322,10 @@ LLDBSwigPythonCreateScriptedProcess PythonObject result = {}; if (arg_info.get().max_positional_args == 2) { - if (args_impl != nullptr) { - error_string.assign("args passed, but __init__ does not take an args dictionary"); - Py_RETURN_NONE; - } - result = pfunc(target_arg, dict); - } else if (arg_info.get().max_positional_args >= 3) { PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); - result = pfunc(target_arg, args_arg, dict); + result = pfunc(target_arg, args_arg); } else { - error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); + error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)"); Py_RETURN_NONE; } @@ -345,7 +339,8 @@ LLDBSwigPythonCreateScriptedThread ( const char *python_class_name, const char *session_dictionary_name, - const lldb::TargetSP& target_sp, + const lldb::ProcessSP& process_sp, + lldb_private::StructuredDataImpl *args_impl, std::string &error_string ) { @@ -363,12 +358,12 @@ LLDBSwigPythonCreateScriptedThread return nullptr; } - // I do not want the SBTarget to be deallocated when going out of scope + // I do not want the SBProcess to be deallocated when going out of scope // because python has ownership of it and will manage memory for this // object by itself - PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBTarget(target_sp))); + PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBProcess(process_sp))); - if (!target_arg.IsAllocated()) + if (!process_arg.IsAllocated()) Py_RETURN_NONE; llvm::Expected arg_info = pfunc.GetArgInfo(); @@ -385,10 +380,11 @@ LLDBSwigPythonCreateScriptedThread } PythonObject result = {}; - if (arg_info.get().max_positional_args == 1) { - result = pfunc(target_arg); + if (arg_info.get().max_positional_args == 2) { + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); + result = pfunc(process_arg, args_arg); } else { - error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); + error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)"); Py_RETURN_NONE; } diff --git a/lldb/examples/python/scripted_process/my_scripted_process.py b/lldb/examples/python/scripted_process/my_scripted_process.py index 224b772845a7f..5e7c10b91533d 100644 --- a/lldb/examples/python/scripted_process/my_scripted_process.py +++ b/lldb/examples/python/scripted_process/my_scripted_process.py @@ -93,8 +93,8 @@ class MyScriptedThread(ScriptedThread): "gs":0x0000000000000000, } - def __init__(self, target): - super().__init__(target) + def __init__(self, process, args): + super().__init__(process, args) def get_thread_id(self) -> int: return 0x19 diff --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/scripted_process/scripted_process.py index 5869ca03e20bd..43ee2d6fffb27 100644 --- a/lldb/examples/python/scripted_process/scripted_process.py +++ b/lldb/examples/python/scripted_process/scripted_process.py @@ -190,18 +190,20 @@ class ScriptedThread: """ @abstractmethod - def __init__(self, target): + def __init__(self, process, args): """ Construct a scripted thread. Args: - target (lldb.SBTarget): The target launching the scripted process. + process (lldb.SBProcess): The scripted process owning this thread. args (lldb.SBStructuredData): A Dictionary holding arbitrary - key/value pairs used by the scripted process. + key/value pairs used by the scripted thread. """ self.target = None + self.process = None self.args = None - if isinstance(target, lldb.SBTarget) and target.IsValid(): - self.target = target + if isinstance(process, lldb.SBProcess) and process.IsValid(): + self.process = process + self.target = process.GetTarget() self.id = None self.name = None diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 81e25128b2c7d..798d947a0a7dc 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -48,7 +48,8 @@ extern "C" void *LLDBSwigPythonCreateScriptedProcess( extern "C" void *LLDBSwigPythonCreateScriptedThread( const char *python_class_name, const char *session_dictionary_name, - const lldb::TargetSP &target_sp, std::string &error_string); + const lldb::ProcessSP &process_sp, StructuredDataImpl *args_impl, + std::string &error_string); extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data); extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data); diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp index 4d6903d567c52..d2c28bc426ee6 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -36,16 +36,20 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( if (class_name.empty()) return {}; - Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); - + ProcessSP process_sp = exe_ctx.GetProcessSP(); + StructuredDataImpl *args_impl = nullptr; + if (args_sp) { + args_impl = new StructuredDataImpl(); + args_impl->SetObjectSP(args_sp); + } std::string error_string; - TargetSP target_sp = exe_ctx.GetTargetSP(); + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); void *ret_val = LLDBSwigPythonCreateScriptedThread( - class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, - error_string); + class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp, + args_impl, error_string); if (!ret_val) return {}; diff --git a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py index 31a52f28c6c00..d7f428d408457 100644 --- a/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py +++ b/lldb/test/API/functionalities/scripted_process/dummy_scripted_process.py @@ -43,8 +43,8 @@ def get_scripted_thread_plugin(self): class DummyScriptedThread(ScriptedThread): - def __init__(self, target): - super().__init__(target) + def __init__(self, process, args): + super().__init__(process, args) def get_thread_id(self) -> int: return 0x19 diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index ea6d6be7dbd5e..7a4b6328a2f54 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -229,7 +229,8 @@ extern "C" void *LLDBSwigPythonCreateScriptedProcess( extern "C" void *LLDBSwigPythonCreateScriptedThread( const char *python_class_name, const char *session_dictionary_name, - const lldb::TargetSP &target_sp, std::string &error_string) { + const lldb::ProcessSP &process_sp, StructuredDataImpl *args_impl, + std::string &error_string) { return nullptr; } From 77b929d6145f1b8be921bce796e5ec03bfef96c9 Mon Sep 17 00:00:00 2001 From: Muhammad Omair Javaid Date: Mon, 11 Oct 2021 07:53:05 +0000 Subject: [PATCH 034/293] [LLDB] Skip TestScriptedProcess on Arm/AArch64 Linux This is failing on Arm and AArch64 Linux buildbots since the time it was comitted. https://lab.llvm.org/buildbot/#/builders/96/builds/12628 Differential Revision: https://reviews.llvm.org/D107585 --- .../API/functionalities/scripted_process/TestScriptedProcess.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 963ba060f949a..9f5b804d91a30 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -43,6 +43,7 @@ def test_python_plugin_package(self): self.expect('script dir(ScriptedProcess)', substrs=["launch"]) + @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) def test_scripted_process_and_scripted_thread(self): """Test that we can launch an lldb scripted process using the SBAPI, check its process ID, read string from memory, check scripted thread From 11ab69d84cedac10be5ce49961d13a2298143bbb Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Wed, 10 Nov 2021 16:11:22 +0000 Subject: [PATCH 035/293] [lldb/test] Update TestScriptedProcess to use skinny corefiles This patch changes the ScriptedProcess test to use a stack-only skinny corefile as a backing store. The corefile is saved as a temporary file at the beginning of the test, and a second target is created for the ScriptedProcess. To do so, we use the SBAPI from the ScriptedProcess' python script to interact with the corefile process. This patch also makes some small adjustments to the other ScriptedProcess scripts to resolve some inconsistencies and removes the raw memory dump that was previously checked in. Differential Revision: https://reviews.llvm.org/D112047 Signed-off-by: Med Ismail Bennani --- .../python/scripted_process/main.stack-dump | Bin 8192 -> 0 bytes .../scripted_process/my_scripted_process.py | 4 +- .../scripted_process/scripted_process.py | 12 +- .../scripted_process/TestScriptedProcess.py | 61 +++++--- .../stack_core_scripted_process.py | 139 ++++++++++++++++++ 5 files changed, 191 insertions(+), 25 deletions(-) delete mode 100644 lldb/examples/python/scripted_process/main.stack-dump create mode 100644 lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py diff --git a/lldb/examples/python/scripted_process/main.stack-dump b/lldb/examples/python/scripted_process/main.stack-dump deleted file mode 100644 index 3df66384f4431dbb7296b964bed918e51a6846a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmcgxeT*AN72kfSX-R|vs?<=9)=5*Eme^}wd>^^ornhJBo!zs~#vhlvYs+T6UfbJS zd!60&#TO1Ww1J|OKZ1xv5dlS|2#QL%w4t;m5K>_e|@Fmx-^C*82=X+#5jCY|NV*|7ocLMJF z1mGF;!@+gXKJ5VvehTpDlYrM^|0Mdi3;lay2K*aD|IVWwi${R(4Ept2#31_jJlb;x z^;(1e&7gnpLjT6lzvu4&d3p5jBKqkVuHWhXFz%p#H=}>QivB%@@=u~&htMxCJq~jEJu?XX2hqQep?~MmzZvxJBF0A-+A)v*4WfS!p?|~ZU*^B+HCMUuxt3ey;(^;C zUU%LG{@ipL+7Qhgw}xAFBm4e;;Nf3_USzIeI^Q*CK%e86LBD4s=(%$z;AL)HxNrA$ z;wI?-U+K!?jLAE-B>(au(s}2fLBCyyjBYt(`jhd?hsf*sKLP(q!~-{j{%gq?eK72y zaS`t>q&;v8`U%_Z{=FCVK8yZk_Epyd-)+dp^tifBhf@!9_V~L_xrBT!VN%w zYU2;5XufnGvd5YK*?K4b4nBG3n@4WX)%tplB)<2T^~S4@(>SKju|RU;{*TT)!}#95 z9pv&g+u{v9$LHsaJfS;vEA(G|4&)Npw}K8yEz z75aJh-1l91@7@RPpIHwDX+LY1`0uo|?;iVx+dk~>9*)~YiRr@v3R>@ZSGR+mb+pgp zhc<^eiT#Z6R`!A8$8r1z-v)oQ$Jq;}b~Vkc)EmF3p1$z(fr?()5tuD)MW@ z3Hg>~Gk1?Fm+hjQvovLfJMqqSq?=pK9o^X9`}%(RO`mm`_n2MWCRo=Y#9MLw+x6eZ z;^Jn^Pe{+^0qNw;`pKt<{GNXI<8B;L`B#zlaU5s3fckha|Nh}W5HFKWa!6=!zs2^t z&w#!S|C2E~K7{ei{C@!D9%A+q8uuZ@l%D;rd=kD{c=V&3zr6}}HueejvvCi$UwH!f zS^M`g+Yd0^5a#KfNWUWo? z*R;;Su*{pq5#wXX)`L3^{$h32kMo@-i%xUs5Vr3pd5Y@B>h4#_deU)Le;;idr}k5o zs<`eizXbfW@BN-8yWD*=@G|gKG0&exeYm|S53z}Fh{`{Re20;*K~D$C(~v{znV+<8 zK>E#yF3}};?L~id63t?pjve>GeqnSs^3d)_3?mwd^N2q}d=Bw6;yJ`FKgjVS_8|@< zW)W+M4~}MSK(S--y?32fEFOMZ|f;{fN&XzJ|!+Dv5FSCiede z@p?ReBoGb6hY^2;_*XFVrfkqnj1Q&>dZ~d0Vygs-xxQs%5I0ZS#uHtT`Na ziRFi-iH;_4vBc=O7?%WM7^&f*k>Oe;Z)nlHR&n%#u33U=mVHXKYG}TUW|ehf2p35Z zh9!l$L@b=#5pL@F02gu6ctjizh2?NGEe^*d*%j#LV(CyKmPnRmnHlD7h@AMg>luPR6pMav~C+nodUq%gp8GteS0WhQXU9Z+XtU$1ZU(aeP$J zDsndM%VtKr{ajK?MH69Ri=UIi(M%#G%<5$>7LvtStc4Dw4@bwFZS(D^8nq&y(<@5~ zO(i4JxICVX3jsfuPDf-hn~BKjL}*OltCl{iI2!MitNfBP4TS_oDetq!rn>|EddQ#T zW4i5V6%u6)xefog@&!Ma6i20$V34?JqDi%Ar&UTyMa^>~Nih>?9_bvmdDAKAL?91V zm33RCT9WmqQELw@E%P#q+9n{U*cuO8;^LW=nqwNKl3&@ZHAgoteoj~6d(7O*<}}RW z${2NXWqhh>X)EKThF&x$TM-%)Wu=n8c>gvenAMd*X^Yfeb1bTlz8bo;t}K`tE%iJ^!j!#f?FmV_Sv zCsGQCYgVqB?``AQ`$h@c` z#OG?dk>}%PzGf&EmmZ5I<;hSYEXn9!nRu1t?~ba5r4cb3%Yb8*99vG!^@^NKB}P+X zTo7s5lpAG}tzS5iajTcl$L$c)@l2Fdv$m4T`*tgK+0n}yElZ)yRI=3-)cI^0rmqkT z1~^&;n^N}D7HK%V5fXDW8ajtX(IjD_t1|<-s<~*BNH%EOR#n4rU@LNeq*C=*12xl}evL#e`pSw@#F%z9e;w_UPM<*eY$t2U*3Hcx#Z9N@;Csjo)X&gCSBxB-~ zFhGt$cpxLj$3?OQ$@#$zu{2p{x;3L=vP4@$lGGjWj%*DLdxL!=TfD=4{vNN`EA<6? z!-1Zy!C~g0Y$_&{9H&YWDPPo`QZ45r2@j7Lu>NdDcEll@f}C$4Yc=92oehO(q(M9p z&EWiFmpoq8vw`Fsk2mL;_mI;Y?YPC(98bX!NS*RHw$SgXm}N6h-Uc~X5vbHWZki&m zTDcW=alc&ESN@~-j@A-ezvhGTm^ySKa@)Rq4hHvb7F-%HR^SzQsKa)_NQHq-FTRNI#(|F(! z9IK`^(iiO>$xcsC$#F3giZs>k2;9)aPbzdIpF<`r{~pdq-z~pSZ+Wbu77Ds}wb% z!$f68ugJDTmZj5Z2L`vR=`Sku#z_rS{Q(*Wer2=2p6d^)h5l}i{(ngBL{Nao?+*mJ Q^MO9jDalpSa!`f;0!D`8qW}N^ diff --git a/lldb/examples/python/scripted_process/my_scripted_process.py b/lldb/examples/python/scripted_process/my_scripted_process.py index 5e7c10b91533d..202ad097d4987 100644 --- a/lldb/examples/python/scripted_process/my_scripted_process.py +++ b/lldb/examples/python/scripted_process/my_scripted_process.py @@ -69,7 +69,7 @@ def get_scripted_thread_plugin(self): class MyScriptedThread(ScriptedThread): - registers = { + register_ctx = { "rax":0x00000000000006e4, "rbx":0x00000001040b6060, "rcx":0x00000001040b2e00, @@ -123,7 +123,7 @@ def __init__(idx, cfa, pc, symbol_ctx): return self.frame_zero[0:0] def get_register_context(self) -> str: - return struct.pack("{}Q".format(len(self.registers)), *self.registers.values()) + return struct.pack("{}Q".format(len(self.register_ctx)), *self.register_ctx.values()) def __lldb_init_module(debugger, dict): diff --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/scripted_process/scripted_process.py index 43ee2d6fffb27..ebb48523805d9 100644 --- a/lldb/examples/python/scripted_process/scripted_process.py +++ b/lldb/examples/python/scripted_process/scripted_process.py @@ -37,7 +37,7 @@ def __init__(self, target, args): self.args = args @abstractmethod - def get_memory_region_containing_address(addr): + def get_memory_region_containing_address(self, addr): """ Get the memory region for the scripted process, containing a specific address. @@ -52,7 +52,7 @@ def get_memory_region_containing_address(addr): pass @abstractmethod - def get_thread_with_id(tid): + def get_thread_with_id(self, tid): """ Get the scripted process thread with a specific ID. Args: @@ -66,7 +66,7 @@ def get_thread_with_id(tid): pass @abstractmethod - def get_registers_for_thread(tid): + def get_registers_for_thread(self, tid): """ Get the register context dictionary for a certain thread of the scripted process. @@ -81,7 +81,7 @@ def get_registers_for_thread(tid): pass @abstractmethod - def read_memory_at_address(addr, size): + def read_memory_at_address(self, addr, size): """ Get a memory buffer from the scripted process at a certain address, of a certain size. @@ -211,7 +211,7 @@ def __init__(self, process, args): self.state = None self.stop_reason = None self.register_info = None - self.register_ctx = [] + self.register_ctx = {} self.frames = [] @abstractmethod @@ -294,7 +294,7 @@ def get_register_info(self): if triple: arch = triple.split('-')[0] if arch == 'x86_64': - self.register_info['sets'] = ['GPR', 'FPU', 'EXC'] + self.register_info['sets'] = ['General Purpose Registers'] self.register_info['registers'] = [ {'name': 'rax', 'bitsize': 64, 'offset': 0, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0, 'dwarf': 0}, {'name': 'rbx', 'bitsize': 64, 'offset': 8, 'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 3, 'dwarf': 3}, diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index 9f5b804d91a30..b8319d722e345 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -2,7 +2,7 @@ Test python scripted process in lldb """ -import os +import os, json, tempfile import lldb from lldbsuite.test.decorators import * @@ -10,14 +10,12 @@ from lldbsuite.test import lldbutil from lldbsuite.test import lldbtest - class ScriptedProcesTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) def setUp(self): TestBase.setUp(self) - self.source = "main.c" def tearDown(self): TestBase.tearDown(self) @@ -43,7 +41,7 @@ def test_python_plugin_package(self): self.expect('script dir(ScriptedProcess)', substrs=["launch"]) - @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) + @skipIf(archs=no_match(['x86_64'])) def test_scripted_process_and_scripted_thread(self): """Test that we can launch an lldb scripted process using the SBAPI, check its process ID, read string from memory, check scripted thread @@ -78,19 +76,29 @@ def test_scripted_process_and_scripted_thread(self): self.assertGreater(thread.GetNumFrames(), 0) frame = thread.GetFrameAtIndex(0) + GPRs = None register_set = frame.registers # Returns an SBValueList. for regs in register_set: - if 'GPR' in regs.name: - registers = regs + if 'general purpose' in regs.name.lower(): + GPRs = regs break - self.assertTrue(registers, "Invalid General Purpose Registers Set") - self.assertEqual(registers.GetNumChildren(), 21) - for idx, reg in enumerate(registers, start=1): + self.assertTrue(GPRs, "Invalid General Purpose Registers Set") + self.assertEqual(GPRs.GetNumChildren(), 21) + for idx, reg in enumerate(GPRs, start=1): self.assertEqual(idx, int(reg.value, 16)) - @skipIfDarwin + def create_stack_skinny_corefile(self, file): + self.build() + target, process, thread, _ = lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.c")) + self.assertTrue(process.IsValid(), "Process is invalid.") + # FIXME: Use SBAPI to save the process corefile. + self.runCmd("process save-core -s stack " + file) + self.assertTrue(os.path.exists(file), "No stack-only corefile found.") + self.assertTrue(self.dbg.DeleteTarget(target), "Couldn't delete target") + @skipUnlessDarwin + @skipIf(archs=no_match(['x86_64'])) def test_launch_scripted_process_stack_frames(self): """Test that we can launch an lldb scripted process from the command line, check its process ID and read string from memory.""" @@ -101,26 +109,45 @@ def test_launch_scripted_process_stack_frames(self): for module in target.modules: if 'a.out' in module.GetFileSpec().GetFilename(): main_module = module + break self.assertTrue(main_module, "Invalid main module.") error = target.SetModuleLoadAddress(main_module, 0) self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.") - scripted_process_example_relpath = ['..','..','..','..','examples','python','scripted_process','my_scripted_process.py'] + scripted_process_example_relpath = 'stack_core_scripted_process.py' + os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' self.runCmd("command script import " + os.path.join(self.getSourceDir(), - *scripted_process_example_relpath)) + scripted_process_example_relpath)) + + corefile_process = None + with tempfile.NamedTemporaryFile() as file: + self.create_stack_skinny_corefile(file.name) + corefile_target = self.dbg.CreateTarget(None) + corefile_process = corefile_target.LoadCore(self.getBuildArtifact(file.name)) + self.assertTrue(corefile_process, PROCESS_IS_VALID) + + structured_data = lldb.SBStructuredData() + structured_data.SetFromJSON(json.dumps({ + "backing_target_idx" : self.dbg.GetIndexOfTarget(corefile_process.GetTarget()) + })) + launch_info = lldb.SBLaunchInfo(None) + launch_info.SetProcessPluginName("ScriptedProcess") + launch_info.SetScriptedProcessClassName("stack_core_scripted_process.StackCoreScriptedProcess") + launch_info.SetScriptedProcessDictionary(structured_data) - process = target.GetProcess() + error = lldb.SBError() + process = target.Launch(launch_info, error) + self.assertTrue(error.Success(), error.GetCString()) self.assertTrue(process, PROCESS_IS_VALID) self.assertEqual(process.GetProcessID(), 42) - self.assertEqual(process.GetNumThreads(), 1) + self.assertEqual(process.GetNumThreads(), 1) thread = process.GetSelectedThread() self.assertTrue(thread, "Invalid thread.") - self.assertEqual(thread.GetThreadID(), 0x19) - self.assertEqual(thread.GetName(), "MyScriptedThread.thread-1") + self.assertEqual(thread.GetName(), "StackCoreScriptedThread.thread-1") - self.assertEqual(thread.GetNumFrames(), 4) + self.assertEqual(thread.GetNumFrames(), 3) frame = thread.GetSelectedFrame() self.assertTrue(frame, "Invalid frame.") self.assertEqual(frame.GetFunctionName(), "bar") diff --git a/lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py b/lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py new file mode 100644 index 0000000000000..7c3e069d22505 --- /dev/null +++ b/lldb/test/API/functionalities/scripted_process/stack_core_scripted_process.py @@ -0,0 +1,139 @@ +import os,struct,signal + +from typing import Any, Dict + +import lldb +from lldb.plugins.scripted_process import ScriptedProcess +from lldb.plugins.scripted_process import ScriptedThread + +class StackCoreScriptedProcess(ScriptedProcess): + def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData): + super().__init__(target, args) + + self.backing_target_idx = args.GetValueForKey("backing_target_idx") + + self.corefile_target = None + self.corefile_process = None + if (self.backing_target_idx and self.backing_target_idx.IsValid()): + if self.backing_target_idx.GetType() == lldb.eStructuredDataTypeInteger: + idx = self.backing_target_idx.GetIntegerValue(42) + if self.backing_target_idx.GetType() == lldb.eStructuredDataTypeString: + idx = int(self.backing_target_idx.GetStringValue(100)) + self.corefile_target = target.GetDebugger().GetTargetAtIndex(idx) + self.corefile_process = self.corefile_target.GetProcess() + + def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo: + mem_region = lldb.SBMemoryRegionInfo() + error = self.corefile_process.GetMemoryRegionInfo(addr, mem_region) + if error.Fail(): + return None + return mem_region + + def get_thread_with_id(self, tid: int): + return {} + + def get_registers_for_thread(self, tid: int): + return {} + + def read_memory_at_address(self, addr: int, size: int) -> lldb.SBData: + data = lldb.SBData() + error = lldb.SBError() + bytes_read = self.corefile_process.ReadMemory(addr, size, error) + + if error.Fail(): + return data + + data.SetData(error, bytes_read, self.corefile_target.GetByteOrder(), + self.corefile_target.GetAddressByteSize()) + + return data + + def get_loaded_images(self): + # TODO: Iterate over corefile_target modules and build a data structure + # from it. + return self.loaded_images + + def get_process_id(self) -> int: + return 42 + + def should_stop(self) -> bool: + return True + + def is_alive(self) -> bool: + return True + + def get_scripted_thread_plugin(self): + return StackCoreScriptedThread.__module__ + "." + StackCoreScriptedThread.__name__ + + +class StackCoreScriptedThread(ScriptedThread): + def __init__(self, process, args): + super().__init__(process, args) + self.backing_target_idx = args.GetValueForKey("backing_target_idx") + + self.corefile_target = None + self.corefile_process = None + if (self.backing_target_idx and self.backing_target_idx.IsValid()): + if self.backing_target_idx.GetType() == lldb.eStructuredDataTypeInteger: + idx = self.backing_target_idx.GetIntegerValue(42) + if self.backing_target_idx.GetType() == lldb.eStructuredDataTypeString: + idx = int(self.backing_target_idx.GetStringValue(100)) + self.corefile_target = self.target.GetDebugger().GetTargetAtIndex(idx) + self.corefile_process = self.corefile_target.GetProcess() + + def get_thread_id(self) -> int: + return 0x19 + + def get_name(self) -> str: + return StackCoreScriptedThread.__name__ + ".thread-1" + + def get_stop_reason(self) -> Dict[str, Any]: + return { "type": lldb.eStopReasonSignal, "data": { + "signal": signal.SIGINT + } } + + def get_stackframes(self): + class ScriptedStackFrame: + def __init__(idx, cfa, pc, symbol_ctx): + self.idx = idx + self.cfa = cfa + self.pc = pc + self.symbol_ctx = symbol_ctx + + + symbol_ctx = lldb.SBSymbolContext() + frame_zero = ScriptedStackFrame(0, 0x42424242, 0x5000000, symbol_ctx) + self.frames.append(frame_zero) + + return self.frame_zero[0:0] + + def get_register_context(self) -> str: + thread = self.corefile_process.GetSelectedThread() + if not thread or thread.GetNumFrames() == 0: + return None + frame = thread.GetFrameAtIndex(0) + + GPRs = None + registerSet = frame.registers # Returns an SBValueList. + for regs in registerSet: + if 'general purpose' in regs.name.lower(): + GPRs = regs + break + + if not GPRs: + return None + + for reg in GPRs: + self.register_ctx[reg.name] = int(reg.value, base=16) + + return struct.pack("{}Q".format(len(self.register_ctx)), *self.register_ctx.values()) + + +def __lldb_init_module(debugger, dict): + if not 'SKIP_SCRIPTED_PROCESS_LAUNCH' in os.environ: + debugger.HandleCommand( + "process launch -C %s.%s" % (__name__, + StackCoreScriptedProcess.__name__)) + else: + print("Name of the class that will manage the scripted process: '%s.%s'" + % (__name__, StackCoreScriptedProcess.__name__)) From ff790af7ab759e0d8888c810acc99dda61da4b22 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Wed, 10 Nov 2021 19:12:32 +0000 Subject: [PATCH 036/293] [lldb/test] Skip TestScriptedProcess when using system's debugserver (NFC) Because TestScriptedProcess.py creates a skinny corefile to provides data to the ScriptedProcess and ScriptedThread, we need to make sure that the debugserver used is not out of tree, to ensure feature availability between debugserver and lldb. This also removes the `SKIP_SCRIPTED_PROCESS_LAUNCH` env variable after each test finish running. Signed-off-by: Med Ismail Bennani --- .../scripted_process/TestScriptedProcess.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py index b8319d722e345..342068328310a 100644 --- a/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py +++ b/lldb/test/API/functionalities/scripted_process/TestScriptedProcess.py @@ -51,8 +51,12 @@ def test_scripted_process_and_scripted_thread(self): target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) - scripted_process_example_relpath = 'dummy_scripted_process.py' os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' + def cleanup(): + del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] + self.addTearDownHook(cleanup) + + scripted_process_example_relpath = 'dummy_scripted_process.py' self.runCmd("command script import " + os.path.join(self.getSourceDir(), scripted_process_example_relpath)) @@ -98,6 +102,7 @@ def create_stack_skinny_corefile(self, file): self.assertTrue(self.dbg.DeleteTarget(target), "Couldn't delete target") @skipUnlessDarwin + @skipIfOutOfTreeDebugserver @skipIf(archs=no_match(['x86_64'])) def test_launch_scripted_process_stack_frames(self): """Test that we can launch an lldb scripted process from the command @@ -115,8 +120,12 @@ def test_launch_scripted_process_stack_frames(self): error = target.SetModuleLoadAddress(main_module, 0) self.assertTrue(error.Success(), "Reloading main module at offset 0 failed.") - scripted_process_example_relpath = 'stack_core_scripted_process.py' os.environ['SKIP_SCRIPTED_PROCESS_LAUNCH'] = '1' + def cleanup(): + del os.environ["SKIP_SCRIPTED_PROCESS_LAUNCH"] + self.addTearDownHook(cleanup) + + scripted_process_example_relpath = 'stack_core_scripted_process.py' self.runCmd("command script import " + os.path.join(self.getSourceDir(), scripted_process_example_relpath)) From c7b4936e807bc6c76e769c9d0382a55843e07a5e Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Wed, 10 Nov 2021 19:53:14 +0000 Subject: [PATCH 037/293] [lldb/Plugins] Refactor ScriptedThread register context creation This patch changes the ScriptedThread class to create the register context when Process::RefreshStateAfterStop is called rather than doing it in the thread constructor. This is required to update the thread state for execution control. Differential Revision: https://reviews.llvm.org/D112167 Signed-off-by: Med Ismail Bennani --- .../Process/scripted/ScriptedProcess.cpp | 8 +- .../Process/scripted/ScriptedProcess.h | 2 +- .../Process/scripted/ScriptedThread.cpp | 83 ++++++++++--------- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index 3b8d37962bcd1..bcf2a2fb48419 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -20,7 +20,6 @@ #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/RegisterContext.h" - #include "lldb/Utility/State.h" #include @@ -300,6 +299,7 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, // actually new threads will get added to new_thread_list. CheckInterpreterAndScriptObject(); + m_thread_plans.ClearThreadCache(); Status error; ScriptLanguage language = m_interpreter->GetLanguage(); @@ -325,6 +325,12 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, return new_thread_list.GetSize(false) > 0; } +void ScriptedProcess::RefreshStateAfterStop() { + // Let all threads recover from stopping and do any clean up based on the + // previous thread state (if any). + m_thread_list.RefreshStateAfterStop(); +} + bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { info.Clear(); info.SetProcessID(GetID()); diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h index 9db3860a10430..85382fe081925 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -77,7 +77,7 @@ class ScriptedProcess : public Process { Status DoDestroy() override; - void RefreshStateAfterStop() override{}; + void RefreshStateAfterStop() override; bool IsAlive() override; diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp index dbe9e5019ff84..1adbd4e7799d1 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -64,32 +64,6 @@ ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error) m_script_object_sp = object_sp; SetID(scripted_thread_interface->GetThreadID()); - - llvm::Optional reg_data = - scripted_thread_interface->GetRegisterContext(); - if (!reg_data) { - error.SetErrorString("Failed to get scripted thread registers data."); - return; - } - - DataBufferSP data_sp( - std::make_shared(reg_data->c_str(), reg_data->size())); - - if (!data_sp->GetByteSize()) { - error.SetErrorString("Failed to copy raw registers data."); - return; - } - - std::shared_ptr reg_ctx_memory = - std::make_shared( - *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); - if (!reg_ctx_memory) { - error.SetErrorString("Failed to create a register context."); - return; - } - - reg_ctx_memory->SetAllRegisterData(data_sp); - m_reg_context_sp = reg_ctx_memory; } ScriptedThread::~ScriptedThread() { DestroyThread(); } @@ -115,21 +89,48 @@ void ScriptedThread::WillResume(StateType resume_state) {} void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); } RegisterContextSP ScriptedThread::GetRegisterContext() { - if (!m_reg_context_sp) { - m_reg_context_sp = std::make_shared( - *this, LLDB_INVALID_ADDRESS); - GetInterface()->GetRegisterContext(); - } + if (!m_reg_context_sp) + m_reg_context_sp = CreateRegisterContextForFrame(nullptr); return m_reg_context_sp; } RegisterContextSP ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { - uint32_t concrete_frame_idx = frame ? frame->GetConcreteFrameIndex() : 0; + const uint32_t concrete_frame_idx = + frame ? frame->GetConcreteFrameIndex() : 0; + + if (concrete_frame_idx) + return GetUnwinder().CreateRegisterContextForFrame(frame); + + lldb::RegisterContextSP reg_ctx_sp; + Status error; + + llvm::Optional reg_data = GetInterface()->GetRegisterContext(); + if (!reg_data) + return GetInterface()->ErrorWithMessage( + LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.", + error, LIBLLDB_LOG_THREAD); + + DataBufferSP data_sp( + std::make_shared(reg_data->c_str(), reg_data->size())); + + if (!data_sp->GetByteSize()) + return GetInterface()->ErrorWithMessage( + LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error, + LIBLLDB_LOG_THREAD); - if (concrete_frame_idx == 0) - return GetRegisterContext(); - return GetUnwinder().CreateRegisterContextForFrame(frame); + std::shared_ptr reg_ctx_memory = + std::make_shared( + *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); + if (!reg_ctx_memory) + return GetInterface()->ErrorWithMessage( + LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error, + LIBLLDB_LOG_THREAD); + + reg_ctx_memory->SetAllRegisterData(data_sp); + m_reg_context_sp = reg_ctx_memory; + + return m_reg_context_sp; } bool ScriptedThread::CalculateStopInfo() { @@ -142,13 +143,15 @@ bool ScriptedThread::CalculateStopInfo() { if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type)) return GetInterface()->ErrorWithMessage( LLVM_PRETTY_FUNCTION, - "Couldn't find value for key 'type' in stop reason dictionary.", error); + "Couldn't find value for key 'type' in stop reason dictionary.", error, + LIBLLDB_LOG_THREAD); StructuredData::Dictionary *data_dict; if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict)) return GetInterface()->ErrorWithMessage( LLVM_PRETTY_FUNCTION, - "Couldn't find value for key 'type' in stop reason dictionary.", error); + "Couldn't find value for key 'type' in stop reason dictionary.", error, + LIBLLDB_LOG_THREAD); switch (stop_reason_type) { case lldb::eStopReasonNone: @@ -175,7 +178,7 @@ bool ScriptedThread::CalculateStopInfo() { llvm::Twine("Unsupported stop reason type (" + llvm::Twine(stop_reason_type) + llvm::Twine(").")) .str(), - error); + error, LIBLLDB_LOG_THREAD); } SetStopInfo(stop_info_sp); @@ -183,9 +186,7 @@ bool ScriptedThread::CalculateStopInfo() { } void ScriptedThread::RefreshStateAfterStop() { - // TODO: Implement - if (m_reg_context_sp) - m_reg_context_sp->InvalidateAllRegisters(); + GetRegisterContext()->InvalidateIfNeeded(/*force=*/false); } lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const { From 4c1056637d176b2b5f3f6601018f2a0acf092ceb Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Sun, 14 Nov 2021 04:42:29 +0100 Subject: [PATCH 038/293] [lldb] Fix ScriptedThread build failure (NFC) This patch replaces `DynamicRegisterInfo.h` include path since the file has been moved upstream in 214054f78a4e40656b17838300dff2f136032172, but merging that change requires cherry-picking multiple patches that could potentially affect the branch stability. Signed-off-by: Med Ismail Bennani --- lldb/source/Plugins/Process/scripted/ScriptedThread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/lldb/source/Plugins/Process/scripted/ScriptedThread.h index cdcd543702a48..069bd4ef654e0 100644 --- a/lldb/source/Plugins/Process/scripted/ScriptedThread.h +++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -13,9 +13,9 @@ #include "ScriptedProcess.h" +#include "Plugins/Process/Utility/DynamicRegisterInfo.h" #include "Plugins/Process/Utility/RegisterContextMemory.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Target//DynamicRegisterInfo.h" #include "lldb/Target/Thread.h" namespace lldb_private { From a7c4c5fe88c4f567439dfcc5405152881af6735d Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Mon, 15 Nov 2021 18:32:40 +0100 Subject: [PATCH 039/293] [lldb/bindings] Update python static bindings (NFC) Signed-off-by: Med Ismail Bennani --- .../python/static-binding/LLDBWrapPython.cpp | 441 +++++++++++++----- lldb/bindings/python/static-binding/lldb.py | 5 + 2 files changed, 339 insertions(+), 107 deletions(-) diff --git a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp index be2ddc3bcab34..b4cc7d531d4d3 100644 --- a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp +++ b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp @@ -2883,100 +2883,101 @@ void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton); #define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptInterpreter_t swig_types[163] #define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t swig_types[164] #define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t swig_types[165] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SearchFilter_t swig_types[166] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SectionLoadList_t swig_types[167] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Section_t swig_types[168] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Settings_t swig_types[169] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameList_t swig_types[170] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameRecognizer_t swig_types[171] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrame_t swig_types[172] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StopInfo_t swig_types[173] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StreamFile_t swig_types[174] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Stream_t swig_types[175] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StringSummaryFormat_t swig_types[176] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StructuredDataPlugin_t swig_types[177] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolContextSpecifier_t swig_types[178] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolFileType_t swig_types[179] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolFile_t swig_types[180] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildrenFrontEnd_t swig_types[181] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildren_t swig_types[182] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SystemRuntime_t swig_types[183] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TargetProperties_t swig_types[184] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Target_t swig_types[185] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadCollection_t swig_types[186] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlanTracer_t swig_types[187] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlan_t swig_types[188] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPostMortemTrace_t swig_types[189] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Thread_t swig_types[190] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Trace_t swig_types[191] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeCategoryImpl_t swig_types[192] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeEnumMemberImpl_t swig_types[193] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFilterImpl_t swig_types[194] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFormatImpl_t swig_types[195] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeImpl_t swig_types[196] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeMemberFunctionImpl_t swig_types[197] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeNameSpecifierImpl_t swig_types[198] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryImpl_t swig_types[199] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryOptions_t swig_types[200] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSystem_t swig_types[201] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Type_t swig_types[202] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnixSignals_t swig_types[203] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindAssembly_t swig_types[204] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindPlan_t swig_types[205] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UserExpression_t swig_types[206] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UtilityFunction_t swig_types[207] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueList_t swig_types[208] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObjectList_t swig_types[209] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObject_t swig_types[210] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Value_t swig_types[211] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__VariableList_t swig_types[212] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Variable_t swig_types[213] -#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Watchpoint_t swig_types[214] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicCheckerFunctions_t swig_types[215] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicLoader_t swig_types[216] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__File_t swig_types[217] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__JITLoaderList_t swig_types[218] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__MemoryRegionInfo_t swig_types[219] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__OperatingSystem_t swig_types[220] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptInterpreter_t swig_types[221] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptedProcessInterface_t swig_types[222] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SectionList_t swig_types[223] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SourceManager_t swig_types[224] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StackFrameRecognizerManager_t swig_types[225] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StackFrame_t swig_types[226] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StructuredDataImpl_t swig_types[227] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SymbolVendor_t swig_types[228] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SystemRuntime_t swig_types[229] -#define SWIGTYPE_p_std__unique_ptrT_lldb_private__TraceCursor_t swig_types[230] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BreakpointLocation_t swig_types[231] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BreakpointSite_t swig_types[232] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Breakpoint_t swig_types[233] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BroadcasterManager_t swig_types[234] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Debugger_t swig_types[235] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Listener_t swig_types[236] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Module_t swig_types[237] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ObjectFileJITDelegate_t swig_types[238] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ObjectFile_t swig_types[239] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__OptionValue_t swig_types[240] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Process_t swig_types[241] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Queue_t swig_types[242] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Section_t swig_types[243] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StackFrame_t swig_types[244] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Stream_t swig_types[245] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StructuredDataPlugin_t swig_types[246] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__SymbolFileType_t swig_types[247] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Target_t swig_types[248] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ThreadPlan_t swig_types[249] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Thread_t swig_types[250] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Type_t swig_types[251] -#define SWIGTYPE_p_std__weak_ptrT_lldb_private__UnixSignals_t swig_types[252] -#define SWIGTYPE_p_unsigned_char swig_types[253] -#define SWIGTYPE_p_unsigned_int swig_types[254] -#define SWIGTYPE_p_unsigned_long_long swig_types[255] -#define SWIGTYPE_p_unsigned_short swig_types[256] -#define SWIGTYPE_p_void swig_types[257] -static swig_type_info *swig_types[259]; -static swig_module_info swig_module = {swig_types, 258, 0, 0, 0, 0}; +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t swig_types[166] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SearchFilter_t swig_types[167] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SectionLoadList_t swig_types[168] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Section_t swig_types[169] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Settings_t swig_types[170] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameList_t swig_types[171] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrameRecognizer_t swig_types[172] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StackFrame_t swig_types[173] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StopInfo_t swig_types[174] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StreamFile_t swig_types[175] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Stream_t swig_types[176] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StringSummaryFormat_t swig_types[177] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__StructuredDataPlugin_t swig_types[178] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolContextSpecifier_t swig_types[179] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolFileType_t swig_types[180] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SymbolFile_t swig_types[181] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildrenFrontEnd_t swig_types[182] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SyntheticChildren_t swig_types[183] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__SystemRuntime_t swig_types[184] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TargetProperties_t swig_types[185] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Target_t swig_types[186] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadCollection_t swig_types[187] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlanTracer_t swig_types[188] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPlan_t swig_types[189] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ThreadPostMortemTrace_t swig_types[190] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Thread_t swig_types[191] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Trace_t swig_types[192] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeCategoryImpl_t swig_types[193] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeEnumMemberImpl_t swig_types[194] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFilterImpl_t swig_types[195] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeFormatImpl_t swig_types[196] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeImpl_t swig_types[197] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeMemberFunctionImpl_t swig_types[198] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeNameSpecifierImpl_t swig_types[199] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryImpl_t swig_types[200] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSummaryOptions_t swig_types[201] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__TypeSystem_t swig_types[202] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Type_t swig_types[203] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnixSignals_t swig_types[204] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindAssembly_t swig_types[205] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UnwindPlan_t swig_types[206] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UserExpression_t swig_types[207] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__UtilityFunction_t swig_types[208] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueList_t swig_types[209] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObjectList_t swig_types[210] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__ValueObject_t swig_types[211] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Value_t swig_types[212] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__VariableList_t swig_types[213] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Variable_t swig_types[214] +#define SWIGTYPE_p_std__shared_ptrT_lldb_private__Watchpoint_t swig_types[215] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicCheckerFunctions_t swig_types[216] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__DynamicLoader_t swig_types[217] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__File_t swig_types[218] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__JITLoaderList_t swig_types[219] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__MemoryRegionInfo_t swig_types[220] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__OperatingSystem_t swig_types[221] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptInterpreter_t swig_types[222] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__ScriptedProcessInterface_t swig_types[223] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SectionList_t swig_types[224] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SourceManager_t swig_types[225] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StackFrameRecognizerManager_t swig_types[226] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StackFrame_t swig_types[227] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__StructuredDataImpl_t swig_types[228] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SymbolVendor_t swig_types[229] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__SystemRuntime_t swig_types[230] +#define SWIGTYPE_p_std__unique_ptrT_lldb_private__TraceCursor_t swig_types[231] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BreakpointLocation_t swig_types[232] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BreakpointSite_t swig_types[233] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Breakpoint_t swig_types[234] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__BroadcasterManager_t swig_types[235] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Debugger_t swig_types[236] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Listener_t swig_types[237] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Module_t swig_types[238] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ObjectFileJITDelegate_t swig_types[239] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ObjectFile_t swig_types[240] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__OptionValue_t swig_types[241] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Process_t swig_types[242] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Queue_t swig_types[243] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Section_t swig_types[244] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StackFrame_t swig_types[245] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Stream_t swig_types[246] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__StructuredDataPlugin_t swig_types[247] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__SymbolFileType_t swig_types[248] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Target_t swig_types[249] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__ThreadPlan_t swig_types[250] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Thread_t swig_types[251] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__Type_t swig_types[252] +#define SWIGTYPE_p_std__weak_ptrT_lldb_private__UnixSignals_t swig_types[253] +#define SWIGTYPE_p_unsigned_char swig_types[254] +#define SWIGTYPE_p_unsigned_int swig_types[255] +#define SWIGTYPE_p_unsigned_long_long swig_types[256] +#define SWIGTYPE_p_unsigned_short swig_types[257] +#define SWIGTYPE_p_void swig_types[258] +static swig_type_info *swig_types[260]; +static swig_module_info swig_module = {swig_types, 259, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -38228,13 +38229,81 @@ SWIGINTERN PyObject *_wrap_new_SBMemoryRegionInfo__SWIG_1(PyObject *SWIGUNUSEDPA } +SWIGINTERN PyObject *_wrap_new_SBMemoryRegionInfo__SWIG_2(PyObject *SWIGUNUSEDPARM(self), Py_ssize_t nobjs, PyObject **swig_obj) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + lldb::addr_t arg2 ; + lldb::addr_t arg3 ; + uint32_t arg4 ; + bool arg5 ; + bool arg6 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + unsigned long long val3 ; + int ecode3 = 0 ; + unsigned int val4 ; + int ecode4 = 0 ; + bool val5 ; + int ecode5 = 0 ; + bool val6 ; + int ecode6 = 0 ; + lldb::SBMemoryRegionInfo *result = 0 ; + + if ((nobjs < 6) || (nobjs > 6)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(swig_obj[0], &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_SBMemoryRegionInfo" "', argument " "1"" of type '" "char const *""'"); + } + arg1 = reinterpret_cast< char * >(buf1); + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_SBMemoryRegionInfo" "', argument " "2"" of type '" "lldb::addr_t""'"); + } + arg2 = static_cast< lldb::addr_t >(val2); + ecode3 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[2], &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_SBMemoryRegionInfo" "', argument " "3"" of type '" "lldb::addr_t""'"); + } + arg3 = static_cast< lldb::addr_t >(val3); + ecode4 = SWIG_AsVal_unsigned_SS_int(swig_obj[3], &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_SBMemoryRegionInfo" "', argument " "4"" of type '" "uint32_t""'"); + } + arg4 = static_cast< uint32_t >(val4); + ecode5 = SWIG_AsVal_bool(swig_obj[4], &val5); + if (!SWIG_IsOK(ecode5)) { + SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_SBMemoryRegionInfo" "', argument " "5"" of type '" "bool""'"); + } + arg5 = static_cast< bool >(val5); + ecode6 = SWIG_AsVal_bool(swig_obj[5], &val6); + if (!SWIG_IsOK(ecode6)) { + SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "new_SBMemoryRegionInfo" "', argument " "6"" of type '" "bool""'"); + } + arg6 = static_cast< bool >(val6); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + result = (lldb::SBMemoryRegionInfo *)new lldb::SBMemoryRegionInfo((char const *)arg1,arg2,arg3,arg4,arg5,arg6); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_lldb__SBMemoryRegionInfo, SWIG_POINTER_NEW | 0 ); + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) delete[] buf1; + return NULL; +} + + SWIGINTERN PyObject *_wrap_new_SBMemoryRegionInfo(PyObject *self, PyObject *args) { Py_ssize_t argc; - PyObject *argv[2] = { + PyObject *argv[7] = { 0 }; - if (!(argc = SWIG_Python_UnpackTuple(args, "new_SBMemoryRegionInfo", 0, 1, argv))) SWIG_fail; + if (!(argc = SWIG_Python_UnpackTuple(args, "new_SBMemoryRegionInfo", 0, 6, argv))) SWIG_fail; --argc; if (argc == 0) { return _wrap_new_SBMemoryRegionInfo__SWIG_0(self, argc, argv); @@ -38247,12 +38316,51 @@ SWIGINTERN PyObject *_wrap_new_SBMemoryRegionInfo(PyObject *self, PyObject *args return _wrap_new_SBMemoryRegionInfo__SWIG_1(self, argc, argv); } } + if (argc == 6) { + int _v; + int res = SWIG_AsCharPtrAndSize(argv[0], 0, NULL, 0); + _v = SWIG_CheckState(res); + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_long_SS_long(argv[1], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_long_SS_long(argv[2], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_unsigned_SS_int(argv[3], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_bool(argv[4], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + { + int res = SWIG_AsVal_bool(argv[5], NULL); + _v = SWIG_CheckState(res); + } + if (_v) { + return _wrap_new_SBMemoryRegionInfo__SWIG_2(self, argc, argv); + } + } + } + } + } + } + } fail: SWIG_Python_RaiseOrModifyTypeError("Wrong number or type of arguments for overloaded function 'new_SBMemoryRegionInfo'.\n" " Possible C/C++ prototypes are:\n" " lldb::SBMemoryRegionInfo::SBMemoryRegionInfo()\n" - " lldb::SBMemoryRegionInfo::SBMemoryRegionInfo(lldb::SBMemoryRegionInfo const &)\n"); + " lldb::SBMemoryRegionInfo::SBMemoryRegionInfo(lldb::SBMemoryRegionInfo const &)\n" + " lldb::SBMemoryRegionInfo::SBMemoryRegionInfo(char const *,lldb::addr_t,lldb::addr_t,uint32_t,bool,bool)\n"); return 0; } @@ -38893,6 +39001,51 @@ SWIGINTERN PyObject *_wrap_SBMemoryRegionInfoList_GetSize(PyObject *SWIGUNUSEDPA } +SWIGINTERN PyObject *_wrap_SBMemoryRegionInfoList_GetMemoryRegionContainingAddress(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + lldb::SBMemoryRegionInfoList *arg1 = (lldb::SBMemoryRegionInfoList *) 0 ; + lldb::addr_t arg2 ; + lldb::SBMemoryRegionInfo *arg3 = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned long long val2 ; + int ecode2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + PyObject *swig_obj[3] ; + bool result; + + if (!SWIG_Python_UnpackTuple(args, "SBMemoryRegionInfoList_GetMemoryRegionContainingAddress", 3, 3, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBMemoryRegionInfoList, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBMemoryRegionInfoList_GetMemoryRegionContainingAddress" "', argument " "1"" of type '" "lldb::SBMemoryRegionInfoList *""'"); + } + arg1 = reinterpret_cast< lldb::SBMemoryRegionInfoList * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_long_SS_long(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SBMemoryRegionInfoList_GetMemoryRegionContainingAddress" "', argument " "2"" of type '" "lldb::addr_t""'"); + } + arg2 = static_cast< lldb::addr_t >(val2); + res3 = SWIG_ConvertPtr(swig_obj[2], &argp3, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "SBMemoryRegionInfoList_GetMemoryRegionContainingAddress" "', argument " "3"" of type '" "lldb::SBMemoryRegionInfo &""'"); + } + if (!argp3) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "SBMemoryRegionInfoList_GetMemoryRegionContainingAddress" "', argument " "3"" of type '" "lldb::SBMemoryRegionInfo &""'"); + } + arg3 = reinterpret_cast< lldb::SBMemoryRegionInfo * >(argp3); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + result = (bool)(arg1)->GetMemoryRegionContainingAddress(arg2,*arg3); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_SBMemoryRegionInfoList_GetMemoryRegionAtIndex(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; lldb::SBMemoryRegionInfoList *arg1 = (lldb::SBMemoryRegionInfoList *) 0 ; @@ -80475,7 +80628,6 @@ LLDBSwigPythonCreateScriptedProcess if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; - PyErr_Cleaner py_err_cleaner(true); auto dict = PythonModule::MainModule().ResolveName(session_dictionary_name); @@ -80510,16 +80662,69 @@ LLDBSwigPythonCreateScriptedProcess PythonObject result = {}; if (arg_info.get().max_positional_args == 2) { - if (args_impl != nullptr) { - error_string.assign("args passed, but __init__ does not take an args dictionary"); - Py_RETURN_NONE; - } - result = pfunc(target_arg, dict); - } else if (arg_info.get().max_positional_args >= 3) { PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); - result = pfunc(target_arg, args_arg, dict); + result = pfunc(target_arg, args_arg); } else { - error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); + error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)"); + Py_RETURN_NONE; + } + + if (result.IsAllocated()) + return result.release(); + Py_RETURN_NONE; +} + +SWIGEXPORT void* +LLDBSwigPythonCreateScriptedThread +( + const char *python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP& process_sp, + lldb_private::StructuredDataImpl *args_impl, + std::string &error_string +) +{ + if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) + Py_RETURN_NONE; + + PyErr_Cleaner py_err_cleaner(true); + + auto dict = PythonModule::MainModule().ResolveName(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary(python_class_name, dict); + + if (!pfunc.IsAllocated()) { + error_string.append("could not find script class: "); + error_string.append(python_class_name); + return nullptr; + } + + // I do not want the SBProcess to be deallocated when going out of scope + // because python has ownership of it and will manage memory for this + // object by itself + PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBProcess(process_sp))); + + if (!process_arg.IsAllocated()) + Py_RETURN_NONE; + + llvm::Expected arg_info = pfunc.GetArgInfo(); + if (!arg_info) { + llvm::handleAllErrors( + arg_info.takeError(), + [&](PythonException &E) { + error_string.append(E.ReadBacktrace()); + }, + [&](const llvm::ErrorInfoBase &E) { + error_string.append(E.message()); + }); + Py_RETURN_NONE; + } + + PythonObject result = {}; + if (arg_info.get().max_positional_args == 2) { + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); + result = pfunc(process_arg, args_arg); + } else { + error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)"); Py_RETURN_NONE; } @@ -81105,6 +81310,22 @@ LLDBSWIGPython_CastPyObjectToSBValue return sb_ptr; } +SWIGEXPORT void* +LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo +( + PyObject* data +) +{ + lldb::SBMemoryRegionInfo* sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + SWIGEXPORT bool LLDBSwigPythonCallCommand ( @@ -82891,7 +83112,8 @@ static PyMethodDef SwigMethods[] = { { "SBListener_swiginit", SBListener_swiginit, METH_VARARGS, NULL}, { "new_SBMemoryRegionInfo", _wrap_new_SBMemoryRegionInfo, METH_VARARGS, "\n" "SBMemoryRegionInfo()\n" - "new_SBMemoryRegionInfo(SBMemoryRegionInfo rhs) -> SBMemoryRegionInfo\n" + "SBMemoryRegionInfo(SBMemoryRegionInfo rhs)\n" + "new_SBMemoryRegionInfo(char const * name, lldb::addr_t begin, lldb::addr_t end, uint32_t permissions, bool mapped, bool stack_memory) -> SBMemoryRegionInfo\n" ""}, { "delete_SBMemoryRegionInfo", _wrap_delete_SBMemoryRegionInfo, METH_O, "delete_SBMemoryRegionInfo(SBMemoryRegionInfo self)"}, { "SBMemoryRegionInfo_Clear", _wrap_SBMemoryRegionInfo_Clear, METH_O, "SBMemoryRegionInfo_Clear(SBMemoryRegionInfo self)"}, @@ -82946,6 +83168,7 @@ static PyMethodDef SwigMethods[] = { ""}, { "delete_SBMemoryRegionInfoList", _wrap_delete_SBMemoryRegionInfoList, METH_O, "delete_SBMemoryRegionInfoList(SBMemoryRegionInfoList self)"}, { "SBMemoryRegionInfoList_GetSize", _wrap_SBMemoryRegionInfoList_GetSize, METH_O, "SBMemoryRegionInfoList_GetSize(SBMemoryRegionInfoList self) -> uint32_t"}, + { "SBMemoryRegionInfoList_GetMemoryRegionContainingAddress", _wrap_SBMemoryRegionInfoList_GetMemoryRegionContainingAddress, METH_VARARGS, "SBMemoryRegionInfoList_GetMemoryRegionContainingAddress(SBMemoryRegionInfoList self, lldb::addr_t addr, SBMemoryRegionInfo region_info) -> bool"}, { "SBMemoryRegionInfoList_GetMemoryRegionAtIndex", _wrap_SBMemoryRegionInfoList_GetMemoryRegionAtIndex, METH_VARARGS, "SBMemoryRegionInfoList_GetMemoryRegionAtIndex(SBMemoryRegionInfoList self, uint32_t idx, SBMemoryRegionInfo region_info) -> bool"}, { "SBMemoryRegionInfoList_Append", _wrap_SBMemoryRegionInfoList_Append, METH_VARARGS, "\n" "SBMemoryRegionInfoList_Append(SBMemoryRegionInfoList self, SBMemoryRegionInfo region)\n" @@ -86103,6 +86326,7 @@ static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__RegularExpression static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t = {"_p_std__shared_ptrT_lldb_private__ScriptInterpreter_t", "std::shared_ptr< lldb_private::ScriptInterpreter > *|lldb::ScriptInterpreterSP *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t = {"_p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t", "lldb::ScriptSummaryFormatSP *|std::shared_ptr< lldb_private::ScriptSummaryFormat > *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t = {"_p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t", "std::shared_ptr< lldb_private::ScriptedSyntheticChildren > *|lldb::ScriptedSyntheticChildrenSP *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t = {"_p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t", "lldb::ScriptedThreadInterfaceSP *|std::shared_ptr< lldb_private::ScriptedThreadInterface > *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__SearchFilter_t = {"_p_std__shared_ptrT_lldb_private__SearchFilter_t", "std::shared_ptr< lldb_private::SearchFilter > *|lldb::SearchFilterSP *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__SectionLoadList_t = {"_p_std__shared_ptrT_lldb_private__SectionLoadList_t", "std::shared_ptr< lldb_private::SectionLoadList > *|lldb::SectionLoadListSP *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_std__shared_ptrT_lldb_private__Section_t = {"_p_std__shared_ptrT_lldb_private__Section_t", "lldb::SectionSP *|std::shared_ptr< lldb_private::Section > *", 0, 0, (void*)0, 0}; @@ -86363,6 +86587,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t, &_swigt__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t, &_swigt__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t, + &_swigt__p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t, &_swigt__p_std__shared_ptrT_lldb_private__SearchFilter_t, &_swigt__p_std__shared_ptrT_lldb_private__SectionLoadList_t, &_swigt__p_std__shared_ptrT_lldb_private__Section_t, @@ -86623,6 +86848,7 @@ static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__RegularExpression static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__SearchFilter_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__SearchFilter_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__SectionLoadList_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__SectionLoadList_t, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_std__shared_ptrT_lldb_private__Section_t[] = { {&_swigt__p_std__shared_ptrT_lldb_private__Section_t, 0, 0, 0},{0, 0, 0, 0}}; @@ -86883,6 +87109,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_std__shared_ptrT_lldb_private__ScriptInterpreter_t, _swigc__p_std__shared_ptrT_lldb_private__ScriptSummaryFormat_t, _swigc__p_std__shared_ptrT_lldb_private__ScriptedSyntheticChildren_t, + _swigc__p_std__shared_ptrT_lldb_private__ScriptedThreadInterface_t, _swigc__p_std__shared_ptrT_lldb_private__SearchFilter_t, _swigc__p_std__shared_ptrT_lldb_private__SectionLoadList_t, _swigc__p_std__shared_ptrT_lldb_private__Section_t, diff --git a/lldb/bindings/python/static-binding/lldb.py b/lldb/bindings/python/static-binding/lldb.py index 910dfaec69f19..c6dcbb34b2c72 100644 --- a/lldb/bindings/python/static-binding/lldb.py +++ b/lldb/bindings/python/static-binding/lldb.py @@ -7065,6 +7065,7 @@ def __init__(self, *args): r""" __init__(SBMemoryRegionInfo self) -> SBMemoryRegionInfo __init__(SBMemoryRegionInfo self, SBMemoryRegionInfo rhs) -> SBMemoryRegionInfo + __init__(SBMemoryRegionInfo self, char const * name, lldb::addr_t begin, lldb::addr_t end, uint32_t permissions, bool mapped, bool stack_memory) -> SBMemoryRegionInfo """ _lldb.SBMemoryRegionInfo_swiginit(self, _lldb.new_SBMemoryRegionInfo(*args)) __swig_destroy__ = _lldb.delete_SBMemoryRegionInfo @@ -7182,6 +7183,10 @@ def GetSize(self): r"""GetSize(SBMemoryRegionInfoList self) -> uint32_t""" return _lldb.SBMemoryRegionInfoList_GetSize(self) + def GetMemoryRegionContainingAddress(self, addr, region_info): + r"""GetMemoryRegionContainingAddress(SBMemoryRegionInfoList self, lldb::addr_t addr, SBMemoryRegionInfo region_info) -> bool""" + return _lldb.SBMemoryRegionInfoList_GetMemoryRegionContainingAddress(self, addr, region_info) + def GetMemoryRegionAtIndex(self, idx, region_info): r"""GetMemoryRegionAtIndex(SBMemoryRegionInfoList self, uint32_t idx, SBMemoryRegionInfo region_info) -> bool""" return _lldb.SBMemoryRegionInfoList_GetMemoryRegionAtIndex(self, idx, region_info) From e87c62d7aef1e441fca8c64e180e5dc8131cdc20 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Tue, 16 Nov 2021 19:06:13 +0100 Subject: [PATCH 040/293] [lldb] Use getters to retrieve Swift module search paths A corresponding PR on apple/swift makes module search paths only accessible using getters to only expose mutability through setters which can make sure that we maintain a module to module path lookup table. --- .../TypeSystem/Swift/SwiftASTContext.cpp | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index b0fcfaf192720..a579cba1ff0be 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -2115,9 +2115,9 @@ ProcessModule(ModuleSP module_sp, std::string m_description, const auto &opts = invocation.getSearchPathOptions(); module_search_paths.insert(module_search_paths.end(), - opts.ImportSearchPaths.begin(), - opts.ImportSearchPaths.end()); - for (const auto &fwsp : opts.FrameworkSearchPaths) + opts.getImportSearchPaths().begin(), + opts.getImportSearchPaths().end()); + for (const auto &fwsp : opts.getFrameworkSearchPaths()) framework_search_paths.push_back({fwsp.Path, fwsp.IsSystem}); auto &clang_opts = invocation.getClangImporterOptions().ExtraArgs; for (const std::string &arg : clang_opts) { @@ -2698,8 +2698,8 @@ void SwiftASTContext::InitializeSearchPathOptions( } llvm::StringMap processed; - std::vector &invocation_import_paths = - invocation.getSearchPathOptions().ImportSearchPaths; + std::vector invocation_import_paths( + invocation.getSearchPathOptions().getImportSearchPaths()); // Add all deserialized paths to the map. for (const auto &path : invocation_import_paths) processed.insert({path, false}); @@ -2710,11 +2710,14 @@ void SwiftASTContext::InitializeSearchPathOptions( if (it_notseen.second) invocation_import_paths.push_back(path); } + invocation.getSearchPathOptions().setImportSearchPaths( + invocation_import_paths); // This preserves the IsSystem bit, but deduplicates entries ignoring it. processed.clear(); - auto &invocation_framework_paths = - invocation.getSearchPathOptions().FrameworkSearchPaths; + std::vector + invocation_framework_paths( + invocation.getSearchPathOptions().getFrameworkSearchPaths()); // Add all deserialized paths to the map. for (const auto &path : invocation_framework_paths) processed.insert({path.Path, path.IsSystem}); @@ -2725,6 +2728,8 @@ void SwiftASTContext::InitializeSearchPathOptions( if (it_notseen.second) invocation_framework_paths.push_back({path.first, path.second}); } + invocation.getSearchPathOptions().setFrameworkSearchPaths( + invocation_framework_paths); } namespace lldb_private { @@ -3384,7 +3389,8 @@ swift::ASTContext *SwiftASTContext::GetASTContext() { std::string moduleCachePath = ""; std::unique_ptr clang_importer_ap; auto &clang_importer_options = GetClangImporterOptions(); - if (!m_ast_context_ap->SearchPathOpts.SDKPath.empty() || TargetHasNoSDK()) { + if (!m_ast_context_ap->SearchPathOpts.getSDKPath().empty() || + TargetHasNoSDK()) { if (!clang_importer_options.OverrideResourceDir.empty()) { // Create the DWARFImporterDelegate. const auto &props = ModuleList::GetGlobalModuleListProperties(); @@ -3442,7 +3448,7 @@ swift::ASTContext *SwiftASTContext::GetASTContext() { if (!sdk_version) { auto SDKInfoOrErr = clang::parseDarwinSDKInfo( *llvm::vfs::getRealFileSystem(), - m_ast_context_ap->SearchPathOpts.SDKPath); + m_ast_context_ap->SearchPathOpts.getSDKPath()); if (SDKInfoOrErr) { if (auto SDKInfo = *SDKInfoOrErr) sdk_version = swift::getTargetSDKVersion(*SDKInfo, triple); @@ -3743,16 +3749,17 @@ swift::ModuleDecl *SwiftASTContext::GetModule(const FileSpec &module_spec, std::string module_directory(module_spec.GetDirectory().GetCString()); bool add_search_path = true; - for (auto path : ast->SearchPathOpts.ImportSearchPaths) { + for (auto path : ast->SearchPathOpts.getImportSearchPaths()) { if (path == module_directory) { add_search_path = false; break; } } // Add the search path if needed so we can find the module by basename. - if (add_search_path) - ast->SearchPathOpts.ImportSearchPaths.push_back( - std::move(module_directory)); + if (add_search_path) { + ast->addSearchPath(module_directory, /*isFramework=*/false, + /*isSystem=*/false); + } typedef swift::Located ModuleNameSpec; llvm::StringRef module_basename_sref(module_basename.GetCString()); @@ -3950,7 +3957,8 @@ void SwiftASTContext::LoadModule(swift::ModuleDecl *swift_module, std::vector uniqued_paths; for (const auto &framework_search_dir : - swift_module->getASTContext().SearchPathOpts.FrameworkSearchPaths) { + swift_module->getASTContext() + .SearchPathOpts.getFrameworkSearchPaths()) { // The framework search dir as it comes from the AST context // often has duplicate entries, don't try to load along the // same path twice. @@ -5145,8 +5153,9 @@ void SwiftASTContext::LogConfiguration() { HEALTH_LOG_PRINTF(" Architecture : %s", m_ast_context_ap->LangOpts.Target.getTriple().c_str()); - HEALTH_LOG_PRINTF(" SDK path : %s", - m_ast_context_ap->SearchPathOpts.SDKPath.c_str()); + HEALTH_LOG_PRINTF( + " SDK path : %s", + m_ast_context_ap->SearchPathOpts.getSDKPath().str().c_str()); HEALTH_LOG_PRINTF( " Runtime resource path : %s", m_ast_context_ap->SearchPathOpts.RuntimeResourcePath.c_str()); @@ -5161,26 +5170,29 @@ void SwiftASTContext::LogConfiguration() { HEALTH_LOG_PRINTF(" Runtime library import paths : (%llu items)", (unsigned long long)m_ast_context_ap->SearchPathOpts - .RuntimeLibraryImportPaths.size()); + .getRuntimeLibraryImportPaths() + .size()); for (const auto &runtime_import_path : - m_ast_context_ap->SearchPathOpts.RuntimeLibraryImportPaths) { + m_ast_context_ap->SearchPathOpts.getRuntimeLibraryImportPaths()) { HEALTH_LOG_PRINTF(" %s", runtime_import_path.c_str()); } HEALTH_LOG_PRINTF(" Framework search paths : (%llu items)", (unsigned long long)m_ast_context_ap->SearchPathOpts - .FrameworkSearchPaths.size()); + .getFrameworkSearchPaths() + .size()); for (const auto &framework_search_path : - m_ast_context_ap->SearchPathOpts.FrameworkSearchPaths) { + m_ast_context_ap->SearchPathOpts.getFrameworkSearchPaths()) { HEALTH_LOG_PRINTF(" %s", framework_search_path.Path.c_str()); } HEALTH_LOG_PRINTF(" Import search paths : (%llu items)", (unsigned long long)m_ast_context_ap->SearchPathOpts - .ImportSearchPaths.size()); - for (std::string &import_search_path : - m_ast_context_ap->SearchPathOpts.ImportSearchPaths) { + .getImportSearchPaths() + .size()); + for (const std::string &import_search_path : + m_ast_context_ap->SearchPathOpts.getImportSearchPaths()) { HEALTH_LOG_PRINTF(" %s", import_search_path.c_str()); } From 854ae3c8bda735a2b928450824a79ba79849ff87 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 16 Nov 2021 10:07:33 -0800 Subject: [PATCH 041/293] Coro: Remove coro_end and coro_suspend_retcon in private unprocessed functions We might emit functions that are private and never called. The coro split pass only processes functions that might be called. Remove intrinsics that we can't generate code for. rdar://84619859 --- .../lib/Transforms/Coroutines/CoroCleanup.cpp | 9 ++- .../Coroutines/coro-retcon-once-private.ll | 55 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp index 6c2a3d8eafae4..a8301ea6bbaf8 100644 --- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -55,7 +55,8 @@ static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn) { bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) { bool Changed = false; - + bool IsPrivateAndUnprocessed = F.hasFnAttribute(CORO_PRESPLIT_ATTR) && + F.hasLocalLinkage(); for (auto IB = inst_begin(F), E = inst_end(F); IB != E;) { Instruction &I = *IB++; if (auto *II = dyn_cast(&I)) { @@ -84,6 +85,12 @@ bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) { case Intrinsic::coro_subfn_addr: lowerSubFn(Builder, cast(II)); break; + case Intrinsic::coro_end: + case Intrinsic::coro_suspend_retcon: + if (IsPrivateAndUnprocessed) { + II->replaceAllUsesWith(UndefValue::get(II->getType())); + } else continue; + break; case Intrinsic::coro_async_size_replace: auto *Target = cast( cast(II->getArgOperand(0)->stripPointerCasts()) diff --git a/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll new file mode 100644 index 0000000000000..bca738406f455 --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-retcon-once-private.ll @@ -0,0 +1,55 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -enable-coroutines -passes='default' -S | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.12.0" + +; CHECK: define internal { i8*, i32 } @f(i8* %buffer, i32* %array) +; CHECK-NEXT: entry: +; CHECK-NEXT: unreachable + +define internal {i8*, i32} @f(i8* %buffer, i32* %array) { +entry: + %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, i8* %buffer, i8* bitcast (void (i8*, i1)* @prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*)) + %hdl = call i8* @llvm.coro.begin(token %id, i8* null) + %load = load i32, i32* %array + %load.pos = icmp sgt i32 %load, 0 + br i1 %load.pos, label %pos, label %neg + +pos: + %unwind0 = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 %load) + br i1 %unwind0, label %cleanup, label %pos.cont + +pos.cont: + store i32 0, i32* %array, align 4 + br label %cleanup + +neg: + %unwind1 = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 0) + br i1 %unwind1, label %cleanup, label %neg.cont + +neg.cont: + store i32 10, i32* %array, align 4 + br label %cleanup + +cleanup: + call i1 @llvm.coro.end(i8* %hdl, i1 0) + unreachable +} + +; Unfortunately, we don't seem to fully optimize this right now due +; to some sort of phase-ordering thing. + +declare token @llvm.coro.id.retcon.once(i32, i32, i8*, i8*, i8*, i8*) +declare i8* @llvm.coro.begin(token, i8*) +declare i1 @llvm.coro.suspend.retcon.i1(...) +declare i1 @llvm.coro.end(i8*, i1) +declare i8* @llvm.coro.prepare.retcon(i8*) + +declare void @prototype(i8*, i1 zeroext) + +declare noalias i8* @allocate(i32 %size) +declare void @deallocate(i8* %ptr) + +declare void @print(i32) + From 603041911fee7be4996d8f193ef3a536a6b7cbdf Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 16 Nov 2021 10:51:29 -0800 Subject: [PATCH 042/293] Revert "[lldb] Fix that the embedded Python REPL crashes if it receives SIGINT" --- .../Python/ScriptInterpreterPython.cpp | 59 --------------- .../sigint/TestIOHandlerPythonREPLSigint.py | 73 ------------------- 2 files changed, 132 deletions(-) delete mode 100644 lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index b918706e93c36..7ad63722c31cf 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -1050,23 +1050,6 @@ void ScriptInterpreterPythonImpl::ExecuteInterpreterLoop() { } bool ScriptInterpreterPythonImpl::Interrupt() { - // PyErr_SetInterrupt was introduced in 3.2. -#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3) - // If the interpreter isn't evaluating any Python at the moment then return - // false to signal that this function didn't handle the interrupt and the - // next component should try handling it. - if (!IsExecutingPython()) - return false; - - // Tell Python that it should pretend to have received a SIGINT. - PyErr_SetInterrupt(); - // PyErr_SetInterrupt has no way to return an error so we can only pretend the - // signal got successfully handled and return true. - // Python 3.10 introduces PyErr_SetInterruptEx that could return an error, but - // the error handling is limited to checking the arguments which would be - // just our (hardcoded) input signal code SIGINT, so that's not useful at all. - return true; -#else Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SCRIPT)); if (IsExecutingPython()) { @@ -1088,7 +1071,6 @@ bool ScriptInterpreterPythonImpl::Interrupt() { "ScriptInterpreterPythonImpl::Interrupt() python code not running, " "can't interrupt"); return false; -#endif } bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn( @@ -3294,28 +3276,6 @@ ScriptInterpreterPythonImpl::AcquireInterpreterLock() { return py_lock; } -namespace { -/// Saves the current signal handler for the specified signal and restores -/// it at the end of the current scope. -struct RestoreSignalHandlerScope { - /// The signal handler. - struct sigaction m_prev_handler; - int m_signal_code; - RestoreSignalHandlerScope(int signal_code) : m_signal_code(signal_code) { - // Initialize sigaction to their default state. - std::memset(&m_prev_handler, 0, sizeof(m_prev_handler)); - // Don't install a new handler, just read back the old one. - struct sigaction *new_handler = nullptr; - int signal_err = ::sigaction(m_signal_code, new_handler, &m_prev_handler); - lldbassert(signal_err == 0 && "sigaction failed to read handler"); - } - ~RestoreSignalHandlerScope() { - int signal_err = ::sigaction(m_signal_code, &m_prev_handler, nullptr); - lldbassert(signal_err == 0 && "sigaction failed to restore old handler"); - } -}; -} // namespace - void ScriptInterpreterPythonImpl::InitializePrivate() { if (g_initialized) return; @@ -3351,25 +3311,6 @@ void ScriptInterpreterPythonImpl::InitializePrivate() { "lldb.embedded_interpreter; from " "lldb.embedded_interpreter import run_python_interpreter; " "from lldb.embedded_interpreter import run_one_line"); - -#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 2) || (PY_MAJOR_VERSION > 3) - // Python will not just overwrite its internal SIGINT handler but also the - // one from the process. Backup the current SIGINT handler to prevent that - // Python deletes it. - RestoreSignalHandlerScope save_sigint(SIGINT); - - // Setup a default SIGINT signal handler that works the same way as the - // normal Python REPL signal handler which raises a KeyboardInterrupt. - // Also make sure to not pollute the user's REPL with the signal module nor - // our utility function. - PyRun_SimpleString("def lldb_setup_sigint_handler():\n" - " import signal;\n" - " def signal_handler(sig, frame):\n" - " raise KeyboardInterrupt()\n" - " signal.signal(signal.SIGINT, signal_handler);\n" - "lldb_setup_sigint_handler();\n" - "del lldb_setup_sigint_handler\n"); -#endif } void ScriptInterpreterPythonImpl::AddToSysPath(AddLocation location, diff --git a/lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py b/lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py deleted file mode 100644 index 7b01919d39526..0000000000000 --- a/lldb/test/API/iohandler/sigint/TestIOHandlerPythonREPLSigint.py +++ /dev/null @@ -1,73 +0,0 @@ -""" -Test sending SIGINT to the embedded Python REPL. -""" - -import os - -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test.lldbpexpect import PExpectTest - -class TestCase(PExpectTest): - - mydir = TestBase.compute_mydir(__file__) - - def start_python_repl(self): - """ Starts up the embedded Python REPL.""" - self.launch() - # Start the embedded Python REPL via the 'script' command. - self.child.send("script -l python --\n") - # Wait for the Python REPL prompt. - self.child.expect(">>>") - - # PExpect uses many timeouts internally and doesn't play well - # under ASAN on a loaded machine.. - @skipIfAsan - def test_while_evaluating_code(self): - """ Tests SIGINT handling while Python code is being evaluated.""" - self.start_python_repl() - - # Start a long-running command that we try to abort with SIGINT. - # Note that we dont actually wait 10000s in this code as pexpect or - # lit will kill the test way before that. - self.child.send("import time; print('running' + 'now'); time.sleep(10000);\n") - - # Make sure the command is actually being evaluated at the moment by - # looking at the string that the command is printing. - # Don't check for a needle that also occurs in the program itself to - # prevent that echoing will make this check pass unintentionally. - self.child.expect("runningnow") - - # Send SIGINT to the LLDB process. - self.child.sendintr() - - # This should get transformed to a KeyboardInterrupt which is the same - # behaviour as the standalone Python REPL. It should also interrupt - # the evaluation of our sleep statement. - self.child.expect("KeyboardInterrupt") - # Send EOF to quit the Python REPL. - self.child.sendeof() - - self.quit() - - # PExpect uses many timeouts internally and doesn't play well - # under ASAN on a loaded machine.. - @skipIfAsan - # FIXME: On Linux the Python code that reads from stdin seems to block until - # it has finished reading a line before handling any queued signals. - @skipIfLinux - def test_while_waiting_on_input(self): - """ Tests SIGINT handling while the REPL is waiting on input from - stdin.""" - self.start_python_repl() - - # Send SIGINT to the LLDB process. - self.child.sendintr() - # This should get transformed to a KeyboardInterrupt which is the same - # behaviour as the standalone Python REPL. - self.child.expect("KeyboardInterrupt") - # Send EOF to quit the Python REPL. - self.child.sendeof() - - self.quit() From 75bf77a06c07b379fe1d6f4bd08b0cc0213166d3 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Wed, 6 Oct 2021 19:43:40 +0000 Subject: [PATCH 043/293] [clang][Driver] Make multiarch output file basenames reproducible When building a multiarch MachO binary, previously the intermediate output file names would contain random characters. On macOS this filename, since it's used when linking, ended up being used as a stable-ish identifier for the adhoc codesignature of the binary, leading to non-reproducible binaries. This change uses the architecture, when available, to create a stable, but unique, basename for the file. Differential Revision: https://reviews.llvm.org/D111269 (cherry picked from commit 17386cb4dc89afad62623b9bc08516b99b9c6df7) --- clang/lib/Driver/Driver.cpp | 8 +++++++- clang/test/Driver/darwin-dsymutil.c | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 8685d4a3ab849..65b48a4f538a4 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4956,7 +4956,13 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, return ""; } } else { - TmpName = GetTemporaryPath(Split.first, Suffix); + if (MultipleArchs && !BoundArch.empty()) { + TmpName = GetTemporaryDirectory(Split.first); + llvm::sys::path::append(TmpName, + Split.first + "-" + BoundArch + "." + Suffix); + } else { + TmpName = GetTemporaryPath(Split.first, Suffix); + } } return C.addTempFile(C.getArgs().MakeArgString(TmpName)); } diff --git a/clang/test/Driver/darwin-dsymutil.c b/clang/test/Driver/darwin-dsymutil.c index 8cdb2f3cbf644..922b5d27f4389 100644 --- a/clang/test/Driver/darwin-dsymutil.c +++ b/clang/test/Driver/darwin-dsymutil.c @@ -42,6 +42,16 @@ // CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Linker", inputs: [{{.*}}], output: "[[outfile]]" // CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Dsymutil", inputs: ["[[outfile]]"], output: "[[dsymfile]]" +// Check output name derivation for multiple -arch options. +// +// RUN: %clang -target x86_64-apple-darwin10 \ +// RUN: -arch x86_64 -arch arm64 -ccc-print-bindings %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-MULTIARCH-OUTPUT-NAME < %t %s +// +// CHECK-MULTIARCH-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Linker", inputs: ["{{.*}}{{/|\\}}darwin-dsymutil-x86_64.o"], output: "{{.*}}{{/|\\}}darwin-dsymutil-x86_64.out" +// CHECK-MULTIARCH-OUTPUT-NAME: "arm64-apple-darwin10" - "darwin::Linker", inputs: ["{{.*}}{{/|\\}}darwin-dsymutil-arm64.o"], output: "{{.*}}{{/|\\}}darwin-dsymutil-arm64.out" +// CHECK-MULTIARCH-OUTPUT-NAME: "arm64-apple-darwin10" - "darwin::Lipo", inputs: ["{{.*}}{{/|\\}}darwin-dsymutil-x86_64.out", "{{.*}}{{/|\\}}darwin-dsymutil-arm64.out"], output: "a.out" + // Check that we only use dsymutil when needed. // // RUN: touch %t.o From b9226b08fee13e87ce03316f8f515ad57f67a37a Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai Date: Thu, 14 Oct 2021 17:45:53 -0700 Subject: [PATCH 044/293] [modules] Update visibility for merged ObjCProtocolDecl definitions. Merge definition visibility the same way we do for other decls. Without the fix the added test emits `-Wobjc-method-access` as it cannot find a visible protocol. Make this warning `-Werror` so the test would fail when protocol visibility regresses. rdar://83600696 Differential Revision: https://reviews.llvm.org/D111860 (cherry picked from commit 7ad693a322c1b6765f5d06559c2bd73cc3938aaf) --- clang/lib/Serialization/ASTReaderDecl.cpp | 7 ++ .../Modules/merge-objc-protocol-visibility.m | 76 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 clang/test/Modules/merge-objc-protocol-visibility.m diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 220182a9722ae..6899cbac4034f 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1222,6 +1222,13 @@ void ASTDeclReader::ReadObjCDefinitionData( void ASTDeclReader::MergeDefinitionData(ObjCProtocolDecl *D, struct ObjCProtocolDecl::DefinitionData &&NewDD) { + struct ObjCProtocolDecl::DefinitionData &DD = D->data(); + if (DD.Definition != NewDD.Definition) { + Reader.MergedDeclContexts.insert( + std::make_pair(NewDD.Definition, DD.Definition)); + Reader.mergeDefinitionVisibility(DD.Definition, NewDD.Definition); + } + // FIXME: odr checking? } diff --git a/clang/test/Modules/merge-objc-protocol-visibility.m b/clang/test/Modules/merge-objc-protocol-visibility.m new file mode 100644 index 0000000000000..04cf60b7e997a --- /dev/null +++ b/clang/test/Modules/merge-objc-protocol-visibility.m @@ -0,0 +1,76 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m -Werror=objc-method-access -DHIDDEN_FIRST=1 \ +// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache +// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m -Werror=objc-method-access -DHIDDEN_FIRST=0 \ +// RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache + +// Test a case when Objective-C protocol is imported both as hidden and as visible. + +//--- Frameworks/Foundation.framework/Headers/Foundation.h +@interface NSObject +@end + +//--- Frameworks/Foundation.framework/Modules/module.modulemap +framework module Foundation { + header "Foundation.h" + export * +} + +//--- Frameworks/Common.framework/Headers/Common.h +#import +@protocol Testing; +@interface Common : NSObject +- (id)getProtocolObj; +@end + +//--- Frameworks/Common.framework/Modules/module.modulemap +framework module Common { + header "Common.h" + export * +} + +//--- Frameworks/Regular.framework/Headers/Regular.h +@protocol Testing +- (void)protocolMethod; +@end + +//--- Frameworks/Regular.framework/Modules/module.modulemap +framework module Regular { + header "Regular.h" + export * +} + +//--- Frameworks/RegularHider.framework/Headers/Visible.h +// Empty, file required to create a module. + +//--- Frameworks/RegularHider.framework/Headers/Hidden.h +@protocol Testing +- (void)protocolMethod; +@end + +//--- Frameworks/RegularHider.framework/Modules/module.modulemap +framework module RegularHider { + header "Visible.h" + export * + + explicit module Hidden { + header "Hidden.h" + export * + } +} + +//--- test.m +#import + +#if HIDDEN_FIRST +#import +#import +#else +#import +#import +#endif + +void test(Common *obj) { + [[obj getProtocolObj] protocolMethod]; +} From 5d5d035ea99155dc8461a2578e2d9f24c8adf3d3 Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Tue, 16 Nov 2021 16:24:16 -0800 Subject: [PATCH 045/293] Allow __attribute__((swift_attr)) in attribute push pragmas This change does what it says on the tin: it allows SwiftAttr to be used with #pragma clang attribute push to add Swift attributes to large regions of header files. We plan to use this to annotate headers with concurrency information. Reviewed at https://reviews.llvm.org/D112773. Fixes rdar://83499885. --- clang/include/clang/Basic/Attr.td | 1 + clang/test/AST/attr-swift_attr.m | 12 ++++++++++-- .../pragma-attribute-supported-attributes-list.test | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index bcd25373050d6..17eca04e250b0 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2347,6 +2347,7 @@ def SwiftAttr : InheritableAttr { let Spellings = [GNU<"swift_attr">]; let Args = [StringArgument<"Attribute">]; let Documentation = [SwiftAttrDocs]; + let PragmaAttributeSupport = 1; } def SwiftBridge : InheritableAttr { diff --git a/clang/test/AST/attr-swift_attr.m b/clang/test/AST/attr-swift_attr.m index 3cd51b81e349f..3969487d40ff4 100644 --- a/clang/test/AST/attr-swift_attr.m +++ b/clang/test/AST/attr-swift_attr.m @@ -1,8 +1,16 @@ -// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s +// RUN: not %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s __attribute__((swift_attr("@actor"))) @interface View @end -// CHECK: InterfaceDecl {{.*}} View +// CHECK-LABEL: InterfaceDecl {{.*}} View // CHECK-NEXT: SwiftAttrAttr {{.*}} "@actor" + +#pragma clang attribute push(__attribute__((swift_attr("@sendable"))), apply_to=objc_interface) +@interface Contact +@end +#pragma clang attribute pop + +// CHECK-LABEL: InterfaceDecl {{.*}} Contact +// CHECK-NEXT: SwiftAttrAttr {{.*}} "@sendable" diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index d02f5f95c6862..fa3300d77063a 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -161,6 +161,7 @@ // CHECK-NEXT: SwiftAsyncContext (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: SwiftAsyncError (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: SwiftAsyncName (SubjectMatchRule_objc_method, SubjectMatchRule_function) +// CHECK-NEXT: SwiftAttr () // CHECK-NEXT: SwiftBridgedTypedef (SubjectMatchRule_type_alias) // CHECK-NEXT: SwiftContext (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: SwiftError (SubjectMatchRule_function, SubjectMatchRule_objc_method) From 839453240dcfbbf3c7ef5929f77dacd63fb98b9d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 16 Aug 2021 19:23:11 -0700 Subject: [PATCH 046/293] [split-file] Default to --no-leading-lines It turns out that the --leading-lines may be a bad default. [[#@LINE+-num]] is rarely used. --- lld/test/ELF/linkerscript/overwrite-sections.test | 2 +- llvm/test/tools/split-file/basic.test | 6 +++--- llvm/tools/split-file/split-file.cpp | 12 ++++++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lld/test/ELF/linkerscript/overwrite-sections.test b/lld/test/ELF/linkerscript/overwrite-sections.test index 06918728826db..0a14542f7d10d 100644 --- a/lld/test/ELF/linkerscript/overwrite-sections.test +++ b/lld/test/ELF/linkerscript/overwrite-sections.test @@ -1,5 +1,5 @@ # REQUIRES: x86 -# RUN: rm -rf %t && split-file %s %t +# RUN: rm -rf %t && split-file --leading-lines %s %t # RUN: llvm-mc -filetype=obj -triple=x86_64 %t/a.s -o %t/a.o ## There is no main linker script. OVERWRITE_SECTIONS defines output section diff --git a/llvm/test/tools/split-file/basic.test b/llvm/test/tools/split-file/basic.test index 5d32c3429ed37..b47aeb1e11801 100644 --- a/llvm/test/tools/split-file/basic.test +++ b/llvm/test/tools/split-file/basic.test @@ -9,20 +9,20 @@ cc //--- end # RUN: rm -rf %t -# RUN: split-file %s %t +# RUN: split-file --leading-lines %s %t # RUN: diff %S/Inputs/basic-aa.txt %t/aa # RUN: diff %S/Inputs/basic-bb.txt %t/bb # RUN: diff %S/Inputs/basic-cc.txt %t/subdir/cc # RUN: FileCheck %s --check-prefix=END < %t/end ## Can be called on a non-empty directory. -# RUN: split-file %s %t +# RUN: split-file --leading-lines %s %t # RUN: diff %S/Inputs/basic-aa.txt %t/aa ## Test that we will delete the output if it is a file, so that we can create ## a directory. # RUN: rm -rf %t && touch %t -# RUN: split-file %s %t +# RUN: split-file --leading-lines %s %t # RUN: diff %S/Inputs/basic-aa.txt %t/aa # END: RUN: split-file %s %t diff --git a/llvm/tools/split-file/split-file.cpp b/llvm/tools/split-file/split-file.cpp index 3ebbda47e0d53..8f75d96c0c304 100644 --- a/llvm/tools/split-file/split-file.cpp +++ b/llvm/tools/split-file/split-file.cpp @@ -35,8 +35,12 @@ static cl::opt input(cl::Positional, cl::desc("filename"), static cl::opt output(cl::Positional, cl::desc("directory"), cl::value_desc("directory"), cl::cat(cat)); +static cl::opt leadingLines("leading-lines", + cl::desc("Preserve line numbers"), + cl::cat(cat)); + static cl::opt noLeadingLines("no-leading-lines", - cl::desc("Don't preserve line numbers"), + cl::desc("Don't preserve line numbers (default)"), cl::cat(cat)); static StringRef toolName; @@ -97,9 +101,9 @@ static int handle(MemoryBuffer &inputBuf, StringRef input) { Part &cur = res.first->second; if (!i.is_at_eof()) cur.begin = i->data(); - // If --no-leading-lines is not specified, numEmptyLines is 0. Append - // newlines so that the extracted part preserves line numbers. - cur.leadingLines = noLeadingLines ? 0 : i.line_number() - 1; + // If --leading-lines is specified, numEmptyLines is 0. Append newlines so + // that the extracted part preserves line numbers. + cur.leadingLines = leadingLines ? i.line_number() - 1 : 0; lastPart = partName; } From 03844d173ba7b00228d8018995f0a3c312386634 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 2 Nov 2021 13:28:14 -0700 Subject: [PATCH 047/293] [lldb] Improve error reporting in `lang objc tagged-pointer info` Improve error handling for the lang objc tagged-pointer info. Rather than failing silently, report an error if we couldn't convert an argument to an address or resolve the class descriptor. (lldb) lang objc tagged-pointer info 0xbb6404c47a587764 error: could not get class descriptor for 0xbb6404c47a587764 (lldb) lang objc tagged-pointer info n1 error: could not convert 'n1' to a valid address Differential revision: https://reviews.llvm.org/D112945 (cherry picked from commit 50b40b0518900f60ec2712384f6ce40341ed7484) --- .../AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 93 +++++++++++-------- .../API/lang/objc/tagged-pointer/Makefile | 4 + .../tagged-pointer/TestTaggedPointerCmd.py | 20 ++++ lldb/test/API/lang/objc/tagged-pointer/main.m | 6 ++ 4 files changed, 84 insertions(+), 39 deletions(-) create mode 100644 lldb/test/API/lang/objc/tagged-pointer/Makefile create mode 100644 lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py create mode 100644 lldb/test/API/lang/objc/tagged-pointer/main.m diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 04b40fea2a50e..c915700e2ff68 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -958,50 +958,65 @@ class CommandObjectMultiwordObjC_TaggedPointer_Info Process *process = m_exe_ctx.GetProcessPtr(); ExecutionContext exe_ctx(process); + ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); - if (objc_runtime) { - ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor = - objc_runtime->GetTaggedPointerVendor(); - if (tagged_ptr_vendor) { - for (size_t i = 0; i < command.GetArgumentCount(); i++) { - const char *arg_str = command.GetArgumentAtIndex(i); - if (!arg_str) - continue; - Status error; - lldb::addr_t arg_addr = OptionArgParser::ToAddress( - &exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error); - if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail()) - continue; - auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr); - if (!descriptor_sp) - continue; - uint64_t info_bits = 0; - uint64_t value_bits = 0; - uint64_t payload = 0; - if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, - &payload)) { - result.GetOutputStream().Printf( - "0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64 - "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64 - "\n\tclass = %s\n", - (uint64_t)arg_addr, payload, value_bits, info_bits, - descriptor_sp->GetClassName().AsCString("")); - } else { - result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n", - (uint64_t)arg_addr); - } - } - } else { - result.AppendError("current process has no tagged pointer support"); + if (!objc_runtime) { + result.AppendError("current process has no Objective-C runtime loaded"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + + ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor = + objc_runtime->GetTaggedPointerVendor(); + if (!tagged_ptr_vendor) { + result.AppendError("current process has no tagged pointer support"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + + for (size_t i = 0; i < command.GetArgumentCount(); i++) { + const char *arg_str = command.GetArgumentAtIndex(i); + if (!arg_str) + continue; + + Status error; + lldb::addr_t arg_addr = OptionArgParser::ToAddress( + &exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error); + if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail()) { + result.AppendErrorWithFormat( + "could not convert '%s' to a valid address\n", arg_str); result.SetStatus(lldb::eReturnStatusFailed); return false; } - result.SetStatus(lldb::eReturnStatusSuccessFinishResult); - return true; + + auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr); + if (!descriptor_sp) { + result.AppendErrorWithFormat( + "could not get class descriptor for 0x%" PRIx64 "\n", + (uint64_t)arg_addr); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + + uint64_t info_bits = 0; + uint64_t value_bits = 0; + uint64_t payload = 0; + if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, + &payload)) { + result.GetOutputStream().Printf( + "0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64 + "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64 + "\n\tclass = %s\n", + (uint64_t)arg_addr, payload, value_bits, info_bits, + descriptor_sp->GetClassName().AsCString("")); + } else { + result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n", + (uint64_t)arg_addr); + } } - result.AppendError("current process has no Objective-C runtime loaded"); - result.SetStatus(lldb::eReturnStatusFailed); - return false; + + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); + return true; } }; diff --git a/lldb/test/API/lang/objc/tagged-pointer/Makefile b/lldb/test/API/lang/objc/tagged-pointer/Makefile new file mode 100644 index 0000000000000..afecbf969483e --- /dev/null +++ b/lldb/test/API/lang/objc/tagged-pointer/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py new file mode 100644 index 0000000000000..0b9ebd86a914b --- /dev/null +++ b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py @@ -0,0 +1,20 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestTaggedPointerCommand(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test(self): + self.build() + lldbutil.run_to_source_breakpoint(self,"// break here", lldb.SBFileSpec("main.m")) + + self.expect("lang objc tagged-pointer info bogus", error=True, + patterns=["could not convert 'bogus' to a valid address"]) + + self.expect("lang objc tagged-pointer info 0x1", error=True, + patterns=["could not get class descriptor for 0x1"]) + diff --git a/lldb/test/API/lang/objc/tagged-pointer/main.m b/lldb/test/API/lang/objc/tagged-pointer/main.m new file mode 100644 index 0000000000000..4d2ccf5120042 --- /dev/null +++ b/lldb/test/API/lang/objc/tagged-pointer/main.m @@ -0,0 +1,6 @@ +#import +int main() { + id n1 = [NSNumber numberWithInt:1]; + printf("%x", n1); // break here + return 0; +} From 3a3a862896ef81cab2f868e58f376b54d5b95cee Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 3 Nov 2021 14:55:28 -0700 Subject: [PATCH 048/293] [lldb] Update tagged pointer command output and test. - Use formatv to print the addresses. - Add check for 0x0 which is treated as an invalid address. - Use a an address that's less likely to be interpreted as a real tagged pointer. (cherry picked from commit f9e6be5cc1a2cfe5294d4d55336b23266fcfc26f) --- .../AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 23 ++++++++++--------- .../tagged-pointer/TestTaggedPointerCmd.py | 6 +++-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index c915700e2ff68..5eee80e33553a 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -983,17 +983,16 @@ class CommandObjectMultiwordObjC_TaggedPointer_Info lldb::addr_t arg_addr = OptionArgParser::ToAddress( &exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error); if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail()) { - result.AppendErrorWithFormat( - "could not convert '%s' to a valid address\n", arg_str); + result.AppendErrorWithFormatv( + "could not convert '{0}' to a valid address\n", arg_str); result.SetStatus(lldb::eReturnStatusFailed); return false; } auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr); if (!descriptor_sp) { - result.AppendErrorWithFormat( - "could not get class descriptor for 0x%" PRIx64 "\n", - (uint64_t)arg_addr); + result.AppendErrorWithFormatv( + "could not get class descriptor for {0:x}\n", arg_addr); result.SetStatus(lldb::eReturnStatusFailed); return false; } @@ -1003,14 +1002,16 @@ class CommandObjectMultiwordObjC_TaggedPointer_Info uint64_t payload = 0; if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, &payload)) { - result.GetOutputStream().Printf( - "0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64 - "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64 - "\n\tclass = %s\n", - (uint64_t)arg_addr, payload, value_bits, info_bits, + result.GetOutputStream().Format( + "{0:x} is tagged\n" + "\tpayload = {1:x}\n" + "\tvalue = {2:x}\n" + "\tinfo bits = {3:x}\n" + "\tclass = {4}\n", + arg_addr, payload, value_bits, info_bits, descriptor_sp->GetClassName().AsCString("")); } else { - result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n", + result.GetOutputStream().Format("{0:x16} is not tagged\n", (uint64_t)arg_addr); } } diff --git a/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py index 0b9ebd86a914b..fbe9de7ecf80e 100644 --- a/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py +++ b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py @@ -15,6 +15,8 @@ def test(self): self.expect("lang objc tagged-pointer info bogus", error=True, patterns=["could not convert 'bogus' to a valid address"]) - self.expect("lang objc tagged-pointer info 0x1", error=True, - patterns=["could not get class descriptor for 0x1"]) + self.expect("lang objc tagged-pointer info 0x0", error=True, + patterns=["could not convert '0x0' to a valid address"]) + self.expect("lang objc tagged-pointer info 0xffffffff", error=True, + patterns=["could not get class descriptor for 0xffffffff"]) From 68b08e5653ef83d0c2d44e4332d905192277fc2a Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 5 Nov 2021 13:13:41 -0700 Subject: [PATCH 049/293] [lldb] Improve 'lang objc tagged-pointer info' command Don't try to get a class descriptor for a pointer that doesn't look like a tagged pointer. Also print addresses as fixed-width hex and update the test. (cherry picked from commit 10eb32f45d40e180a229590f57dd0a61f97f1bc9) --- .../ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 16 ++++++++++------ .../objc/tagged-pointer/TestTaggedPointerCmd.py | 5 +++-- lldb/test/API/lang/objc/tagged-pointer/main.m | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 5eee80e33553a..2f99a6579ac07 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -989,10 +989,15 @@ class CommandObjectMultiwordObjC_TaggedPointer_Info return false; } + if (!tagged_ptr_vendor->IsPossibleTaggedPointer(arg_addr)) { + result.GetOutputStream().Format("{0:x16} is not tagged\n", arg_addr); + continue; + } + auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr); if (!descriptor_sp) { result.AppendErrorWithFormatv( - "could not get class descriptor for {0:x}\n", arg_addr); + "could not get class descriptor for {0:x16}\n", arg_addr); result.SetStatus(lldb::eReturnStatusFailed); return false; } @@ -1004,15 +1009,14 @@ class CommandObjectMultiwordObjC_TaggedPointer_Info &payload)) { result.GetOutputStream().Format( "{0:x} is tagged\n" - "\tpayload = {1:x}\n" - "\tvalue = {2:x}\n" - "\tinfo bits = {3:x}\n" + "\tpayload = {1:x16}\n" + "\tvalue = {2:x16}\n" + "\tinfo bits = {3:x16}\n" "\tclass = {4}\n", arg_addr, payload, value_bits, info_bits, descriptor_sp->GetClassName().AsCString("")); } else { - result.GetOutputStream().Format("{0:x16} is not tagged\n", - (uint64_t)arg_addr); + result.GetOutputStream().Format("{0:x16} is not tagged\n", arg_addr); } } diff --git a/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py index fbe9de7ecf80e..4c70b53ca4b28 100644 --- a/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py +++ b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py @@ -8,6 +8,7 @@ class TestTaggedPointerCommand(TestBase): mydir = TestBase.compute_mydir(__file__) + @no_debug_info_test def test(self): self.build() lldbutil.run_to_source_breakpoint(self,"// break here", lldb.SBFileSpec("main.m")) @@ -18,5 +19,5 @@ def test(self): self.expect("lang objc tagged-pointer info 0x0", error=True, patterns=["could not convert '0x0' to a valid address"]) - self.expect("lang objc tagged-pointer info 0xffffffff", error=True, - patterns=["could not get class descriptor for 0xffffffff"]) + self.expect("lang objc tagged-pointer info 0x00000001", + patterns=["0x0000000000000001 is not tagged"]) diff --git a/lldb/test/API/lang/objc/tagged-pointer/main.m b/lldb/test/API/lang/objc/tagged-pointer/main.m index 4d2ccf5120042..11a9781482f11 100644 --- a/lldb/test/API/lang/objc/tagged-pointer/main.m +++ b/lldb/test/API/lang/objc/tagged-pointer/main.m @@ -1,6 +1,6 @@ #import int main() { id n1 = [NSNumber numberWithInt:1]; - printf("%x", n1); // break here + printf("%x\n", n1); // break here return 0; } From 52a7a8d10b55c9d890c94c2fa60edc64590bcdb6 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Sun, 7 Nov 2021 10:39:11 -0800 Subject: [PATCH 050/293] [lldb] Remove failures case from TestTaggedPointerCmd Somehow every pointer looks like it's tagged on GreenDragon. Removing the check to unblock the bot until we can get to the bottom of this. (cherry picked from commit d09a21a0b378675c7f69628ce7a9cd0d54dec1da) --- lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py index 4c70b53ca4b28..e5ad111217de9 100644 --- a/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py +++ b/lldb/test/API/lang/objc/tagged-pointer/TestTaggedPointerCmd.py @@ -18,6 +18,3 @@ def test(self): self.expect("lang objc tagged-pointer info 0x0", error=True, patterns=["could not convert '0x0' to a valid address"]) - - self.expect("lang objc tagged-pointer info 0x00000001", - patterns=["0x0000000000000001 is not tagged"]) From 06562ad5152334ad64eebdd6e1fd07356051f312 Mon Sep 17 00:00:00 2001 From: Haowei Wu Date: Thu, 12 Aug 2021 14:33:47 -0700 Subject: [PATCH 051/293] [IFS] Fix the copy constructor warning in IFSStub.cpp This change fixes the gcc warning on copy constructor in IFSStub.cpp file. Differential Revision: https://reviews.llvm.org/D108000 (cherry picked from commit 571b0d84d2071f403980823989fdb90288bca972) --- llvm/lib/InterfaceStub/IFSStub.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/InterfaceStub/IFSStub.cpp b/llvm/lib/InterfaceStub/IFSStub.cpp index bbc91ada1ded6..008263f8db9fb 100644 --- a/llvm/lib/InterfaceStub/IFSStub.cpp +++ b/llvm/lib/InterfaceStub/IFSStub.cpp @@ -29,7 +29,7 @@ IFSStub::IFSStub(IFSStub &&Stub) { Symbols = std::move(Stub.Symbols); } -IFSStubTriple::IFSStubTriple(IFSStubTriple const &Stub) { +IFSStubTriple::IFSStubTriple(IFSStubTriple const &Stub) : IFSStub() { IfsVersion = Stub.IfsVersion; Target = Stub.Target; SoName = Stub.SoName; @@ -37,7 +37,7 @@ IFSStubTriple::IFSStubTriple(IFSStubTriple const &Stub) { Symbols = Stub.Symbols; } -IFSStubTriple::IFSStubTriple(IFSStub const &Stub) { +IFSStubTriple::IFSStubTriple(IFSStub const &Stub) : IFSStub() { IfsVersion = Stub.IfsVersion; Target = Stub.Target; SoName = Stub.SoName; From 74483fb12db58925bf6755683a49ccb52f90d39f Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Wed, 24 Nov 2021 10:44:38 -0800 Subject: [PATCH 052/293] Headers: exclude `#include_next ` on MSVC The 14.31.30818 toolset has the following in the `stdatomic.h`: ~~~ #ifndef __cplusplus #error is not yet supported when compiling as C, but this is planned for a future release. #endif ~~~ This results in clang failing to build existing code which relied on `stdatomic.h` in C mode on Windows. Simply fallback to the clang header until that header is available as a complete implementation. (cherry picked from commit 1ad7de9e92bc2977698e5f6d6493202b50c912d5) --- clang/lib/Headers/stdatomic.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/lib/Headers/stdatomic.h b/clang/lib/Headers/stdatomic.h index 665551ea69a46..1e47bcb2bacfc 100644 --- a/clang/lib/Headers/stdatomic.h +++ b/clang/lib/Headers/stdatomic.h @@ -12,8 +12,12 @@ /* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for * example, already has a Clang-compatible stdatomic.h header. + * + * Exclude the MSVC path as well as the MSVC header as of the 14.31.30818 + * explicitly disallows `stdatomic.h` in the C mode via an `#error`. Fallback + * to the clang resource header until that is fully supported. */ -#if __STDC_HOSTED__ && __has_include_next() +#if __STDC_HOSTED__ && __has_include_next() && !defined(_MSC_VER) # include_next #else From 13a2b204874e5dc67e94cb5c3421175e8e8b4175 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sun, 28 Nov 2021 20:35:07 -0800 Subject: [PATCH 053/293] Windows: support `DoLoadImage` This implements DoLoadImage and UnloadImage in the Windows platform plugin modelled after the POSIX platform plugin. This was previously unimplemented and resulted in a difficult to decipher error without any logging. This implementation is intended to support enables the use of LLDB's Swift REPL on Windows. Paths which are added to the library search path are persistent and applied to all subsequent loads. This can be adjusted in the future by storing all the cookies and restoring the path prior to returning from the helper. However, the dynamic path count makes this a bit more challenging. Differential Revision: https://reviews.llvm.org/D77287 --- .../Plugins/Platform/Windows/CMakeLists.txt | 3 + .../Platform/Windows/PlatformWindows.cpp | 479 +++++++++++++++--- .../Platform/Windows/PlatformWindows.h | 4 + 3 files changed, 428 insertions(+), 58 deletions(-) diff --git a/lldb/source/Plugins/Platform/Windows/CMakeLists.txt b/lldb/source/Plugins/Platform/Windows/CMakeLists.txt index 49a197cdaff36..28c174dc4d95e 100644 --- a/lldb/source/Plugins/Platform/Windows/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/Windows/CMakeLists.txt @@ -6,4 +6,7 @@ add_lldb_library(lldbPluginPlatformWindows PLUGIN lldbCore lldbHost lldbTarget + + LINK_COMPONENTS + Support ) diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp index 1fb95fd77e5d2..7e2efe640ee65 100644 --- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp +++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp @@ -20,12 +20,20 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UserExpression.h" +#include "lldb/Expression/UtilityFunction.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" #include "lldb/Utility/Status.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + +#include "llvm/ADT/ScopeExit.h" +#include "llvm/Support/ConvertUTF.h" + using namespace lldb; using namespace lldb_private; @@ -200,85 +208,252 @@ Status PlatformWindows::DisconnectRemote() { return error; } -Status PlatformWindows::EvaluateLoaderExpression(Process *process, - const char *expression, - ValueObjectSP &value) { - // FIXME(compnerd) `-fdeclspec` is not passed to the clang instance? - static const char kLoaderDecls[] = - R"( - // libloaderapi.h +uint32_t PlatformWindows::DoLoadImage(Process *process, + const FileSpec &remote_file, + const std::vector *paths, + Status &error, FileSpec *loaded_image) { + DiagnosticManager diagnostics; - // WINBASEAPI BOOL WINAPI FreeModule(HMODULE); - extern "C" /* __declspec(dllimport) */ BOOL __stdcall FreeModule(void *hLibModule); + if (loaded_image) + loaded_image->Clear(); - // WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR); - extern "C" /* __declspec(dllimport) */ void * __stdcall LoadLibraryA(const char *); - )"; + ThreadSP thread = process->GetThreadList().GetExpressionExecutionThread(); + if (!thread) { + error.SetErrorString("LoadLibrary error: no thread available to invoke LoadLibrary"); + return LLDB_INVALID_IMAGE_TOKEN; + } - if (DynamicLoader *loader = process->GetDynamicLoader()) { - Status result = loader->CanLoadImage(); - if (result.Fail()) - return result; + ExecutionContext context; + thread->CalculateExecutionContext(context); + + Status status; + UtilityFunction *loader = + process->GetLoadImageUtilityFunction(this, [&]() -> std::unique_ptr { + return MakeLoadImageUtilityFunction(context, status); + }); + if (loader == nullptr) + return LLDB_INVALID_IMAGE_TOKEN; + + FunctionCaller *invocation = loader->GetFunctionCaller(); + if (!invocation) { + error.SetErrorString("LoadLibrary error: could not get function caller"); + return LLDB_INVALID_IMAGE_TOKEN; } - ThreadSP thread = process->GetThreadList().GetExpressionExecutionThread(); - if (!thread) - return Status("selected thread is invalid"); + /* Convert name */ + llvm::SmallVector name; + if (!llvm::convertUTF8ToUTF16String(remote_file.GetPath(), name)) { + error.SetErrorString("LoadLibrary error: could not convert path to UCS2"); + return LLDB_INVALID_IMAGE_TOKEN; + } - StackFrameSP frame = thread->GetStackFrameAtIndex(0); - if (!frame) - return Status("frame 0 is invalid"); + /* Inject name paramter into inferior */ + lldb::addr_t injected_name = + process->AllocateMemory(name.size() * sizeof(llvm::UTF16), + ePermissionsReadable | ePermissionsWritable, + status); + if (injected_name == LLDB_INVALID_ADDRESS) { + error.SetErrorStringWithFormat("LoadLibrary error: unable to allocate memory for name: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } - ExecutionContext context; - frame->CalculateExecutionContext(context); + auto name_cleanup = llvm::make_scope_exit([process, injected_name]() { + process->DeallocateMemory(injected_name); + }); + + process->WriteMemory(injected_name, name.data(), + name.size() * sizeof(llvm::UTF16), status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: unable to write name: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } + + /* Inject paths parameter into inferior */ + lldb::addr_t injected_paths{0x0}; + llvm::Optional>> paths_cleanup; + if (paths) { + llvm::SmallVector search_paths; + + for (const auto &path : *paths) { + if (path.empty()) + continue; + + llvm::SmallVector buffer; + if (!llvm::convertUTF8ToUTF16String(path, buffer)) + continue; + + search_paths.append(std::begin(buffer), std::end(buffer)); + } + search_paths.emplace_back(L'\0'); + + injected_paths = + process->AllocateMemory(search_paths.size() * sizeof(llvm::UTF16), + ePermissionsReadable | ePermissionsWritable, + status); + if (injected_paths == LLDB_INVALID_ADDRESS) { + error.SetErrorStringWithFormat("LoadLibrary error: unable to allocate memory for paths: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } + + paths_cleanup.emplace([process, injected_paths]() { + process->DeallocateMemory(injected_paths); + }); + + process->WriteMemory(injected_paths, search_paths.data(), + search_paths.size() * sizeof(llvm::UTF16), status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: unable to write paths: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } + } + + /* Inject wszModulePath into inferior */ + // FIXME(compnerd) should do something better for the length? + // GetModuleFileNameA is likely limited to PATH_MAX rather than the NT path + // limit. + unsigned injected_length = 261; + + lldb::addr_t injected_module_path = + process->AllocateMemory(injected_length + 1, + ePermissionsReadable | ePermissionsWritable, + status); + if (injected_module_path == LLDB_INVALID_ADDRESS) { + error.SetErrorStringWithFormat("LoadLibrary error: unable to allocate memory for module location: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } + auto injected_module_path_cleanup = + llvm::make_scope_exit([process, injected_module_path]() { + process->DeallocateMemory(injected_module_path); + }); + + /* Inject __lldb_LoadLibraryResult into inferior */ + const uint32_t word_size = process->GetAddressByteSize(); + lldb::addr_t injected_result = + process->AllocateMemory(3 * word_size, + ePermissionsReadable | ePermissionsWritable, + status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: could not allocate memory for result: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } + + auto result_cleanup = llvm::make_scope_exit([process, injected_result]() { + process->DeallocateMemory(injected_result); + }); + + process->WritePointerToMemory(injected_result + word_size, + injected_module_path, status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: could not initialize result: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } + + // XXX(compnerd) should we use the compiler to get the sizeof(unsigned)? + process->WriteScalarToMemory(injected_result + 2 * word_size, + Scalar{injected_length}, sizeof(unsigned), + status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: could not initialize result: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } + + /* Setup Formal Parameters */ + ValueList parameters = invocation->GetArgumentValues(); + parameters.GetValueAtIndex(0)->GetScalar() = injected_name; + parameters.GetValueAtIndex(1)->GetScalar() = injected_paths; + parameters.GetValueAtIndex(2)->GetScalar() = injected_result; + + lldb::addr_t injected_parameters = LLDB_INVALID_ADDRESS; + diagnostics.Clear(); + if (!invocation->WriteFunctionArguments(context, injected_parameters, + parameters, diagnostics)) { + error.SetErrorStringWithFormat("LoadLibrary error: unable to write function parameters: %s", + diagnostics.GetString().c_str()); + return LLDB_INVALID_IMAGE_TOKEN; + } + + auto parameter_cleanup = llvm::make_scope_exit([invocation, &context, injected_parameters]() { + invocation->DeallocateFunctionResults(context, injected_parameters); + }); + + TypeSystemClang *ast = + ScratchTypeSystemClang::GetForTarget(process->GetTarget()); + if (!ast) { + error.SetErrorString("LoadLibrary error: unable to get (clang) type system"); + return LLDB_INVALID_IMAGE_TOKEN; + } + + /* Setup Return Type */ + CompilerType VoidPtrTy = ast->GetBasicType(eBasicTypeVoid).GetPointerType(); + + Value value; + value.SetCompilerType(VoidPtrTy); + + /* Invoke expression */ EvaluateExpressionOptions options; - options.SetUnwindOnError(true); - options.SetIgnoreBreakpoints(true); options.SetExecutionPolicy(eExecutionPolicyAlways); options.SetLanguage(eLanguageTypeC_plus_plus); - // LoadLibrary{A,W}/FreeLibrary cannot raise exceptions which we can handle. + options.SetIgnoreBreakpoints(true); + options.SetUnwindOnError(true); + // LoadLibraryEx{A,W}/FreeLibrary cannot raise exceptions which we can handle. // They may potentially throw SEH exceptions which we do not know how to // handle currently. options.SetTrapExceptions(false); options.SetTimeout(process->GetUtilityExpressionTimeout()); + options.SetIsForUtilityExpr(true); + + ExpressionResults result = + invocation->ExecuteFunction(context, &injected_parameters, options, + diagnostics, value); + if (result != eExpressionCompleted) { + error.SetErrorStringWithFormat("LoadLibrary error: failed to execute LoadLibrary helper: %s", + diagnostics.GetString().c_str()); + return LLDB_INVALID_IMAGE_TOKEN; + } - Status error; - ExpressionResults result = UserExpression::Evaluate( - context, options, expression, kLoaderDecls, value, error); - if (result != eExpressionCompleted) - return error; - - if (value->GetError().Fail()) - return value->GetError(); - - return Status(); -} - -uint32_t PlatformWindows::DoLoadImage(Process *process, - const FileSpec &remote_file, - const std::vector *paths, - Status &error, FileSpec *loaded_path) { - if (loaded_path) - loaded_path->Clear(); + /* Read result */ + lldb::addr_t token = process->ReadPointerFromMemory(injected_result, status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: could not read the result: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } - StreamString expression; - expression.Printf("LoadLibraryA(\"%s\")", remote_file.GetPath().c_str()); + if (token == NULL) { + // XXX(compnerd) should we use the compiler to get the sizeof(unsigned)? + uint64_t error_code = + process->ReadUnsignedIntegerFromMemory(injected_result + 2 * word_size + sizeof(unsigned), + word_size, ERROR_SUCCESS, status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: could not read error status: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; + } - ValueObjectSP value; - Status result = - EvaluateLoaderExpression(process, expression.GetData(), value); - if (result.Fail()) + error.SetErrorStringWithFormat("LoadLibrary Error: %lu", error_code); return LLDB_INVALID_IMAGE_TOKEN; + } - Scalar scalar; - if (value->ResolveValue(scalar)) { - lldb::addr_t address = scalar.ULongLong(); - if (address == 0) - return LLDB_INVALID_IMAGE_TOKEN; - return process->AddImageToken(address); + std::string module_path; + process->ReadCStringFromMemory(injected_module_path, module_path, status); + if (status.Fail()) { + error.SetErrorStringWithFormat("LoadLibrary error: could not read module path: %s", + status.AsCString()); + return LLDB_INVALID_IMAGE_TOKEN; } - return LLDB_INVALID_IMAGE_TOKEN; + + if (loaded_image) + loaded_image->SetFile(module_path, llvm::sys::path::Style::native); + return process->AddImageToken(token); } Status PlatformWindows::UnloadImage(Process *process, uint32_t image_token) { @@ -295,6 +470,9 @@ Status PlatformWindows::UnloadImage(Process *process, uint32_t image_token) { if (result.Fail()) return result; + if (value->GetError().Fail()) + return value->GetError(); + Scalar scalar; if (value->ResolveValue(scalar)) { if (scalar.UInt(1)) @@ -420,3 +598,188 @@ ConstString PlatformWindows::GetFullNameForDylib(ConstString basename) { stream.Printf("%s.dll", basename.GetCString()); return ConstString(stream.GetString()); } + +std::unique_ptr +PlatformWindows::MakeLoadImageUtilityFunction(ExecutionContext &context, + Status &status) { + // FIXME(compnerd) `-fdeclspec` is not passed to the clang instance? + static constexpr const char kLoaderDecls[] = R"( +extern "C" { +// errhandlingapi.h + +// `LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS` +// +// Directories in the standard search path are not searched. This value cannot +// be combined with `LOAD_WITH_ALTERED_SEARCH_PATH`. +// +// This value represents the recommended maximum number of directories an +// application should include in its DLL search path. +#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 + +// WINBASEAPI DWORD WINAPI GetLastError(VOID); +/* __declspec(dllimport) */ uint32_t __stdcall GetLastError(); + +// libloaderapi.h + +// WINBASEAPI DLL_DIRECTORY_COOKIE WINAPI AddDllDirectory(LPCWSTR); +/* __declspec(dllimport) */ void * __stdcall AddDllDirectory(const wchar_t *); + +// WINBASEAPI BOOL WINAPI FreeModule(HMODULE); +/* __declspec(dllimport) */ int __stdcall FreeModule(void *hLibModule); + +// WINBASEAPI DWORD WINAPI GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize); +/* __declspec(dllimport) */ uint32_t GetModuleFileNameA(void *, char *, uint32_t); + +// WINBASEAPI HMODULE WINAPI LoadLibraryExW(LPCWSTR, HANDLE, DWORD); +/* __declspec(dllimport) */ void * __stdcall LoadLibraryExW(const wchar_t *, void *, uint32_t); + +// corecrt_wstring.h + +// _ACRTIMP size_t __cdecl wcslen(wchar_t const *_String); +/* __declspec(dllimport) */ size_t __cdecl wcslen(const wchar_t *); + +// lldb specific code + +struct __lldb_LoadLibraryResult { + void *ImageBase; + char *ModulePath; + unsigned Length; + unsigned ErrorCode; +}; + +_Static_assert(sizeof(struct __lldb_LoadLibraryResult) <= 3 * sizeof(void *), + "__lldb_LoadLibraryResult size mismatch"); + +void * __lldb_LoadLibraryHelper(const wchar_t *name, const wchar_t *paths, + __lldb_LoadLibraryResult *result) { + for (const wchar_t *path = paths; path; ) { + (void)AddDllDirectory(path); + path += wcslen(path) + 1; + } + + result->ImageBase = LoadLibraryExW(name, nullptr, + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + if (result->ImageBase == nullptr) + result->ErrorCode = GetLastError(); + else + result->Length = GetModuleFileNameA(result->ImageBase, result->ModulePath, + result->Length); + + return result->ImageBase; +} +} + )"; + + static constexpr const char kName[] = "__lldb_LoadLibraryHelper"; + + ProcessSP process = context.GetProcessSP(); + Target &target = process->GetTarget(); + + auto function = target.CreateUtilityFunction(std::string{kLoaderDecls}, kName, + eLanguageTypeC_plus_plus, + context); + if (!function) { + std::string error = llvm::toString(function.takeError()); + status.SetErrorStringWithFormat("LoadLibrary error: could not create utility function: %s", + error.c_str()); + return nullptr; + } + + TypeSystemClang *ast = ScratchTypeSystemClang::GetForTarget(target); + if (!ast) + return nullptr; + + CompilerType VoidPtrTy = ast->GetBasicType(eBasicTypeVoid).GetPointerType(); + CompilerType WCharPtrTy = ast->GetBasicType(eBasicTypeWChar).GetPointerType(); + + ValueList parameters; + + Value value; + value.SetValueType(Value::ValueType::Scalar); + + value.SetCompilerType(WCharPtrTy); + parameters.PushValue(value); // name + parameters.PushValue(value); // paths + + value.SetCompilerType(VoidPtrTy); + parameters.PushValue(value); // result + + Status error; + std::unique_ptr utility{std::move(*function)}; + utility->MakeFunctionCaller(VoidPtrTy, parameters, context.GetThreadSP(), + error); + if (error.Fail()) { + status.SetErrorStringWithFormat("LoadLibrary error: could not create function caller: %s", + error.AsCString()); + return nullptr; + } + + if (!utility->GetFunctionCaller()) { + status.SetErrorString("LoadLibrary error: could not get function caller"); + return nullptr; + } + + return utility; +} + +Status PlatformWindows::EvaluateLoaderExpression(Process *process, + const char *expression, + ValueObjectSP &value) { + // FIXME(compnerd) `-fdeclspec` is not passed to the clang instance? + static constexpr const char kLoaderDecls[] = R"( +extern "C" { +// libloaderapi.h + +// WINBASEAPI DLL_DIRECTORY_COOKIE WINAPI AddDllDirectory(LPCWSTR); +/* __declspec(dllimport) */ void * __stdcall AddDllDirectory(const wchar_t *); + +// WINBASEAPI BOOL WINAPI FreeModule(HMODULE); +/* __declspec(dllimport) */ int __stdcall FreeModule(void *); + +// WINBASEAPI DWORD WINAPI GetModuleFileNameA(HMODULE, LPSTR, DWORD); +/* __declspec(dllimport) */ uint32_t GetModuleFileNameA(void *, char *, uint32_t); + +// WINBASEAPI HMODULE WINAPI LoadLibraryExW(LPCWSTR, HANDLE, DWORD); +/* __declspec(dllimport) */ void * __stdcall LoadLibraryExW(const wchar_t *, void *, uint32_t); +} + )"; + + if (DynamicLoader *loader = process->GetDynamicLoader()) { + Status result = loader->CanLoadImage(); + if (result.Fail()) + return result; + } + + ThreadSP thread = process->GetThreadList().GetExpressionExecutionThread(); + if (!thread) + return Status("selected thread is invalid"); + + StackFrameSP frame = thread->GetStackFrameAtIndex(0); + if (!frame) + return Status("frame 0 is invalid"); + + ExecutionContext context; + frame->CalculateExecutionContext(context); + + EvaluateExpressionOptions options; + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetExecutionPolicy(eExecutionPolicyAlways); + options.SetLanguage(eLanguageTypeC_plus_plus); + // LoadLibraryEx{A,W}/FreeLibrary cannot raise exceptions which we can handle. + // They may potentially throw SEH exceptions which we do not know how to + // handle currently. + options.SetTrapExceptions(false); + options.SetTimeout(process->GetUtilityExpressionTimeout()); + + Status error; + ExpressionResults result = UserExpression::Evaluate( + context, options, expression, kLoaderDecls, value, error); + if (result != eExpressionCompleted) + return error; + + if (value->GetError().Fail()) + return value->GetError(); + + return Status(); +} diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.h b/lldb/source/Plugins/Platform/Windows/PlatformWindows.h index 4b0f7bfc6f933..5463aeebcc6bd 100644 --- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.h +++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.h @@ -74,6 +74,10 @@ class PlatformWindows : public RemoteAwarePlatform { ConstString GetFullNameForDylib(ConstString basename) override; private: + std::unique_ptr + MakeLoadImageUtilityFunction(lldb_private::ExecutionContext &context, + lldb_private::Status &status); + lldb_private::Status EvaluateLoaderExpression(lldb_private::Process *process, const char *expression, lldb::ValueObjectSP &value); From 7a77da8c3a51dde0c4821dbf6fea45aeda81ed72 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Mon, 29 Nov 2021 15:54:14 -0300 Subject: [PATCH 054/293] [lldb] Remove unused GetAllocationStrategy function --- .../TypeSystem/Swift/SwiftASTContext.cpp | 22 ------------------- .../TypeSystem/Swift/SwiftASTContext.h | 3 --- .../TypeSystem/Swift/TypeSystemSwift.h | 2 -- .../Swift/TypeSystemSwiftTypeRef.cpp | 7 ------ .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 2 -- 5 files changed, 36 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index eb1bc7246ab04..dc33cb604939f 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -5529,28 +5529,6 @@ bool SwiftASTContext::GetProtocolTypeInfo(const CompilerType &type, return false; } -TypeSystemSwift::TypeAllocationStrategy -SwiftASTContext::GetAllocationStrategy(opaque_compiler_type_t type) { - VALID_OR_RETURN_CHECK_TYPE(type, TypeAllocationStrategy::eUnknown); - - swift::Type swift_type = GetSwiftType(type); - if (!swift_type) - return TypeAllocationStrategy::eUnknown; - const swift::irgen::TypeInfo *type_info = - GetSwiftTypeInfo(swift_type.getPointer()); - if (!type_info) - return TypeAllocationStrategy::eUnknown; - switch (type_info->getFixedPacking(GetIRGenModule())) { - case swift::irgen::FixedPacking::OffsetZero: - return TypeAllocationStrategy::eInline; - case swift::irgen::FixedPacking::Allocate: - return TypeAllocationStrategy::ePointer; - case swift::irgen::FixedPacking::Dynamic: - return TypeAllocationStrategy::eDynamic; - } - return TypeAllocationStrategy::eUnknown; -} - CompilerType SwiftASTContext::GetTypeRefType(lldb::opaque_compiler_type_t type) { return GetTypeSystemSwiftTypeRef().GetTypeFromMangledTypename( diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h index 88d8bc8fac2b8..8651cee142711 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h @@ -538,9 +538,6 @@ class SwiftASTContext : public TypeSystemSwift { static bool GetProtocolTypeInfo(const CompilerType &type, ProtocolInfo &protocol_info); - TypeAllocationStrategy - GetAllocationStrategy(lldb::opaque_compiler_type_t type) override; - enum class NonTriviallyManagedReferenceStrategy { eWeak, eUnowned, diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h index 855f8431a633e..c70bb9bde7245 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h @@ -127,8 +127,6 @@ class TypeSystemSwift : public TypeSystem { static CompilerType GetInstanceType(CompilerType ct); virtual CompilerType GetInstanceType(lldb::opaque_compiler_type_t type) = 0; enum class TypeAllocationStrategy { eInline, ePointer, eDynamic, eUnknown }; - virtual TypeAllocationStrategy - GetAllocationStrategy(lldb::opaque_compiler_type_t type) = 0; struct TupleElement { ConstString element_name; CompilerType element_type; diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 921848ea4593b..cf1778189d46d 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -3123,13 +3123,6 @@ TypeSystemSwiftTypeRef::GetInstanceType(opaque_compiler_type_t type) { (ReconstructType(type))); } -TypeSystemSwift::TypeAllocationStrategy -TypeSystemSwiftTypeRef::GetAllocationStrategy(opaque_compiler_type_t type) { - if (auto *swift_ast_context = GetSwiftASTContext()) - return swift_ast_context->GetAllocationStrategy(ReconstructType(type)); - return {}; -} - CompilerType TypeSystemSwiftTypeRef::CreateTupleType( const std::vector &elements) { auto impl = [&]() -> CompilerType { diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index b15d8e6a362f1..7268403c50d08 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -246,8 +246,6 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { CompilerType GetErrorType() override; CompilerType GetReferentType(lldb::opaque_compiler_type_t type) override; CompilerType GetInstanceType(lldb::opaque_compiler_type_t type) override; - TypeAllocationStrategy - GetAllocationStrategy(lldb::opaque_compiler_type_t type) override; CompilerType CreateTupleType(const std::vector &elements) override; bool IsTupleType(lldb::opaque_compiler_type_t type) override; From 716bb2c5be0c07e638904790faf73e997f138049 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Mon, 29 Nov 2021 13:08:09 -0800 Subject: [PATCH 055/293] Update PlatformWindows.cpp Use `0` instead of `ERROR_SUCCESS` as `ERROR_SUCCESS` requires building on Windows. --- lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp index 7e2efe640ee65..f0fca4e703b22 100644 --- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp +++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp @@ -432,7 +432,7 @@ uint32_t PlatformWindows::DoLoadImage(Process *process, // XXX(compnerd) should we use the compiler to get the sizeof(unsigned)? uint64_t error_code = process->ReadUnsignedIntegerFromMemory(injected_result + 2 * word_size + sizeof(unsigned), - word_size, ERROR_SUCCESS, status); + word_size, 0, status); if (status.Fail()) { error.SetErrorStringWithFormat("LoadLibrary error: could not read error status: %s", status.AsCString()); From 627f7d36b0241ddca3f156a342a72f1df3d2e5e0 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 5 Nov 2021 22:07:54 -0700 Subject: [PATCH 056/293] [lldb] Don't set the OS for ARMGetSupportedArchitectureAtIndex Don't set the OS when computing supported architectures in PlatformDarwin::ARMGetSupportedArchitectureAtIndex. Differential revision: https://reviews.llvm.org/D113159 (cherry picked from commit cd7a2bf94b69e613ce64327839b831610c4eea14) --- .../Platform/MacOSX/PlatformDarwin.cpp | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 923e7abf25fa2..7e2dc7fddb233 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -559,6 +559,15 @@ static llvm::ArrayRef GetCompatibleArchs(ArchSpec::Core core) { switch (core) { default: LLVM_FALLTHROUGH; + case ArchSpec::eCore_arm_arm64e: { + static const char *g_arm64e_compatible_archs[] = { + "arm64e", "arm64", "armv7", "armv7f", "armv7k", "armv7s", + "armv7m", "armv7em", "armv6m", "armv6", "armv5", "armv4", + "arm", "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", + "thumbv7em", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", + }; + return {g_arm64e_compatible_archs}; + } case ArchSpec::eCore_arm_arm64: { static const char *g_arm64_compatible_archs[] = { "arm64", "armv7", "armv7f", "armv7k", "armv7s", "armv7m", @@ -662,38 +671,15 @@ const char *PlatformDarwin::GetCompatibleArch(ArchSpec::Core core, size_t idx) { /// processor. bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) { -#if TARGET_OS_OSX - if (IsHost()) { - if (idx == 0) { - arch.SetTriple("arm64e-apple-macosx"); - return true; - } else if (idx == 1) { - arch.SetTriple("arm64-apple-macosx"); - return true; - } - arch.Clear(); - return false; - } -#endif - -#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 -#define OSNAME "tvos" -#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 -#define OSNAME "watchos" -#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 -#define OSNAME "bridgeos" -#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1 -#define OSNAME "macosx" -#else -#define OSNAME "ios" -#endif - const ArchSpec system_arch = GetSystemArchitecture(); const ArchSpec::Core system_core = system_arch.GetCore(); + if (const char *compatible_arch = GetCompatibleArch(system_core, idx)) { - std::string triple = - llvm::formatv("{0}-apple-" OSNAME, compatible_arch).str(); + llvm::Triple triple; + triple.setArchName(compatible_arch); + triple.setVendor(llvm::Triple::VendorType::Apple); arch.SetTriple(triple); + return true; } arch.Clear(); From 8df5b3d08f21b31824d4faa703b61a924fa08883 Mon Sep 17 00:00:00 2001 From: Jessica Paquette Date: Mon, 8 Nov 2021 14:43:12 -0800 Subject: [PATCH 057/293] [GlobalISel] Ensure that translateInvoke adds all successors for inlineasm The existing code didn't add all necessary successors, which resulted in disjoint basic blocks. These would end up not being legalized which, in the best case, caused a fallback only in assert builds. Here's an example: https://godbolt.org/z/ndx15Enfj We also end up getting weird codegen here as well. Refactoring the code here allows us to correctly attach all successors. With this patch, the above example gives correct codegen at -O0 with and without asserts. Also autogen the testcase to show that we add all the successors now. Differential Revision: https://reviews.llvm.org/D113437 --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 47 ++++++------ .../irtranslator-unwind-inline-asm.ll | 75 +++++++++++++++++-- 2 files changed, 88 insertions(+), 34 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 58601945f7bee..21564aded68be 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2485,32 +2485,19 @@ bool IRTranslator::translateInvoke(const User &U, if (!isa(EHPadBB->getFirstNonPHI())) return false; - bool LowerInlineAsm = false; - if (I.isInlineAsm()) { - const InlineAsm *IA = cast(I.getCalledOperand()); - if (!IA->canThrow()) { - // Fast path without emitting EH_LABELs. - - if (!translateInlineAsm(I, MIRBuilder)) - return false; - - MachineBasicBlock *InvokeMBB = &MIRBuilder.getMBB(), - *ReturnMBB = &getMBB(*ReturnBB); - - // Update successor info. - addSuccessorWithProb(InvokeMBB, ReturnMBB, BranchProbability::getOne()); - - MIRBuilder.buildBr(*ReturnMBB); - return true; - } else { - LowerInlineAsm = true; - } - } + bool LowerInlineAsm = I.isInlineAsm(); + bool NeedEHLabel = true; + // If it can't throw then use a fast-path without emitting EH labels. + if (LowerInlineAsm) + NeedEHLabel = (cast(I.getCalledOperand()))->canThrow(); // Emit the actual call, bracketed by EH_LABELs so that the MF knows about // the region covered by the try. - MCSymbol *BeginSymbol = Context.createTempSymbol(); - MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol); + MCSymbol *BeginSymbol = nullptr; + if (NeedEHLabel) { + BeginSymbol = Context.createTempSymbol(); + MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(BeginSymbol); + } if (LowerInlineAsm) { if (!translateInlineAsm(I, MIRBuilder)) @@ -2518,8 +2505,11 @@ bool IRTranslator::translateInvoke(const User &U, } else if (!translateCallBase(I, MIRBuilder)) return false; - MCSymbol *EndSymbol = Context.createTempSymbol(); - MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol); + MCSymbol *EndSymbol = nullptr; + if (NeedEHLabel) { + EndSymbol = Context.createTempSymbol(); + MIRBuilder.buildInstr(TargetOpcode::EH_LABEL).addSym(EndSymbol); + } SmallVector, 1> UnwindDests; BranchProbabilityInfo *BPI = FuncInfo.BPI; @@ -2541,7 +2531,12 @@ bool IRTranslator::translateInvoke(const User &U, } InvokeMBB->normalizeSuccProbs(); - MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol); + if (NeedEHLabel) { + assert(BeginSymbol && "Expected a begin symbol!"); + assert(EndSymbol && "Expected an end symbol!"); + MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol); + } + MIRBuilder.buildBr(ReturnMBB); return true; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll index fdb0543c8cdd7..5d1e78285bf72 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -O0 -global-isel -stop-after=irtranslator < %s | FileCheck %s target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" @@ -6,19 +7,45 @@ target triple = "aarch64-unknown-linux-gnu" @.str.2 = private unnamed_addr constant [7 x i8] c"Boom!\0A\00", align 1 define dso_local void @trap() { + ; CHECK-LABEL: name: trap + ; CHECK: bb.1.entry: entry: unreachable } define dso_local void @test() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { + ; CHECK-LABEL: name: test + ; CHECK: bb.1.entry: + ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @.str.2 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[GV]](p0) + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: INLINEASM &"bl trap", 1 /* sideeffect attdialect */ + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: G_BR %bb.2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.invoke.cont: + ; CHECK-NEXT: RET_ReallyLR + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3.lpad (landing-pad): + ; CHECK-NEXT: liveins: $x0, $x1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x1 + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY2]](p0) + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY]](p0) + ; CHECK-NEXT: BL @printf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0 + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY1]](p0) + ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0 + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp entry: -; CHECK-LABEL: name: test -; CHECK: body: -; CHECK-NEXT: bb.1.entry -; CHECK: EH_LABEL -; CHECK-NEXT: INLINEASM -; CHECK-NEXT: EH_LABEL invoke void asm sideeffect unwind "bl trap", ""() to label %invoke.cont unwind label %lpad @@ -27,8 +54,6 @@ invoke.cont: ret void lpad: -; CHECK: bb.3.lpad -; CHECK: EH_LABEL %0 = landingpad { i8*, i32 } cleanup @@ -37,6 +62,40 @@ lpad: } +define void @test2() #0 personality i32 (...)* @__gcc_personality_v0 { + ; CHECK-LABEL: name: test2 + ; CHECK: bb.1 (%ir-block.0): + ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY [[DEF]](p0) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 1572873 /* reguse:GPR64common */, [[COPY]] + ; CHECK-NEXT: G_BR %bb.2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.a: + ; CHECK-NEXT: RET_ReallyLR + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3.b (landing-pad): + ; CHECK-NEXT: liveins: $x0, $x1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: EH_LABEL + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(p0) = COPY $x1 + ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY2]](p0) + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp + ; CHECK-NEXT: $x0 = COPY [[COPY1]](p0) + ; CHECK-NEXT: BL @_Unwind_Resume, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0 + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp + invoke void asm sideeffect "", "r"(i64* undef) to label %a unwind label %b +a: + ret void +b: + %landing_pad = landingpad { i8*, i32 } cleanup + resume { i8*, i32 } %landing_pad +} + +declare i32 @__gcc_personality_v0(...) declare dso_local i32 @__gxx_personality_v0(...) declare dso_local void @printf(i8*, ...) From 248daba2ddf35be88c25fa162e38174ee12282d2 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Tue, 30 Nov 2021 13:39:01 -0300 Subject: [PATCH 058/293] [lldb] Consider bound types when deciding if the overall type is dynamic --- .../TypeSystem/Swift/SwiftASTContext.cpp | 9 +++ .../Swift/TypeSystemSwiftTypeRef.cpp | 78 ++++++++++++------- 2 files changed, 59 insertions(+), 28 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index eb1bc7246ab04..f693a73ffc083 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -5410,6 +5410,15 @@ bool SwiftASTContext::IsPossibleDynamicType(opaque_compiler_type_t type, if (can_type == GetASTContext()->TheBridgeObjectType) return true; + if (auto *bound_type = + llvm::dyn_cast(can_type.getPointer())) { + for (auto generic_arg : bound_type->getGenericArgs()) { + if (IsPossibleDynamicType(generic_arg.getPointer(), dynamic_pointee_type, + check_cplusplus, check_objc)) + return true; + } + } + if (dynamic_pointee_type) dynamic_pointee_type->Clear(); return false; diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 921848ea4593b..984035ef0c389 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1990,37 +1990,59 @@ bool TypeSystemSwiftTypeRef::IsPossibleDynamicType(opaque_compiler_type_t type, auto impl = [&]() { using namespace swift::Demangle; Demangler dem; - auto *node = DemangleCanonicalType(dem, type); - if (!node) - return false; + std::function is_possible_dynamic = + [&](NodePointer node) -> bool { + if (!node) + return false; - if (node->getKind() == Node::Kind::TypeAlias) { - auto resolved = ResolveTypeAlias(this, GetSwiftASTContext(), dem, node); - if (auto *n = std::get(resolved)) - node = n; - } + if (node->getKind() == Node::Kind::TypeAlias) { + auto resolved = ResolveTypeAlias(this, GetSwiftASTContext(), dem, node); + if (auto *n = std::get(resolved)) + node = n; + } - switch (node->getKind()) { - case Node::Kind::Class: - case Node::Kind::BoundGenericClass: - case Node::Kind::Protocol: - case Node::Kind::ProtocolList: - case Node::Kind::ProtocolListWithClass: - case Node::Kind::ProtocolListWithAnyObject: - case Node::Kind::ExistentialMetatype: - case Node::Kind::DynamicSelf: - return true; - case Node::Kind::BuiltinTypeName: { - if (!node->hasText()) + switch (node->getKind()) { + case Node::Kind::Class: + case Node::Kind::BoundGenericClass: + case Node::Kind::Protocol: + case Node::Kind::ProtocolList: + case Node::Kind::ProtocolListWithClass: + case Node::Kind::ProtocolListWithAnyObject: + case Node::Kind::ExistentialMetatype: + case Node::Kind::DynamicSelf: + return true; + case Node::Kind::BoundGenericStructure: + case Node::Kind::BoundGenericEnum: { + if (node->getNumChildren() < 2) + return false; + NodePointer type_list = node->getLastChild(); + if (type_list->getKind() != Node::Kind::TypeList) + return false; + for (size_t i = 0; i < type_list->getNumChildren(); ++i) { + NodePointer child = type_list->getChild(i); + if (child->getKind() == Node::Kind::Type) { + child = child->getFirstChild(); + if (is_possible_dynamic(child)) + return true; + } + } return false; - StringRef name = node->getText(); - return name == swift::BUILTIN_TYPE_NAME_RAWPOINTER || - name == swift::BUILTIN_TYPE_NAME_NATIVEOBJECT || - name == swift::BUILTIN_TYPE_NAME_BRIDGEOBJECT; - } - default: - return ContainsGenericTypeParameter(node); - } + } + case Node::Kind::BuiltinTypeName: { + if (!node->hasText()) + return false; + StringRef name = node->getText(); + return name == swift::BUILTIN_TYPE_NAME_RAWPOINTER || + name == swift::BUILTIN_TYPE_NAME_NATIVEOBJECT || + name == swift::BUILTIN_TYPE_NAME_BRIDGEOBJECT; + } + default: + return ContainsGenericTypeParameter(node); + } + }; + + auto *node = DemangleCanonicalType(dem, type); + return is_possible_dynamic(node); }; VALIDATE_AND_RETURN( impl, IsPossibleDynamicType, type, From b26f76314fe85c31872c6bc04268c381aea1f342 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 30 Nov 2021 09:58:41 -0800 Subject: [PATCH 059/293] Add support for 32-bit reflection contexts. This patch introduces a wrapper ReflectionContextInterface that encapsulates all traffic to ReflectionContext and abstracts the detail that ReflectionContext is a template that needs to be specialized for a specific pointer width. This fixes various TypeSystemSwiftTypeRef issues when debugging on an arm64_32 Apple Watch. rdar://83959667 --- .../Swift/SwiftLanguageRuntime.cpp | 18 +- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 202 +++++++++++++----- .../Swift/SwiftLanguageRuntimeImpl.h | 71 +++++- 3 files changed, 226 insertions(+), 65 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index d4fdb4c5cf739..19d7165882c25 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -412,7 +412,7 @@ static bool HasReflectionInfo(ObjectFile *obj_file) { return hasReflectionSection; } -SwiftLanguageRuntimeImpl::NativeReflectionContext * +SwiftLanguageRuntimeImpl::ReflectionContextInterface * SwiftLanguageRuntimeImpl::GetReflectionContext() { if (!m_initialized_reflection_ctx) SetupReflection(); @@ -438,7 +438,21 @@ void SwiftLanguageRuntimeImpl::SetupReflection() { if (m_initialized_reflection_ctx) return; - m_reflection_ctx.reset(new NativeReflectionContext(this->GetMemoryReader())); + auto &target = m_process.GetTarget(); + if (auto exe_module = target.GetExecutableModule()) { + auto &triple = exe_module->GetArchitecture().GetTriple(); + if (triple.isArch64Bit()) + m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext64( + this->GetMemoryReader()); + else if (triple.isArch32Bit()) + m_reflection_ctx = ReflectionContextInterface::CreateReflectionContext32( + this->GetMemoryReader()); + else { + LLDB_LOGF(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "Could not initialize reflection context for \"%s\"", + triple.str().c_str()); + } + } m_initialized_reflection_ctx = true; // Add all defered modules to reflection context that were added to diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 12f56a94df70d..fd26155589228 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -250,6 +250,142 @@ lldb::addr_t SwiftLanguageRuntime::MaybeMaskNonTrivialReferencePointer( return addr; } +namespace { + +/// An implementation of the generic ReflectionContextInterface that +/// is templatized on target pointer width and specialized to either +/// 32-bit or 64-bit pointers. +template +class TargetReflectionContext + : public SwiftLanguageRuntimeImpl::ReflectionContextInterface { + using ReflectionContext = swift::reflection::ReflectionContext< + swift::External>>; + ReflectionContext m_reflection_ctx; + +public: + TargetReflectionContext( + std::shared_ptr reader) + : m_reflection_ctx(reader) {} + + bool addImage( + llvm::function_ref, uint64_t>( + swift::ReflectionSectionKind)> + find_section) override { + return m_reflection_ctx.addImage(find_section); + } + + bool addImage(swift::remote::RemoteAddress image_start) override { + return m_reflection_ctx.addImage(image_start); + } + + bool readELF(swift::remote::RemoteAddress ImageStart, + llvm::Optional FileBuffer) override { + return m_reflection_ctx.readELF(ImageStart, FileBuffer); + } + + const swift::reflection::TypeInfo * + getTypeInfo(const swift::reflection::TypeRef *type_ref, + swift::remote::TypeInfoProvider *provider) override { + return m_reflection_ctx.getTypeInfo(type_ref, provider); + } + + swift::reflection::MemoryReader &getReader() override { + return m_reflection_ctx.getReader(); + } + + bool ForEachSuperClassType( + LLDBTypeInfoProvider *tip, lldb::addr_t pointer, + std::function fn) + override { + auto md_ptr = m_reflection_ctx.readMetadataFromInstance(pointer); + if (!md_ptr) + return false; + + // Class object. + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "found RecordTypeInfo for instance"); + while (md_ptr && *md_ptr) { + // Reading metadata is potentially expensive since (in a remote + // debugging scenario it may even incur network traffic) so we + // just return closures that the caller can use to query details + // if they need them.' + auto metadata = *md_ptr; + if (fn({[=]() -> const swift::reflection::RecordTypeInfo * { + auto *ti = m_reflection_ctx.getMetadataTypeInfo(metadata, tip); + return llvm::dyn_cast_or_null< + swift::reflection::RecordTypeInfo>(ti); + }, + [=]() -> const swift::reflection::TypeRef * { + return m_reflection_ctx.readTypeFromMetadata(metadata); + }})) + return true; + + // Continue with the base class. + md_ptr = m_reflection_ctx.readSuperClassFromClassMetadata(metadata); + } + return false; + } + + llvm::Optional> + projectExistentialAndUnwrapClass( + swift::reflection::RemoteAddress existential_address, + const swift::reflection::TypeRef &existential_tr) override { + return m_reflection_ctx.projectExistentialAndUnwrapClass( + existential_address, existential_tr); + } + + const swift::reflection::TypeRef * + readTypeFromMetadata(lldb::addr_t metadata_address, + bool skip_artificial_subclasses) override { + return m_reflection_ctx.readTypeFromMetadata(metadata_address, + skip_artificial_subclasses); + } + + const swift::reflection::TypeRef * + readTypeFromInstance(lldb::addr_t instance_address, + bool skip_artificial_subclasses) override { + auto metadata_address = + m_reflection_ctx.readMetadataFromInstance(instance_address); + if (!metadata_address) { + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "could not read heap metadata for object at %llu\n", + instance_address); + return nullptr; + } + + return m_reflection_ctx.readTypeFromMetadata(*metadata_address, + skip_artificial_subclasses); + } + + swift::reflection::TypeRefBuilder &getBuilder() override { + return m_reflection_ctx.getBuilder(); + } + + llvm::Optional isValueInlinedInExistentialContainer( + swift::remote::RemoteAddress existential_address) override { + return m_reflection_ctx.isValueInlinedInExistentialContainer( + existential_address); + } +}; + +} // namespace + +std::unique_ptr +SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext32( + std::shared_ptr reader) { + return std::make_unique>(reader); +} + +std::unique_ptr +SwiftLanguageRuntimeImpl::ReflectionContextInterface::CreateReflectionContext64( + std::shared_ptr reader) { + return std::make_unique>(reader); +} + +SwiftLanguageRuntimeImpl::ReflectionContextInterface:: + ~ReflectionContextInterface() {} + const CompilerType &SwiftLanguageRuntimeImpl::GetBoxMetadataType() { if (m_box_metadata_type.IsValid()) return m_box_metadata_type; @@ -634,6 +770,8 @@ class ASTVerifier : public swift::ASTWalker { } }; +} // namespace + class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider { SwiftLanguageRuntimeImpl &m_runtime; TypeSystemSwift &m_typesystem; @@ -712,7 +850,8 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider { if (is_bitfield_ptr) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); if (log) - log->Printf("[LLDBTypeInfoProvider] bitfield support is not yet implemented"); + log->Printf("[LLDBTypeInfoProvider] bitfield support is not yet " + "implemented"); continue; } swift::reflection::FieldInfo field_info = { @@ -725,8 +864,6 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider { } }; -} // namespace - llvm::Optional SwiftLanguageRuntimeImpl::lookupClangTypeInfo(CompilerType clang_type) { std::lock_guard locker(m_clang_type_info_mutex); @@ -1574,35 +1711,9 @@ bool SwiftLanguageRuntimeImpl::ForEachSuperClassType( if (!ts) return false; + LLDBTypeInfoProvider tip(*this, *ts); lldb::addr_t pointer = instance.GetPointerValue(); - auto md_ptr = reflection_ctx->readMetadataFromInstance(pointer); - if (!md_ptr) - return false; - - // Class object. - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "found RecordTypeInfo for instance"); - while (md_ptr && *md_ptr) { - // Reading metadata is potentially expensive since (in a remote - // debugging scenario it may even incur network traffic) so we - // just return closures that the caller can use to query details - // if they need them. - auto metadata = *md_ptr; - if (fn({[=]() -> const swift::reflection::RecordTypeInfo * { - LLDBTypeInfoProvider tip(*this, *ts); - auto *ti = reflection_ctx->getMetadataTypeInfo(metadata, &tip); - return llvm::dyn_cast_or_null( - ti); - }, - [=]() -> const swift::reflection::TypeRef * { - return reflection_ctx->readTypeFromMetadata(metadata); - }})) - return true; - - // Continue with the base class. - md_ptr = reflection_ctx->readSuperClassFromClassMetadata(metadata); - } - return false; + return reflection_ctx->ForEachSuperClassType(&tip, pointer, fn); } bool SwiftLanguageRuntime::IsSelf(Variable &variable) { @@ -1673,8 +1784,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address) { AddressType address_type; - lldb::addr_t class_metadata_ptr = in_value.GetPointerValue(&address_type); - if (class_metadata_ptr == LLDB_INVALID_ADDRESS || class_metadata_ptr == 0) + lldb::addr_t instance_ptr = in_value.GetPointerValue(&address_type); + if (instance_ptr == LLDB_INVALID_ADDRESS || instance_ptr == 0) return false; CompilerType static_type = in_value.GetCompilerType(); @@ -1682,7 +1793,7 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( llvm::dyn_cast_or_null(static_type.GetTypeSystem()); if (!tss) return false; - address.SetRawAddress(class_metadata_ptr); + address.SetRawAddress(instance_ptr); auto &ts = tss->GetTypeSystemSwiftTypeRef(); // Ask the Objective-C runtime about Objective-C types. if (tss->IsImportedType(static_type.GetOpaqueQualType(), nullptr)) @@ -1712,19 +1823,7 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( } Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES)); auto *reflection_ctx = GetReflectionContext(); - swift::remote::RemoteAddress instance_address(class_metadata_ptr); - auto metadata_address = - reflection_ctx->readMetadataFromInstance(class_metadata_ptr); - if (!metadata_address) { - if (log) - log->Printf("could not read heap metadata for object at %llu\n", - class_metadata_ptr); - return false; - } - - const auto *typeref = - reflection_ctx->readTypeFromMetadata(*metadata_address, - /*skipArtificial=*/false); + const auto *typeref = reflection_ctx->readTypeFromInstance(instance_ptr); if (!typeref) return false; swift::Demangle::Demangler dem; @@ -1733,8 +1832,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( #ifndef NDEBUG auto &remote_ast = GetRemoteASTContext(scratch_ctx); - auto remote_ast_metadata_address = - remote_ast.getHeapMetadataForObject(instance_address); + auto remote_ast_metadata_address = remote_ast.getHeapMetadataForObject( + swift::remote::RemoteAddress(instance_ptr)); if (remote_ast_metadata_address) { auto instance_type = remote_ast.getTypeForRemoteTypeMetadata( remote_ast_metadata_address.getValue(), @@ -1748,9 +1847,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( << "\n"; } else { if (log) { - log->Printf( - "could not get type metadata from address %" PRIu64 " : %s\n", - *metadata_address, instance_type.getFailure().render().c_str()); + log->Printf("could not get type metadata: %s\n", + instance_type.getFailure().render().c_str()); } } } diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h index 7474ab2516600..711c36941495b 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h @@ -15,6 +15,7 @@ #include "SwiftLanguageRuntime.h" #include "swift/Reflection/TypeLowering.h" +#include "llvm/Support/Memory.h" namespace swift { namespace reflection { @@ -24,6 +25,7 @@ class TypeRef; namespace lldb_private { class Process; +class LLDBTypeInfoProvider; /// A full LLDB language runtime backed by the Swift runtime library /// in the process. @@ -177,15 +179,6 @@ class SwiftLanguageRuntimeImpl { bool IsABIStable(); -protected: - using NativeReflectionContext = swift::reflection::ReflectionContext< - swift::External>>; - - /// Use the reflection context to build a TypeRef object. - const swift::reflection::TypeRef * - GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder, - SwiftASTContext *swift_ast_context); - /// Returned by \ref ForEachSuperClassType. Not every user of \p /// ForEachSuperClassType needs all of these. By returning this /// object we call into the runtime only when needed. @@ -194,6 +187,62 @@ class SwiftLanguageRuntimeImpl { std::function get_record_type_info; std::function get_typeref; }; + + /// An abstract interface to swift::reflection::ReflectionContext + /// objects of varying pointer sizes. This class encapsulates all + /// traffic to ReflectionContext and abstracts the detail that + /// ReflectionContext is a template that needs to be specialized for + /// a specific pointer width. + class ReflectionContextInterface { + public: + /// Return a 32-bit reflection context. + static std::unique_ptr + CreateReflectionContext32( + std::shared_ptr reader); + + /// Return a 64-bit reflection context. + static std::unique_ptr + CreateReflectionContext64( + std::shared_ptr reader); + + virtual ~ReflectionContextInterface(); + + virtual bool addImage( + llvm::function_ref, uint64_t>( + swift::ReflectionSectionKind)> + find_section); + virtual bool addImage(swift::remote::RemoteAddress image_start) = 0; + virtual bool readELF(swift::remote::RemoteAddress ImageStart, + llvm::Optional FileBuffer) = 0; + virtual const swift::reflection::TypeInfo * + getTypeInfo(const swift::reflection::TypeRef *type_ref, + swift::remote::TypeInfoProvider *provider) = 0; + virtual swift::remote::MemoryReader &getReader() = 0; + virtual bool + ForEachSuperClassType(LLDBTypeInfoProvider *tip, lldb::addr_t pointer, + std::function fn) = 0; + virtual llvm::Optional> + projectExistentialAndUnwrapClass( + swift::remote::RemoteAddress existential_addess, + const swift::reflection::TypeRef &existential_tr) = 0; + virtual const swift::reflection::TypeRef * + readTypeFromMetadata(lldb::addr_t metadata_address, + bool skip_artificial_subclasses = false) = 0; + virtual const swift::reflection::TypeRef * + readTypeFromInstance(lldb::addr_t instance_address, + bool skip_artificial_subclasses = false) = 0; + virtual swift::reflection::TypeRefBuilder &getBuilder() = 0; + virtual llvm::Optional isValueInlinedInExistentialContainer( + swift::remote::RemoteAddress existential_address) = 0; + }; + +protected: + /// Use the reflection context to build a TypeRef object. + const swift::reflection::TypeRef * + GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder, + SwiftASTContext *swift_ast_context); + /// If \p instance points to a Swift object, retrieve its /// RecordTypeInfo and pass it to the callback \p fn. Repeat the /// process with all superclasses. If \p fn returns \p true, early @@ -301,7 +350,7 @@ class SwiftLanguageRuntimeImpl { llvm::Optional GetDynamicExclusivityFlagAddr(); /// Lazily initialize the reflection context. Return \p nullptr on failure. - NativeReflectionContext *GetReflectionContext(); + ReflectionContextInterface *GetReflectionContext(); /// Lazily initialize and return \p m_SwiftNativeNSErrorISA. llvm::Optional GetSwiftNativeNSErrorISA(); @@ -321,7 +370,7 @@ class SwiftLanguageRuntimeImpl { /// Reflection context. /// \{ - std::unique_ptr m_reflection_ctx; + std::unique_ptr m_reflection_ctx; /// Record modules added through ModulesDidLoad, which are to be /// added to the reflection context once it's being initialized. From c0b76ea8f88fded23d764e8a302168104623b278 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Tue, 30 Nov 2021 17:28:18 -0300 Subject: [PATCH 060/293] [lldb] Desugar unlimited levels when calculating type name --- .../Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 2 +- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 15 ++++----------- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index eb1bc7246ab04..0bfcb24785790 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -5569,7 +5569,7 @@ ConstString SwiftASTContext::GetTypeName(opaque_compiler_type_t type) { swift::Type swift_type(GetSwiftType(type)); swift::Type normalized_type = - swift_type.transform([](swift::Type type) -> swift::Type { + swift_type.transformRec([](swift::Type type) -> swift::Type { if (swift::SyntaxSugarType *syntax_sugar_type = swift::dyn_cast(type.getPointer())) { return syntax_sugar_type->getSinglyDesugaredType(); diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 921848ea4593b..5402fa1f8fdf1 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -905,7 +905,7 @@ TypeSystemSwiftTypeRef::GetSwiftified(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer TypeSystemSwiftTypeRef::GetNodeForPrintingImpl( swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, - bool resolve_objc_module, bool desugar) { + bool resolve_objc_module) { using namespace swift::Demangle; return Transform(dem, node, [&](NodePointer node) { NodePointer canonical = node; @@ -957,26 +957,19 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::GetNodeForPrintingImpl( } case Node::Kind::SugaredOptional: - // This is particularly silly. The outermost sugared Optional is - // desugared. See SwiftASTContext::GetTypeName() and remove it there, too! - if (desugar && node->getNumChildren() == 1) { - desugar = false; + if (node->getNumChildren() == 1) { return Desugar(dem, node, Node::Kind::BoundGenericEnum, Node::Kind::Enum, "Optional"); } return node; case Node::Kind::SugaredArray: - // See comment on SugaredOptional. - if (desugar && node->getNumChildren() == 1) { - desugar = false; + if (node->getNumChildren() == 1) { return Desugar(dem, node, Node::Kind::BoundGenericStructure, Node::Kind::Structure, "Array"); } return node; case Node::Kind::SugaredDictionary: - // See comment on SugaredOptional. - if (desugar && node->getNumChildren() == 1) { - desugar = false; + if (node->getNumChildren() == 1) { return Desugar(dem, node, Node::Kind::BoundGenericStructure, Node::Kind::Structure, "Dictionary"); } diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index b15d8e6a362f1..1d1be929b7d64 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -331,7 +331,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { swift::Demangle::NodePointer GetNodeForPrintingImpl(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, - bool resolve_objc_module, bool desugar = true); + bool resolve_objc_module); /// Return the demangle tree representation with all "__C" module /// names with their actual Clang module names. From 1f2c20f16bfd2218fc4808f30a7ff44d63ad25c4 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Tue, 30 Nov 2021 16:11:46 -0300 Subject: [PATCH 061/293] [lldb] Fix desugaring of dicts on TypeSystemSwiftTypeRef --- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index b4a04b68bab26..6eef507c94774 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -760,9 +760,12 @@ Desugar(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, type->addChild(concrete, dem); } NodePointer type_list = dem.createNode(Node::Kind::TypeList); - { + + assert(node->getNumChildren() >= 1 && node->getNumChildren() <= 2 && + "Sugared types should only have 1 or 2 children"); + for (NodePointer child : *node) { NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(node->getFirstChild(), dem); + type->addChild(child, dem); type_list->addChild(type, dem); } desugared->addChild(type, dem); @@ -969,7 +972,7 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::GetNodeForPrintingImpl( } return node; case Node::Kind::SugaredDictionary: - if (node->getNumChildren() == 1) { + if (node->getNumChildren() == 2) { return Desugar(dem, node, Node::Kind::BoundGenericStructure, Node::Kind::Structure, "Dictionary"); } @@ -2011,8 +2014,7 @@ bool TypeSystemSwiftTypeRef::IsPossibleDynamicType(opaque_compiler_type_t type, NodePointer type_list = node->getLastChild(); if (type_list->getKind() != Node::Kind::TypeList) return false; - for (size_t i = 0; i < type_list->getNumChildren(); ++i) { - NodePointer child = type_list->getChild(i); + for (NodePointer child : *type_list) { if (child->getKind() == Node::Kind::Type) { child = child->getFirstChild(); if (is_possible_dynamic(child)) From f7e500c2d796ff098a163bd0d38e43e5978818f2 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Wed, 1 Dec 2021 10:32:01 -0300 Subject: [PATCH 062/293] [lldb] Implement TypeSystemSwiftTypeRef::GetFullyUnqualifiedType --- .../Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index b4a04b68bab26..df01a6f43c701 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -3549,9 +3549,11 @@ TypeSystemSwiftTypeRef::GetTypedefedType(opaque_compiler_type_t type) { CompilerType TypeSystemSwiftTypeRef::GetFullyUnqualifiedType(opaque_compiler_type_t type) { - if (auto *swift_ast_context = GetSwiftASTContext()) - return swift_ast_context->GetFullyUnqualifiedType(ReconstructType(type)); - return {}; + LLDB_SCOPED_TIMER(); + auto impl = [&]() -> CompilerType { return {this, type}; }; + + VALIDATE_AND_RETURN(impl, GetFullyUnqualifiedType, type, + (ReconstructType(type)), (ReconstructType(type))); } uint32_t TypeSystemSwiftTypeRef::GetNumDirectBaseClasses(opaque_compiler_type_t type) { From a5c262237329d3800196820466d5ce5eac7f62ee Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Wed, 1 Dec 2021 11:11:48 -0300 Subject: [PATCH 063/293] [lldb] Implement GetFormat in terms of GetTypeInfo --- .../TypeSystem/Swift/SwiftASTContext.cpp | 90 ------------------- .../TypeSystem/Swift/SwiftASTContext.h | 2 - .../TypeSystem/Swift/TypeSystemSwift.cpp | 24 +++++ .../TypeSystem/Swift/TypeSystemSwift.h | 2 + .../Swift/TypeSystemSwiftTypeRef.cpp | 7 -- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 1 - 6 files changed, 26 insertions(+), 100 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 9ac0a04a78063..bd583314ea898 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -6361,96 +6361,6 @@ lldb::Encoding SwiftASTContext::GetEncoding(opaque_compiler_type_t type, return lldb::eEncodingInvalid; } -lldb::Format SwiftASTContext::GetFormat(opaque_compiler_type_t type) { - VALID_OR_RETURN_CHECK_TYPE(type, lldb::eFormatInvalid); - - swift::CanType swift_can_type(GetCanonicalSwiftType(type)); - - const swift::TypeKind type_kind = swift_can_type->getKind(); - switch (type_kind) { - case swift::TypeKind::BuiltinDefaultActorStorage: - case swift::TypeKind::BuiltinExecutor: - case swift::TypeKind::BuiltinJob: - case swift::TypeKind::BuiltinRawUnsafeContinuation: - case swift::TypeKind::Error: - case swift::TypeKind::Module: - case swift::TypeKind::InOut: - case swift::TypeKind::VariadicSequence: - case swift::TypeKind::Placeholder: - case swift::TypeKind::SILBlockStorage: - case swift::TypeKind::SILBox: - case swift::TypeKind::SILFunction: - case swift::TypeKind::SILToken: - case swift::TypeKind::TypeVariable: - case swift::TypeKind::Unresolved: - break; - case swift::TypeKind::BuiltinIntegerLiteral: - case swift::TypeKind::BuiltinInteger: - return eFormatDecimal; // TODO: detect if an integer is unsigned - case swift::TypeKind::BuiltinFloat: - return eFormatFloat; // TODO: detect if an integer is unsigned - - case swift::TypeKind::BuiltinRawPointer: - case swift::TypeKind::BuiltinNativeObject: - case swift::TypeKind::BuiltinUnsafeValueBuffer: - case swift::TypeKind::BuiltinBridgeObject: - case swift::TypeKind::PrimaryArchetype: - case swift::TypeKind::OpenedArchetype: - case swift::TypeKind::OpaqueTypeArchetype: - case swift::TypeKind::NestedArchetype: - case swift::TypeKind::GenericTypeParam: - case swift::TypeKind::DependentMember: - return eFormatAddressInfo; - - // Classes are always pointers in swift. - case swift::TypeKind::Class: - case swift::TypeKind::BoundGenericClass: - return eFormatHex; - - case swift::TypeKind::BuiltinVector: - break; - case swift::TypeKind::Tuple: - break; - case swift::TypeKind::UnmanagedStorage: - case swift::TypeKind::UnownedStorage: - case swift::TypeKind::WeakStorage: - return ToCompilerType(swift_can_type->getReferenceStorageReferent()) - .GetFormat(); - break; - - case swift::TypeKind::Enum: - case swift::TypeKind::BoundGenericEnum: - return eFormatUnsigned; - - case swift::TypeKind::GenericFunction: - case swift::TypeKind::Function: - return lldb::eFormatAddressInfo; - - case swift::TypeKind::Struct: - case swift::TypeKind::Protocol: - case swift::TypeKind::Metatype: - case swift::TypeKind::ProtocolComposition: - break; - case swift::TypeKind::LValue: - return lldb::eFormatHex; - case swift::TypeKind::UnboundGeneric: - case swift::TypeKind::BoundGenericStruct: - case swift::TypeKind::ExistentialMetatype: - case swift::TypeKind::DynamicSelf: - break; - - case swift::TypeKind::Optional: - case swift::TypeKind::TypeAlias: - case swift::TypeKind::Paren: - case swift::TypeKind::Dictionary: - case swift::TypeKind::ArraySlice: - assert(false && "Not a canonical type"); - break; - } - // We don't know hot to display this type. - return lldb::eFormatBytes; -} - uint32_t SwiftASTContext::GetNumChildren(opaque_compiler_type_t type, bool omit_empty_base_classes, const ExecutionContext *exe_ctx) { diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h index 88d8bc8fac2b8..719b54ccb73e1 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h @@ -617,8 +617,6 @@ class SwiftASTContext : public TypeSystemSwift { lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override; - lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; - uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes, const ExecutionContext *exe_ctx) override; diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp index 97d82e0039ca8..55c9b4cfda532 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp @@ -122,3 +122,27 @@ uint32_t TypeSystemSwift::GetIndexOfChildWithName( type, name, exe_ctx, omit_empty_base_classes, child_indexes); return num_child_indexes == 1 ? child_indexes.front() : UINT32_MAX; } + +lldb::Format TypeSystemSwift::GetFormat(opaque_compiler_type_t type) { + auto swift_flags = GetTypeInfo(type, nullptr); + + if (swift_flags & eTypeIsInteger) + return eFormatDecimal; + + if (swift_flags & eTypeIsFloat) + return eFormatFloat; + + if (swift_flags & eTypeIsPointer || swift_flags & eTypeIsClass) + return eFormatAddressInfo; + + if (swift_flags & eTypeIsClass) + return eFormatHex; + + if (swift_flags & eTypeIsGeneric) + return eFormatUnsigned; + + if (swift_flags & eTypeIsFuncPrototype || swift_flags & eTypeIsBlock) + return eFormatAddressInfo; + + return eFormatBytes; +} diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h index 855f8431a633e..9e6ba6aa2a540 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h @@ -168,6 +168,8 @@ class TypeSystemSwift : public TypeSystem { bool show_types, bool show_summary, bool verbose, uint32_t depth) override; + lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; + /// Unavailable hardcoded functions that don't make sense for Swift. /// \{ ConstString DeclContextGetName(void *opaque_decl_ctx) override { return {}; } diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index b4a04b68bab26..277907a289067 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -2512,13 +2512,6 @@ lldb::Encoding TypeSystemSwiftTypeRef::GetEncoding(opaque_compiler_type_t type, (ReconstructType(type), count)); } -lldb::Format TypeSystemSwiftTypeRef::GetFormat(opaque_compiler_type_t type) { - LLDB_SCOPED_TIMER(); - if (auto *swift_ast_context = GetSwiftASTContext()) - return swift_ast_context->GetFormat(ReconstructType(type)); - return {}; -} - uint32_t TypeSystemSwiftTypeRef::GetNumChildren(opaque_compiler_type_t type, bool omit_empty_base_classes, diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index 1d1be929b7d64..6627ec75ef47d 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -164,7 +164,6 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { ExecutionContextScope *exe_scope) override; lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override; - lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes, const ExecutionContext *exe_ctx) override; From 5efa8c076c21a60e1a6739dbef88d428fb93ca05 Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Wed, 1 Dec 2021 14:49:27 -0300 Subject: [PATCH 064/293] [lldb] Use Desugar function in GetCanonicalNode and remove duped code --- .../Swift/TypeSystemSwiftTypeRef.cpp | 148 +++++------------- 1 file changed, 40 insertions(+), 108 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 6eef507c94774..f164f2ec30af2 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -552,6 +552,40 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::Transform( return fn(node); } +/// Desugar a sugared type. +static swift::Demangle::NodePointer +Desugar(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, + swift::Demangle::Node::Kind bound_kind, + swift::Demangle::Node::Kind kind, llvm::StringRef name) { + LLDB_SCOPED_TIMER(); + + using namespace swift::Demangle; + NodePointer desugared = dem.createNode(bound_kind); + NodePointer type = dem.createNode(Node::Kind::Type); + { + NodePointer concrete = dem.createNode(kind); + NodePointer swift = + dem.createNodeWithAllocatedText(Node::Kind::Module, swift::STDLIB_NAME); + concrete->addChild(swift, dem); + NodePointer ident = + dem.createNodeWithAllocatedText(Node::Kind::Identifier, name); + concrete->addChild(ident, dem); + type->addChild(concrete, dem); + } + NodePointer type_list = dem.createNode(Node::Kind::TypeList); + + assert(node->getNumChildren() >= 1 && node->getNumChildren() <= 2 && + "Sugared types should only have 1 or 2 children"); + for (NodePointer child : *node) { + NodePointer type = dem.createNode(Node::Kind::Type); + type->addChild(child, dem); + type_list->addChild(type, dem); + } + desugared->addChild(type, dem); + desugared->addChild(type_list, dem); + return desugared; +} + /// Iteratively resolve all type aliases in \p node by looking up their /// desugared types in the debug info of module \p M. static swift::Demangle::NodePointer GetCanonicalNode( @@ -559,7 +593,6 @@ static swift::Demangle::NodePointer GetCanonicalNode( swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node) { using namespace swift::Demangle; return TypeSystemSwiftTypeRef::Transform(dem, node, [&](NodePointer node) { - NodePointer canonical = nullptr; auto kind = node->getKind(); switch (kind) { case Node::Kind::SugaredOptional: @@ -567,89 +600,22 @@ static swift::Demangle::NodePointer GetCanonicalNode( assert(node->getNumChildren() == 1); if (node->getNumChildren() != 1) return node; - - canonical = dem.createNode(Node::Kind::BoundGenericEnum); - { - NodePointer type = dem.createNode(Node::Kind::Type); - NodePointer e = dem.createNode(Node::Kind::Enum); - NodePointer module = dem.createNodeWithAllocatedText( - Node::Kind::Module, swift::STDLIB_NAME); - e->addChild(module, dem); - NodePointer optional = - dem.createNodeWithAllocatedText(Node::Kind::Identifier, "Optional"); - e->addChild(optional, dem); - type->addChild(e, dem); - canonical->addChild(type, dem); - } - { - NodePointer typelist = dem.createNode(Node::Kind::TypeList); - NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(node->getFirstChild(), dem); - typelist->addChild(type, dem); - canonical->addChild(typelist, dem); - } - return canonical; + return Desugar(dem, node, Node::Kind::BoundGenericEnum, Node::Kind::Enum, + "Optional"); case Node::Kind::SugaredArray: { assert(node->getNumChildren() == 1); if (node->getNumChildren() != 1) return node; - - canonical = dem.createNode(Node::Kind::BoundGenericStructure); - { - NodePointer type = dem.createNode(Node::Kind::Type); - NodePointer structure = dem.createNode(Node::Kind::Structure); - NodePointer module = dem.createNodeWithAllocatedText( - Node::Kind::Module, swift::STDLIB_NAME); - structure->addChild(module, dem); - NodePointer array = - dem.createNodeWithAllocatedText(Node::Kind::Identifier, "Array"); - structure->addChild(array, dem); - type->addChild(structure, dem); - canonical->addChild(type, dem); - } - { - NodePointer typelist = dem.createNode(Node::Kind::TypeList); - NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(node->getFirstChild(), dem); - typelist->addChild(type, dem); - canonical->addChild(typelist, dem); - } - return canonical; + return Desugar(dem, node, Node::Kind::BoundGenericStructure, + Node::Kind::Structure, "Array"); } case Node::Kind::SugaredDictionary: // FIXME: This isnt covered by any test. assert(node->getNumChildren() == 2); if (node->getNumChildren() != 2) return node; - - canonical = dem.createNode(Node::Kind::BoundGenericStructure); - { - NodePointer type = dem.createNode(Node::Kind::Type); - NodePointer structure = dem.createNode(Node::Kind::Structure); - NodePointer module = dem.createNodeWithAllocatedText( - Node::Kind::Module, swift::STDLIB_NAME); - structure->addChild(module, dem); - NodePointer dict = dem.createNodeWithAllocatedText( - Node::Kind::Identifier, "Dictionary"); - structure->addChild(dict, dem); - type->addChild(structure, dem); - canonical->addChild(type, dem); - } - { - NodePointer typelist = dem.createNode(Node::Kind::TypeList); - { - NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(node->getChild(0), dem); - typelist->addChild(type, dem); - } - { - NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(node->getChild(1), dem); - typelist->addChild(type, dem); - } - canonical->addChild(typelist, dem); - } - return canonical; + return Desugar(dem, node, Node::Kind::BoundGenericStructure, + Node::Kind::Structure, "Dictionary"); case Node::Kind::SugaredParen: assert(node->getNumChildren() == 1); if (node->getNumChildren() != 1) @@ -739,40 +705,6 @@ clang::api_notes::APINotesManager *TypeSystemSwiftTypeRef::GetAPINotesManager( return apinotes_manager.get(); } -/// Desugar a sugared type. -static swift::Demangle::NodePointer -Desugar(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, - swift::Demangle::Node::Kind bound_kind, - swift::Demangle::Node::Kind kind, llvm::StringRef name) { - LLDB_SCOPED_TIMER(); - - using namespace swift::Demangle; - NodePointer desugared = dem.createNode(bound_kind); - NodePointer type = dem.createNode(Node::Kind::Type); - { - NodePointer concrete = dem.createNode(kind); - NodePointer swift = - dem.createNodeWithAllocatedText(Node::Kind::Module, swift::STDLIB_NAME); - concrete->addChild(swift, dem); - NodePointer ident = - dem.createNodeWithAllocatedText(Node::Kind::Identifier, name); - concrete->addChild(ident, dem); - type->addChild(concrete, dem); - } - NodePointer type_list = dem.createNode(Node::Kind::TypeList); - - assert(node->getNumChildren() >= 1 && node->getNumChildren() <= 2 && - "Sugared types should only have 1 or 2 children"); - for (NodePointer child : *node) { - NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(child, dem); - type_list->addChild(type, dem); - } - desugared->addChild(type, dem); - desugared->addChild(type_list, dem); - return desugared; -} - /// Helper for \p GetSwiftName. template std::string ExtractSwiftName( From 559c82efabef184e33e4a17feaa9493ad7bc8f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Bolvansk=C3=BD?= Date: Wed, 13 Oct 2021 11:46:37 +0200 Subject: [PATCH 065/293] [NFC] Added test for PR49927 (cherry-picked from 005b715b543e) --- .../stores-of-existing-values.ll | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index 77f006a524547..6c4c16a94a5f0 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -282,3 +282,17 @@ bb3: store i32 0, i32* %P ret void } + +define void @pr49927(i32* %q, i32* %p) { +; CHECK-LABEL: @pr49927( +; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4 +; CHECK-NEXT: store i32 [[V]], i32* [[Q:%.*]], align 4 +; CHECK-NEXT: store i32 [[V]], i32* [[P]], align 4 +; CHECK-NEXT: ret void +; + %v = load i32, i32* %p, align 4 + store i32 %v, i32* %q, align 4 + ; FIXME: this store can be eliminated + store i32 %v, i32* %p, align 4 + ret void +} From e84ee17d07571ac4ea0c5bb0bf8130400df814dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20Bolvansk=C3=BD?= Date: Wed, 13 Oct 2021 12:15:44 +0200 Subject: [PATCH 066/293] [NFC] Added test for PR50339 (cherry-picked from 93fd30a16327) --- .../stores-of-existing-values.ll | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index 6c4c16a94a5f0..8abfcbf4444c5 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -3,6 +3,10 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +@a = external global [32 x i8], align 16 + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) + ; Test case for PR16520. The store in %if.then is dead, because the same value ; has been stored earlier to the same location. define void @test1_pr16520(i1 %b, i8* nocapture %r) { @@ -296,3 +300,16 @@ define void @pr49927(i32* %q, i32* %p) { store i32 %v, i32* %p, align 4 ret void } + + +define void @pr50339(i8* nocapture readonly %0) { +; CHECK-LABEL: @pr50339( +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) [[TMP0:%.*]], i64 16, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) [[TMP0]], i64 16, i1 false) +; CHECK-NEXT: ret void +; + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false) + ; FIXME: Eliminate the second memcpy as a "store of existing value" for this particular case, where both memcpy's are identical (same source, not just same dest). + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false) + ret void +} From 2f2d19db176634696d5d7b6874df603f90083fb1 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 22 Oct 2021 13:50:32 +0100 Subject: [PATCH 067/293] [DSE] Add test cases with more complex redundant stores. This patch adds more complex test cases with redundant stores of an existing memset, with other stores in between. It also makes a few of the existing tests more robust. (cherry-picked from 286e98b97ebe) --- .../memset-unknown-sizes.ll | 42 ++-- .../multiblock-throwing.ll | 37 +++- .../stores-of-existing-values.ll | 194 +++++++++++++++++- 3 files changed, 244 insertions(+), 29 deletions(-) diff --git a/llvm/test/Transforms/DeadStoreElimination/memset-unknown-sizes.ll b/llvm/test/Transforms/DeadStoreElimination/memset-unknown-sizes.ll index bbd0d01ee475f..d7fc00e3940a3 100644 --- a/llvm/test/Transforms/DeadStoreElimination/memset-unknown-sizes.ll +++ b/llvm/test/Transforms/DeadStoreElimination/memset-unknown-sizes.ll @@ -6,17 +6,17 @@ declare i8* @_Znwm() local_unnamed_addr #0 ; Function Attrs: argmemonly nounwind willreturn writeonly declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1 -define void @test1(i1 %c) { +define void @test1(i1 %c, i64 %N) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C:%.*]], label [[COND_TRUE_I_I_I:%.*]], label [[COND_END_I_I_I:%.*]] ; CHECK: cond.true.i.i.i: ; CHECK-NEXT: ret void ; CHECK: cond.end.i.i.i: -; CHECK-NEXT: [[CALL_I_I_I_I_I:%.*]] = tail call noalias nonnull i8* @_Znam() -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[CALL_I_I_I_I_I]] to i64* -; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 [[CALL_I_I_I_I_I]], i8 0, i64 undef, i1 false) -; CHECK-NEXT: store i64 0, i64* [[TMP0]], align 8 +; CHECK-NEXT: [[ALLOC:%.*]] = tail call noalias nonnull i8* @_Znam() #[[ATTR2:[0-9]+]] +; CHECK-NEXT: [[ALLOC_BC:%.*]] = bitcast i8* [[ALLOC]] to i64* +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 [[ALLOC]], i8 0, i64 [[N:%.*]], i1 false) #[[ATTR3:[0-9]+]] +; CHECK-NEXT: store i64 0, i64* [[ALLOC_BC]], align 8 ; CHECK-NEXT: ret void ; entry: @@ -26,26 +26,26 @@ cond.true.i.i.i: ; preds = %entry ret void cond.end.i.i.i: ; preds = %entry - %call.i.i.i.i.i = tail call noalias nonnull i8* @_Znam() #2 - %0 = bitcast i8* %call.i.i.i.i.i to i64* - tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %call.i.i.i.i.i, i8 0, i64 undef, i1 false) #3 - store i64 0, i64* %0, align 8 + %alloc = tail call noalias nonnull i8* @_Znam() #2 + %alloc.bc = bitcast i8* %alloc to i64* + tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %alloc, i8 0, i64 %N, i1 false) #3 + store i64 0, i64* %alloc.bc, align 8 ret void } -declare i8* @_Znam() local_unnamed_addr #0 +declare i8* @_Znam() -define void @test2(i1 %c) { +define void @test2(i1 %c, i64 %N) { ; CHECK-LABEL: @test2( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C:%.*]], label [[CLEANUP_CONT104:%.*]], label [[IF_THEN:%.*]] ; CHECK: if.then: -; CHECK-NEXT: [[MUL_I_I_I_I:%.*]] = shl nuw nsw i64 undef, 3 -; CHECK-NEXT: [[CALL_I_I_I_I_I_I131:%.*]] = call noalias nonnull i8* @_Znwm() -; CHECK-NEXT: [[DOTCAST_I_I:%.*]] = bitcast i8* [[CALL_I_I_I_I_I_I131]] to i64* -; CHECK-NEXT: store i64 0, i64* [[DOTCAST_I_I]], align 8 -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 [[CALL_I_I_I_I_I_I131]], i8 0, i64 [[MUL_I_I_I_I]], i1 false) +; CHECK-NEXT: [[MUL:%.*]] = shl nuw nsw i64 [[N:%.*]], 3 +; CHECK-NEXT: [[ALLOC:%.*]] = call noalias nonnull i8* @_Znwm() #[[ATTR2]] +; CHECK-NEXT: [[ALLOC_BC:%.*]] = bitcast i8* [[ALLOC]] to i64* +; CHECK-NEXT: store i64 0, i64* [[ALLOC_BC]], align 8 +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull align 8 [[ALLOC]], i8 0, i64 [[MUL]], i1 false) #[[ATTR3]] ; CHECK-NEXT: ret void ; CHECK: cleanup.cont104: ; CHECK-NEXT: ret void @@ -54,11 +54,11 @@ entry: br i1 %c, label %cleanup.cont104, label %if.then if.then: ; preds = %entry - %mul.i.i.i.i = shl nuw nsw i64 undef, 3 - %call.i.i.i.i.i.i131 = call noalias nonnull i8* @_Znwm() #2 - %.cast.i.i = bitcast i8* %call.i.i.i.i.i.i131 to i64* - store i64 0, i64* %.cast.i.i, align 8 - call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %call.i.i.i.i.i.i131, i8 0, i64 %mul.i.i.i.i, i1 false) #3 + %mul = shl nuw nsw i64 %N, 3 + %alloc = call noalias nonnull i8* @_Znwm() #2 + %alloc.bc = bitcast i8* %alloc to i64* + store i64 0, i64* %alloc.bc, align 8 + call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %alloc, i8 0, i64 %mul, i1 false) #3 ret void cleanup.cont104: ; preds = %entry diff --git a/llvm/test/Transforms/DeadStoreElimination/multiblock-throwing.ll b/llvm/test/Transforms/DeadStoreElimination/multiblock-throwing.ll index c067a907892d9..2033b34e05159 100644 --- a/llvm/test/Transforms/DeadStoreElimination/multiblock-throwing.ll +++ b/llvm/test/Transforms/DeadStoreElimination/multiblock-throwing.ll @@ -4,9 +4,9 @@ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" declare void @unknown_func() -define void @test6(i32* noalias %P) { -; CHECK-LABEL: @test6( -; CHECK-NEXT: store i32 0, i32* [[P:%.*]] +define void @test6_store_same_value(i32* noalias %P) { +; CHECK-LABEL: @test6_store_same_value( +; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 ; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: ; CHECK-NEXT: br label [[BB3:%.*]] @@ -14,7 +14,7 @@ define void @test6(i32* noalias %P) { ; CHECK-NEXT: call void @unknown_func() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: store i32 0, i32* [[P]] +; CHECK-NEXT: store i32 0, i32* [[P]], align 4 ; CHECK-NEXT: ret void ; store i32 0, i32* %P @@ -29,6 +29,31 @@ bb3: ret void } +define void @test6_store_other_value(i32* noalias %P) { +; CHECK-LABEL: @test6_store_other_value( +; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 +; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: call void @unknown_func() +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: store i32 1, i32* [[P]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, i32* %P + br i1 true, label %bb1, label %bb2 +bb1: + br label %bb3 +bb2: + call void @unknown_func() + br label %bb3 +bb3: + store i32 1, i32* %P + ret void +} + define void @test23(i32* noalias %P) { ; CHECK-LABEL: @test23( ; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] @@ -38,7 +63,7 @@ define void @test23(i32* noalias %P) { ; CHECK-NEXT: call void @unknown_func() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: store i32 0, i32* [[P:%.*]] +; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 ; CHECK-NEXT: ret void ; br i1 true, label %bb1, label %bb2 @@ -63,7 +88,7 @@ define void @test24(i32* noalias %P) { ; CHECK-NEXT: call void @unknown_func() ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: -; CHECK-NEXT: store i32 0, i32* [[P:%.*]] +; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 ; CHECK-NEXT: ret void ; br i1 true, label %bb2, label %bb1 diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index 8abfcbf4444c5..509d4e9763fe9 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -235,7 +235,7 @@ bb3: } ; Make sure the store in %bb3 won't be eliminated because it may be clobbered before. -define void @test8(i32* noalias %P) { +define void @test8(i32* %P) { ; CHECK-LABEL: @test8( ; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 ; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]] @@ -287,6 +287,197 @@ bb3: ret void } +; The store in bb3 can be eliminated, because the store in bb1 cannot alias it. +define void @test10(i32* noalias %P, i32* %Q, i1 %c) { +; CHECK-LABEL: @test10( +; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 +; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: store i32 10, i32* [[Q:%.*]], align 4 +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: ret void +; CHECK: bb3: +; CHECK-NEXT: store i32 0, i32* [[P]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, i32* %P + br i1 %c, label %bb1, label %bb2 + +bb1: + store i32 10, i32* %Q + br label %bb3 + +bb2: + ret void + +bb3: + store i32 0, i32* %P + ret void +} + +define void @test11_smaller_later_store(i32* noalias %P, i32* %Q, i1 %c) { +; CHECK-LABEL: @test11_smaller_later_store( +; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 +; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: ret void +; CHECK: bb3: +; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[P]] to i8* +; CHECK-NEXT: store i8 0, i8* [[BC]], align 1 +; CHECK-NEXT: ret void +; + store i32 0, i32* %P + br i1 %c, label %bb1, label %bb2 + +bb1: + br label %bb3 + +bb2: + ret void + +bb3: + %bc = bitcast i32* %P to i8* + store i8 0, i8* %bc + ret void +} + +define void @test11_smaller_earlier_store(i32* noalias %P, i32* %Q, i1 %c) { +; CHECK-LABEL: @test11_smaller_earlier_store( +; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[P:%.*]] to i8* +; CHECK-NEXT: store i8 0, i8* [[BC]], align 1 +; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: ret void +; CHECK: bb3: +; CHECK-NEXT: store i32 0, i32* [[P]], align 4 +; CHECK-NEXT: ret void +; + %bc = bitcast i32* %P to i8* + store i8 0, i8* %bc + br i1 %c, label %bb1, label %bb2 + +bb1: + br label %bb3 + +bb2: + ret void + +bb3: + store i32 0, i32* %P + ret void +} + +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1 + +define void @test12_memset_simple(i8* %ptr) { +; CHECK-LABEL: @test12_memset_simple( +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) +; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 +; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1 +; CHECK-NEXT: ret void +; + call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false) + %ptr.5 = getelementptr i8, i8* %ptr, i64 4 + store i8 0, i8* %ptr.5 + ret void +} + +define void @test12_memset_other_store_in_between(i8* %ptr) { +; CHECK-LABEL: @test12_memset_other_store_in_between( +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) +; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 +; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1 +; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5 +; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1 +; CHECK-NEXT: ret void +; + call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false) + %ptr.4 = getelementptr i8, i8* %ptr, i64 4 + store i8 8, i8* %ptr.4 + %ptr.5 = getelementptr i8, i8* %ptr, i64 5 + store i8 0, i8* %ptr.5 + ret void +} + +define void @test12_memset_other_store_in_between_partial_overlap(i8* %ptr) { +; CHECK-LABEL: @test12_memset_other_store_in_between_partial_overlap( +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) +; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 +; CHECK-NEXT: [[BC_4:%.*]] = bitcast i8* [[PTR_4]] to i16* +; CHECK-NEXT: store i16 8, i16* [[BC_4]], align 2 +; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5 +; CHECK-NEXT: [[BC_5:%.*]] = bitcast i8* [[PTR_5]] to i16* +; CHECK-NEXT: store i16 0, i16* [[BC_5]], align 2 +; CHECK-NEXT: ret void +; + call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false) + %ptr.4 = getelementptr i8, i8* %ptr, i64 4 + %bc.4 = bitcast i8* %ptr.4 to i16* + store i16 8, i16* %bc.4 + %ptr.5 = getelementptr i8, i8* %ptr, i64 5 + %bc.5 = bitcast i8* %ptr.5 to i16* + store i16 0, i16* %bc.5 + ret void +} + +define void @test12_memset_later_store_exceeds_memset(i8* %ptr) { +; CHECK-LABEL: @test12_memset_later_store_exceeds_memset( +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[PTR:%.*]], i8 0, i64 8, i1 false) +; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 +; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1 +; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 8 +; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR_5]] to i64* +; CHECK-NEXT: store i64 0, i64* [[BC]], align 8 +; CHECK-NEXT: ret void +; + call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false) + %ptr.4 = getelementptr i8, i8* %ptr, i64 4 + store i8 8, i8* %ptr.4 + %ptr.5 = getelementptr i8, i8* %ptr, i64 8 + %bc = bitcast i8* %ptr.5 to i64* + store i64 0, i64* %bc + ret void +} + +define void @test12_memset_later_store_before_memset(i8* %ptr) { +; CHECK-LABEL: @test12_memset_later_store_before_memset( +; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i64 1 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[PTR_1]], i64 7 +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 3, i1 false) +; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[PTR]] to i64* +; CHECK-NEXT: store i64 0, i64* [[BC]], align 8 +; CHECK-NEXT: ret void +; + %ptr.1 = getelementptr i8, i8* %ptr, i64 1 + call void @llvm.memset.p0i8.i64(i8* %ptr.1, i8 0, i64 10, i1 false) + %ptr.4 = getelementptr i8, i8* %ptr, i64 4 + store i8 8, i8* %ptr.4 + %bc = bitcast i8* %ptr to i64* + store i64 0, i64* %bc + ret void +} + +; The memset will be shortened and the store will not be redundant afterwards. +; It cannot be eliminated. +define void @test13_memset_shortened(i64* %ptr) { +; CHECK-LABEL: @test13_memset_shortened( +; CHECK-NEXT: [[PTR_I8:%.*]] = bitcast i64* [[PTR:%.*]] to i8* +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[PTR_I8]], i64 8 +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[TMP1]], i8 0, i64 16, i1 false) +; CHECK-NEXT: store i64 0, i64* [[PTR]], align 8 +; CHECK-NEXT: ret void +; + %ptr.i8 = bitcast i64* %ptr to i8* + call void @llvm.memset.p0i8.i64(i8* %ptr.i8, i8 0, i64 24, i1 false) + store i64 0, i64* %ptr + ret void +} + define void @pr49927(i32* %q, i32* %p) { ; CHECK-LABEL: @pr49927( ; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4 @@ -301,7 +492,6 @@ define void @pr49927(i32* %q, i32* %p) { ret void } - define void @pr50339(i8* nocapture readonly %0) { ; CHECK-LABEL: @pr50339( ; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) [[TMP0:%.*]], i64 16, i1 false) From 8b29c5ca98d55389114f84c252aaf1b83e7203c9 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 27 Oct 2021 11:15:58 +0100 Subject: [PATCH 068/293] [DSE] Add test case with 2 memcpys that should not be eliminated. (cherry-picked from 1a2a7cca3e43) --- .../stores-of-existing-values.ll | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index 509d4e9763fe9..0380e80a83a8c 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -503,3 +503,20 @@ define void @pr50339(i8* nocapture readonly %0) { tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 16 dereferenceable(16) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), i8* noundef nonnull align 1 dereferenceable(16) %0, i64 16, i1 false) ret void } + +; Cannot remove the second memcpy as redundant store, because %src is modified +; in between. +define i8 @memset_optimized_access(i8* noalias %dst, i8* noalias %src) { +; CHECK-LABEL: @memset_optimized_access( +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST:%.*]], i8* [[SRC:%.*]], i64 16, i1 false) +; CHECK-NEXT: store i8 99, i8* [[SRC]], align 1 +; CHECK-NEXT: [[L:%.*]] = load i8, i8* [[DST]], align 1 +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DST]], i8* [[SRC]], i64 16, i1 false) +; CHECK-NEXT: ret i8 [[L]] +; + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 16, i1 false) + store i8 99, i8* %src + %l = load i8, i8* %dst + tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 16, i1 false) + ret i8 %l +} From 15ca6a059aebdc2506c29950930b9f832ed8b17a Mon Sep 17 00:00:00 2001 From: Dawid Jurczak Date: Fri, 22 Oct 2021 14:11:12 +0200 Subject: [PATCH 069/293] [DSE] Eliminates redundant store of an exisiting value (PR16520) That's https://reviews.llvm.org/D90328 follow-up. This change eliminates writes to variables where the value that is being written is already stored in the variable. This achieves the goal by looping through all memory definitions in the current state and getting defining access from each of them. When there is defining access where the write instruction is identical to the original instruction it will remove this redundant write. For example: void f() { x = 1; if foo() { x = 1; g(); } else { h(); } } void g(); void h(); The second x=1 will be eliminated since it is rewriting 1 to x. This pass will produce this: void f() { x = 1; if foo() { g(); } else { h(); } } void g(); void h(); Differential Revision: https://reviews.llvm.org/D111727 (cherry-picked from f87e0c68d786) --- .../Scalar/DeadStoreElimination.cpp | 29 ++++++++++ .../stores-of-existing-values.ll | 56 ++++++++++++++++--- 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index f1f911b59212a..945bfe6a063db 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1871,6 +1871,34 @@ struct DSEState { return false; } + + /// Eliminates writes to locations where the value that is being written + /// is already stored at the same location. + bool eliminateRedundantStoresOfExistingValues() { + bool MadeChange = false; + LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs that write the " + "already existing value\n"); + for (auto *Def : MemDefs) { + if (SkipStores.contains(Def) || MSSA.isLiveOnEntryDef(Def) || + !isRemovable(Def->getMemoryInst())) + continue; + auto *UpperDef = dyn_cast(Def->getDefiningAccess()); + if (!UpperDef || MSSA.isLiveOnEntryDef(UpperDef)) + continue; + auto *DefInst = Def->getMemoryInst(); + auto *UpperInst = UpperDef->getMemoryInst(); + auto MaybeUpperLoc = getLocForWriteEx(UpperInst); + if (!MaybeUpperLoc || !DefInst->isIdenticalTo(UpperInst) || + isReadClobber(*MaybeUpperLoc, DefInst)) + continue; + LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *DefInst + << '\n'); + deleteDeadInstruction(DefInst); + NumRedundantStores++; + MadeChange = true; + } + return MadeChange; + } }; static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, @@ -2036,6 +2064,7 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, for (auto &KV : State.IOLs) MadeChange |= removePartiallyOverlappedStores(State.DL, KV.second, TLI); + MadeChange |= State.eliminateRedundantStoresOfExistingValues(); MadeChange |= State.eliminateDeadWritesAtEndOfFunction(); return MadeChange; } diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index 0380e80a83a8c..7888a393f5218 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -7,7 +7,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) -; Test case for PR16520. The store in %if.then is dead, because the same value +; Test case for PR16520. The store in %if.then is redundant, because the same value ; has been stored earlier to the same location. define void @test1_pr16520(i1 %b, i8* nocapture %r) { ; CHECK-LABEL: @test1_pr16520( @@ -15,7 +15,6 @@ define void @test1_pr16520(i1 %b, i8* nocapture %r) { ; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; CHECK: if.then: -; CHECK-NEXT: store i8 1, i8* [[R]], align 1 ; CHECK-NEXT: tail call void @fn_mayread_or_clobber() ; CHECK-NEXT: br label [[IF_END:%.*]] ; CHECK: if.else: @@ -42,8 +41,6 @@ if.end: ; preds = %if.else, %if.then } declare void @fn_mayread_or_clobber() - - declare void @fn_readonly() readonly define void @test2(i1 %b, i8* nocapture %r) { @@ -58,7 +55,6 @@ define void @test2(i1 %b, i8* nocapture %r) { ; CHECK-NEXT: tail call void @fn_readonly() ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: -; CHECK-NEXT: store i8 1, i8* [[R]], align 1 ; CHECK-NEXT: ret void ; entry: @@ -78,6 +74,39 @@ if.end: ; preds = %if.else, %if.then ret void } +; Make sure volatile stores are not removed. +define void @test2_volatile(i1 %b, i8* nocapture %r) { +; CHECK-LABEL: @test2_volatile( +; CHECK-NEXT: entry: +; CHECK-NEXT: store volatile i8 1, i8* [[R:%.*]], align 1 +; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: tail call void @fn_readonly() +; CHECK-NEXT: br label [[IF_END:%.*]] +; CHECK: if.else: +; CHECK-NEXT: tail call void @fn_readonly() +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: store volatile i8 1, i8* [[R]], align 1 +; CHECK-NEXT: ret void +; +entry: + store volatile i8 1, i8* %r, align 1 + br i1 %b, label %if.then, label %if.else + +if.then: ; preds = %entry + tail call void @fn_readonly() + br label %if.end + +if.else: ; preds = %entry + tail call void @fn_readonly() + br label %if.end + +if.end: ; preds = %if.else, %if.then + store volatile i8 1, i8* %r, align 1 + ret void +} + define void @test3(i1 %b, i8* nocapture %r) { ; CHECK-LABEL: @test3( ; CHECK-NEXT: entry: @@ -185,7 +214,6 @@ define void @test6(i32* noalias %P) { ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]] ; CHECK: for.body: -; CHECK-NEXT: store i32 1, i32* [[P]], align 4 ; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[P]], align 4 ; CHECK-NEXT: br label [[FOR_HEADER]] ; CHECK: end: @@ -220,7 +248,6 @@ define void @test7(i32* noalias %P) { ; CHECK: bb2: ; CHECK-NEXT: ret void ; CHECK: bb3: -; CHECK-NEXT: store i32 0, i32* [[P]], align 4 ; CHECK-NEXT: ret void ; store i32 0, i32* %P @@ -272,7 +299,6 @@ define void @test9(i32* noalias %P) { ; CHECK-NEXT: call void @fn_mayread_or_clobber() ; CHECK-NEXT: ret void ; CHECK: bb3: -; CHECK-NEXT: store i32 0, i32* [[P]], align 4 ; CHECK-NEXT: ret void ; store i32 0, i32* %P @@ -478,6 +504,20 @@ define void @test13_memset_shortened(i64* %ptr) { ret void } +declare i8* @strcat(i8*, i8*) nounwind argmemonly + +define void @test14_strcat(i8* noalias %P, i8* noalias %Q) { +; CHECK-LABEL: @test14_strcat( +; CHECK-NEXT: call i8* @strcat(i8* [[P:%.*]], i8* [[Q:%.*]]) +; CHECK-NEXT: call i8* @strcat(i8* [[P]], i8* [[Q]]) +; CHECK-NEXT: ret void +; + %call1 = call i8* @strcat(i8* %P, i8* %Q) + ; FIXME: Eliminate the second strcat as a "store of existing value" for this particular case, where both strcat's are identical (same source, not just same dest). + %call2 = call i8* @strcat(i8* %P, i8* %Q) + ret void +} + define void @pr49927(i32* %q, i32* %p) { ; CHECK-LABEL: @pr49927( ; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4 From f06bec9baf3897fb9c8241081fc0d37d076128ba Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 29 Oct 2021 21:58:42 +0100 Subject: [PATCH 070/293] [DSE] Support redundant stores eliminated by memset. This patch adds support to remove stores that write the same value as earlier memesets. It uses isOverwrite to check that a memset completely overwrites a later store. The candidate store must store the same bytewise value as the byte stored by the memset. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D112321 (cherry-picked from 274a9b0f0b4e) --- .../Scalar/DeadStoreElimination.cpp | 28 +++++++++++++++++-- .../stores-of-existing-values.ll | 2 -- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 945bfe6a063db..c1eef0b3cf900 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1885,10 +1885,32 @@ struct DSEState { auto *UpperDef = dyn_cast(Def->getDefiningAccess()); if (!UpperDef || MSSA.isLiveOnEntryDef(UpperDef)) continue; - auto *DefInst = Def->getMemoryInst(); - auto *UpperInst = UpperDef->getMemoryInst(); + + Instruction *DefInst = Def->getMemoryInst(); + Instruction *UpperInst = UpperDef->getMemoryInst(); + auto IsRedundantStore = [this, DefInst, + UpperInst](MemoryLocation UpperLoc) { + if (DefInst->isIdenticalTo(UpperInst)) + return true; + if (auto *MemSetI = dyn_cast(UpperInst)) { + if (auto *SI = dyn_cast(DefInst)) { + auto MaybeDefLoc = getLocForWriteEx(DefInst); + if (!MaybeDefLoc) + return false; + int64_t InstWriteOffset = 0; + int64_t DepWriteOffset = 0; + auto OR = isOverwrite(UpperInst, DefInst, UpperLoc, *MaybeDefLoc, + InstWriteOffset, DepWriteOffset); + Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL); + return StoredByte && StoredByte == MemSetI->getOperand(1) && + OR == OW_Complete; + } + } + return false; + }; + auto MaybeUpperLoc = getLocForWriteEx(UpperInst); - if (!MaybeUpperLoc || !DefInst->isIdenticalTo(UpperInst) || + if (!MaybeUpperLoc || !IsRedundantStore(*MaybeUpperLoc) || isReadClobber(*MaybeUpperLoc, DefInst)) continue; LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *DefInst diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index 7888a393f5218..8419dcadf3e19 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -403,8 +403,6 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) define void @test12_memset_simple(i8* %ptr) { ; CHECK-LABEL: @test12_memset_simple( ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) -; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 -; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1 ; CHECK-NEXT: ret void ; call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false) From 944f5d03bb52c6d4225d90024380a2f849f8abad Mon Sep 17 00:00:00 2001 From: Evgeniy Brevnov Date: Wed, 28 Jul 2021 17:13:45 +0700 Subject: [PATCH 071/293] [DSE][NFC] Rename Later->Killing, Earlier->Dead First (and biggest) change is to use "Killing/Dead" in place of "Later/Earlier" base for names in DSE. For example, [Maybe]DeadLoc - is a location killed by KillingI instruction. I believe such names are more descriptive and easy to understand than current ones. Second, there are inconsistencies in naming where different names are used for the same thing. Fixed that too. Third, reordered parameters of isPartialOverwrite, tryToMergePartialOverlappingStores, isOverwrite to make them consistent between each other. This greatly reduces potential mistakes. Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D106947 (cherry-picked from 129cf336041f) --- .../Scalar/DeadStoreElimination.cpp | 781 +++++++++--------- 1 file changed, 393 insertions(+), 388 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index c1eef0b3cf900..d4cf3713c7e64 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -13,10 +13,10 @@ // in between both MemoryDefs. A bit more concretely: // // For all MemoryDefs StartDef: -// 1. Get the next dominating clobbering MemoryDef (EarlierAccess) by walking +// 1. Get the next dominating clobbering MemoryDef (MaybeDeadAccess) by walking // upwards. -// 2. Check that there are no reads between EarlierAccess and the StartDef by -// checking all uses starting at EarlierAccess and walking until we see +// 2. Check that there are no reads between MaybeDeadAccess and the StartDef by +// checking all uses starting at MaybeDeadAccess and walking until we see // StartDef. // 3. For each found CurrentDef, check that: // 1. There are no barrier instructions between CurrentDef and StartDef (like @@ -333,147 +333,146 @@ enum OverwriteResult { } // end anonymous namespace /// Check if two instruction are masked stores that completely -/// overwrite one another. More specifically, \p Later has to -/// overwrite \p Earlier. -static OverwriteResult isMaskedStoreOverwrite(const Instruction *Later, - const Instruction *Earlier, +/// overwrite one another. More specifically, \p KillingI has to +/// overwrite \p DeadI. +static OverwriteResult isMaskedStoreOverwrite(const Instruction *KillingI, + const Instruction *DeadI, BatchAAResults &AA) { - const auto *IIL = dyn_cast(Later); - const auto *IIE = dyn_cast(Earlier); - if (IIL == nullptr || IIE == nullptr) + const auto *KillingII = dyn_cast(KillingI); + const auto *DeadII = dyn_cast(DeadI); + if (KillingII == nullptr || DeadII == nullptr) return OW_Unknown; - if (IIL->getIntrinsicID() != Intrinsic::masked_store || - IIE->getIntrinsicID() != Intrinsic::masked_store) + if (KillingII->getIntrinsicID() != Intrinsic::masked_store || + DeadII->getIntrinsicID() != Intrinsic::masked_store) return OW_Unknown; // Pointers. - Value *LP = IIL->getArgOperand(1)->stripPointerCasts(); - Value *EP = IIE->getArgOperand(1)->stripPointerCasts(); - if (LP != EP && !AA.isMustAlias(LP, EP)) + Value *KillingPtr = KillingII->getArgOperand(1)->stripPointerCasts(); + Value *DeadPtr = DeadII->getArgOperand(1)->stripPointerCasts(); + if (KillingPtr != DeadPtr && !AA.isMustAlias(KillingPtr, DeadPtr)) return OW_Unknown; // Masks. - // TODO: check that Later's mask is a superset of the Earlier's mask. - if (IIL->getArgOperand(3) != IIE->getArgOperand(3)) + // TODO: check that KillingII's mask is a superset of the DeadII's mask. + if (KillingII->getArgOperand(3) != DeadII->getArgOperand(3)) return OW_Unknown; return OW_Complete; } -/// Return 'OW_Complete' if a store to the 'Later' location completely -/// overwrites a store to the 'Earlier' location, 'OW_End' if the end of the -/// 'Earlier' location is completely overwritten by 'Later', 'OW_Begin' if the -/// beginning of the 'Earlier' location is overwritten by 'Later'. -/// 'OW_PartialEarlierWithFullLater' means that an earlier (big) store was -/// overwritten by a latter (smaller) store which doesn't write outside the big +/// Return 'OW_Complete' if a store to the 'KillingLoc' location completely +/// overwrites a store to the 'DeadLoc' location, 'OW_End' if the end of the +/// 'DeadLoc' location is completely overwritten by 'KillingLoc', 'OW_Begin' +/// if the beginning of the 'DeadLoc' location is overwritten by 'KillingLoc'. +/// 'OW_PartialEarlierWithFullLater' means that a dead (big) store was +/// overwritten by a killing (smaller) store which doesn't write outside the big /// store's memory locations. Returns 'OW_Unknown' if nothing can be determined. -/// NOTE: This function must only be called if both \p Later and \p Earlier -/// write to the same underlying object with valid \p EarlierOff and \p -/// LaterOff. -static OverwriteResult isPartialOverwrite(const MemoryLocation &Later, - const MemoryLocation &Earlier, - int64_t EarlierOff, int64_t LaterOff, - Instruction *DepWrite, +/// NOTE: This function must only be called if both \p KillingLoc and \p +/// DeadLoc belong to the same underlying object with valid \p KillingOff and +/// \p DeadOff. +static OverwriteResult isPartialOverwrite(const MemoryLocation &KillingLoc, + const MemoryLocation &DeadLoc, + int64_t KillingOff, int64_t DeadOff, + Instruction *DeadI, InstOverlapIntervalsTy &IOL) { - const uint64_t LaterSize = Later.Size.getValue(); - const uint64_t EarlierSize = Earlier.Size.getValue(); + const uint64_t KillingSize = KillingLoc.Size.getValue(); + const uint64_t DeadSize = DeadLoc.Size.getValue(); // We may now overlap, although the overlap is not complete. There might also // be other incomplete overlaps, and together, they might cover the complete - // earlier write. + // dead store. // Note: The correctness of this logic depends on the fact that this function // is not even called providing DepWrite when there are any intervening reads. if (EnablePartialOverwriteTracking && - LaterOff < int64_t(EarlierOff + EarlierSize) && - int64_t(LaterOff + LaterSize) >= EarlierOff) { + KillingOff < int64_t(DeadOff + DeadSize) && + int64_t(KillingOff + KillingSize) >= DeadOff) { // Insert our part of the overlap into the map. - auto &IM = IOL[DepWrite]; - LLVM_DEBUG(dbgs() << "DSE: Partial overwrite: Earlier [" << EarlierOff - << ", " << int64_t(EarlierOff + EarlierSize) - << ") Later [" << LaterOff << ", " - << int64_t(LaterOff + LaterSize) << ")\n"); + auto &IM = IOL[DeadI]; + LLVM_DEBUG(dbgs() << "DSE: Partial overwrite: DeadLoc [" << DeadOff << ", " + << int64_t(DeadOff + DeadSize) << ") KillingLoc [" + << KillingOff << ", " << int64_t(KillingOff + KillingSize) + << ")\n"); // Make sure that we only insert non-overlapping intervals and combine // adjacent intervals. The intervals are stored in the map with the ending // offset as the key (in the half-open sense) and the starting offset as // the value. - int64_t LaterIntStart = LaterOff, LaterIntEnd = LaterOff + LaterSize; + int64_t KillingIntStart = KillingOff; + int64_t KillingIntEnd = KillingOff + KillingSize; - // Find any intervals ending at, or after, LaterIntStart which start - // before LaterIntEnd. - auto ILI = IM.lower_bound(LaterIntStart); - if (ILI != IM.end() && ILI->second <= LaterIntEnd) { + // Find any intervals ending at, or after, KillingIntStart which start + // before KillingIntEnd. + auto ILI = IM.lower_bound(KillingIntStart); + if (ILI != IM.end() && ILI->second <= KillingIntEnd) { // This existing interval is overlapped with the current store somewhere - // in [LaterIntStart, LaterIntEnd]. Merge them by erasing the existing + // in [KillingIntStart, KillingIntEnd]. Merge them by erasing the existing // intervals and adjusting our start and end. - LaterIntStart = std::min(LaterIntStart, ILI->second); - LaterIntEnd = std::max(LaterIntEnd, ILI->first); + KillingIntStart = std::min(KillingIntStart, ILI->second); + KillingIntEnd = std::max(KillingIntEnd, ILI->first); ILI = IM.erase(ILI); // Continue erasing and adjusting our end in case other previous // intervals are also overlapped with the current store. // - // |--- ealier 1 ---| |--- ealier 2 ---| - // |------- later---------| + // |--- dead 1 ---| |--- dead 2 ---| + // |------- killing---------| // - while (ILI != IM.end() && ILI->second <= LaterIntEnd) { - assert(ILI->second > LaterIntStart && "Unexpected interval"); - LaterIntEnd = std::max(LaterIntEnd, ILI->first); + while (ILI != IM.end() && ILI->second <= KillingIntEnd) { + assert(ILI->second > KillingIntStart && "Unexpected interval"); + KillingIntEnd = std::max(KillingIntEnd, ILI->first); ILI = IM.erase(ILI); } } - IM[LaterIntEnd] = LaterIntStart; + IM[KillingIntEnd] = KillingIntStart; ILI = IM.begin(); - if (ILI->second <= EarlierOff && - ILI->first >= int64_t(EarlierOff + EarlierSize)) { - LLVM_DEBUG(dbgs() << "DSE: Full overwrite from partials: Earlier [" - << EarlierOff << ", " - << int64_t(EarlierOff + EarlierSize) - << ") Composite Later [" << ILI->second << ", " + if (ILI->second <= DeadOff && ILI->first >= int64_t(DeadOff + DeadSize)) { + LLVM_DEBUG(dbgs() << "DSE: Full overwrite from partials: DeadLoc [" + << DeadOff << ", " << int64_t(DeadOff + DeadSize) + << ") Composite KillingLoc [" << ILI->second << ", " << ILI->first << ")\n"); ++NumCompletePartials; return OW_Complete; } } - // Check for an earlier store which writes to all the memory locations that - // the later store writes to. - if (EnablePartialStoreMerging && LaterOff >= EarlierOff && - int64_t(EarlierOff + EarlierSize) > LaterOff && - uint64_t(LaterOff - EarlierOff) + LaterSize <= EarlierSize) { - LLVM_DEBUG(dbgs() << "DSE: Partial overwrite an earlier load [" - << EarlierOff << ", " - << int64_t(EarlierOff + EarlierSize) - << ") by a later store [" << LaterOff << ", " - << int64_t(LaterOff + LaterSize) << ")\n"); + // Check for a dead store which writes to all the memory locations that + // the killing store writes to. + if (EnablePartialStoreMerging && KillingOff >= DeadOff && + int64_t(DeadOff + DeadSize) > KillingOff && + uint64_t(KillingOff - DeadOff) + KillingSize <= DeadSize) { + LLVM_DEBUG(dbgs() << "DSE: Partial overwrite a dead load [" << DeadOff + << ", " << int64_t(DeadOff + DeadSize) + << ") by a killing store [" << KillingOff << ", " + << int64_t(KillingOff + KillingSize) << ")\n"); // TODO: Maybe come up with a better name? return OW_PartialEarlierWithFullLater; } - // Another interesting case is if the later store overwrites the end of the - // earlier store. + // Another interesting case is if the killing store overwrites the end of the + // dead store. // - // |--earlier--| - // |-- later --| + // |--dead--| + // |-- killing --| // - // In this case we may want to trim the size of earlier to avoid generating - // writes to addresses which will definitely be overwritten later + // In this case we may want to trim the size of dead store to avoid + // generating stores to addresses which will definitely be overwritten killing + // store. if (!EnablePartialOverwriteTracking && - (LaterOff > EarlierOff && LaterOff < int64_t(EarlierOff + EarlierSize) && - int64_t(LaterOff + LaterSize) >= int64_t(EarlierOff + EarlierSize))) + (KillingOff > DeadOff && KillingOff < int64_t(DeadOff + DeadSize) && + int64_t(KillingOff + KillingSize) >= int64_t(DeadOff + DeadSize))) return OW_End; - // Finally, we also need to check if the later store overwrites the beginning - // of the earlier store. + // Finally, we also need to check if the killing store overwrites the + // beginning of the dead store. // - // |--earlier--| - // |-- later --| + // |--dead--| + // |-- killing --| // // In this case we may want to move the destination address and trim the size - // of earlier to avoid generating writes to addresses which will definitely - // be overwritten later. + // of dead store to avoid generating stores to addresses which will definitely + // be overwritten killing store. if (!EnablePartialOverwriteTracking && - (LaterOff <= EarlierOff && int64_t(LaterOff + LaterSize) > EarlierOff)) { - assert(int64_t(LaterOff + LaterSize) < int64_t(EarlierOff + EarlierSize) && + (KillingOff <= DeadOff && int64_t(KillingOff + KillingSize) > DeadOff)) { + assert(int64_t(KillingOff + KillingSize) < int64_t(DeadOff + DeadSize) && "Expect to be handled as OW_Complete"); return OW_Begin; } @@ -568,11 +567,11 @@ memoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI, return true; } -static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierStart, - uint64_t &EarlierSize, int64_t LaterStart, - uint64_t LaterSize, bool IsOverwriteEnd) { - auto *EarlierIntrinsic = cast(EarlierWrite); - Align PrefAlign = EarlierIntrinsic->getDestAlign().valueOrOne(); +static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart, + uint64_t &DeadSize, int64_t KillingStart, + uint64_t KillingSize, bool IsOverwriteEnd) { + auto *DeadIntrinsic = cast(DeadI); + Align PrefAlign = DeadIntrinsic->getDestAlign().valueOrOne(); // We assume that memet/memcpy operates in chunks of the "largest" native // type size and aligned on the same value. That means optimal start and size @@ -593,19 +592,19 @@ static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierStart, // Compute start and size of the region to remove. Make sure 'PrefAlign' is // maintained on the remaining store. if (IsOverwriteEnd) { - // Calculate required adjustment for 'LaterStart'in order to keep remaining - // store size aligned on 'PerfAlign'. + // Calculate required adjustment for 'KillingStart' in order to keep + // remaining store size aligned on 'PerfAlign'. uint64_t Off = - offsetToAlignment(uint64_t(LaterStart - EarlierStart), PrefAlign); - ToRemoveStart = LaterStart + Off; - if (EarlierSize <= uint64_t(ToRemoveStart - EarlierStart)) + offsetToAlignment(uint64_t(KillingStart - DeadStart), PrefAlign); + ToRemoveStart = KillingStart + Off; + if (DeadSize <= uint64_t(ToRemoveStart - DeadStart)) return false; - ToRemoveSize = EarlierSize - uint64_t(ToRemoveStart - EarlierStart); + ToRemoveSize = DeadSize - uint64_t(ToRemoveStart - DeadStart); } else { - ToRemoveStart = EarlierStart; - assert(LaterSize >= uint64_t(EarlierStart - LaterStart) && + ToRemoveStart = DeadStart; + assert(KillingSize >= uint64_t(DeadStart - KillingStart) && "Not overlapping accesses?"); - ToRemoveSize = LaterSize - uint64_t(EarlierStart - LaterStart); + ToRemoveSize = KillingSize - uint64_t(DeadStart - KillingStart); // Calculate required adjustment for 'ToRemoveSize'in order to keep // start of the remaining store aligned on 'PerfAlign'. uint64_t Off = offsetToAlignment(ToRemoveSize, PrefAlign); @@ -619,10 +618,10 @@ static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierStart, } assert(ToRemoveSize > 0 && "Shouldn't reach here if nothing to remove"); - assert(EarlierSize > ToRemoveSize && "Can't remove more than original size"); + assert(DeadSize > ToRemoveSize && "Can't remove more than original size"); - uint64_t NewSize = EarlierSize - ToRemoveSize; - if (auto *AMI = dyn_cast(EarlierWrite)) { + uint64_t NewSize = DeadSize - ToRemoveSize; + if (auto *AMI = dyn_cast(DeadI)) { // When shortening an atomic memory intrinsic, the newly shortened // length must remain an integer multiple of the element size. const uint32_t ElementSize = AMI->getElementSizeInBytes(); @@ -631,65 +630,62 @@ static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierStart, } LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n OW " - << (IsOverwriteEnd ? "END" : "BEGIN") << ": " - << *EarlierWrite << "\n KILLER [" << ToRemoveStart << ", " + << (IsOverwriteEnd ? "END" : "BEGIN") << ": " << *DeadI + << "\n KILLER [" << ToRemoveStart << ", " << int64_t(ToRemoveStart + ToRemoveSize) << ")\n"); - Value *EarlierWriteLength = EarlierIntrinsic->getLength(); - Value *TrimmedLength = - ConstantInt::get(EarlierWriteLength->getType(), NewSize); - EarlierIntrinsic->setLength(TrimmedLength); - EarlierIntrinsic->setDestAlignment(PrefAlign); + Value *DeadWriteLength = DeadIntrinsic->getLength(); + Value *TrimmedLength = ConstantInt::get(DeadWriteLength->getType(), NewSize); + DeadIntrinsic->setLength(TrimmedLength); + DeadIntrinsic->setDestAlignment(PrefAlign); if (!IsOverwriteEnd) { - Value *OrigDest = EarlierIntrinsic->getRawDest(); + Value *OrigDest = DeadIntrinsic->getRawDest(); Type *Int8PtrTy = - Type::getInt8PtrTy(EarlierIntrinsic->getContext(), + Type::getInt8PtrTy(DeadIntrinsic->getContext(), OrigDest->getType()->getPointerAddressSpace()); Value *Dest = OrigDest; if (OrigDest->getType() != Int8PtrTy) - Dest = CastInst::CreatePointerCast(OrigDest, Int8PtrTy, "", EarlierWrite); + Dest = CastInst::CreatePointerCast(OrigDest, Int8PtrTy, "", DeadI); Value *Indices[1] = { - ConstantInt::get(EarlierWriteLength->getType(), ToRemoveSize)}; + ConstantInt::get(DeadWriteLength->getType(), ToRemoveSize)}; Instruction *NewDestGEP = GetElementPtrInst::CreateInBounds( - Type::getInt8Ty(EarlierIntrinsic->getContext()), - Dest, Indices, "", EarlierWrite); - NewDestGEP->setDebugLoc(EarlierIntrinsic->getDebugLoc()); + Type::getInt8Ty(DeadIntrinsic->getContext()), Dest, Indices, "", DeadI); + NewDestGEP->setDebugLoc(DeadIntrinsic->getDebugLoc()); if (NewDestGEP->getType() != OrigDest->getType()) NewDestGEP = CastInst::CreatePointerCast(NewDestGEP, OrigDest->getType(), - "", EarlierWrite); - EarlierIntrinsic->setDest(NewDestGEP); + "", DeadI); + DeadIntrinsic->setDest(NewDestGEP); } - // Finally update start and size of earlier access. + // Finally update start and size of dead access. if (!IsOverwriteEnd) - EarlierStart += ToRemoveSize; - EarlierSize = NewSize; + DeadStart += ToRemoveSize; + DeadSize = NewSize; return true; } -static bool tryToShortenEnd(Instruction *EarlierWrite, - OverlapIntervalsTy &IntervalMap, - int64_t &EarlierStart, uint64_t &EarlierSize) { - if (IntervalMap.empty() || !isShortenableAtTheEnd(EarlierWrite)) +static bool tryToShortenEnd(Instruction *DeadI, OverlapIntervalsTy &IntervalMap, + int64_t &DeadStart, uint64_t &DeadSize) { + if (IntervalMap.empty() || !isShortenableAtTheEnd(DeadI)) return false; OverlapIntervalsTy::iterator OII = --IntervalMap.end(); - int64_t LaterStart = OII->second; - uint64_t LaterSize = OII->first - LaterStart; + int64_t KillingStart = OII->second; + uint64_t KillingSize = OII->first - KillingStart; - assert(OII->first - LaterStart >= 0 && "Size expected to be positive"); + assert(OII->first - KillingStart >= 0 && "Size expected to be positive"); - if (LaterStart > EarlierStart && - // Note: "LaterStart - EarlierStart" is known to be positive due to + if (KillingStart > DeadStart && + // Note: "KillingStart - KillingStart" is known to be positive due to // preceding check. - (uint64_t)(LaterStart - EarlierStart) < EarlierSize && - // Note: "EarlierSize - (uint64_t)(LaterStart - EarlierStart)" is known to + (uint64_t)(KillingStart - DeadStart) < DeadSize && + // Note: "DeadSize - (uint64_t)(KillingStart - DeadStart)" is known to // be non negative due to preceding checks. - LaterSize >= EarlierSize - (uint64_t)(LaterStart - EarlierStart)) { - if (tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart, - LaterSize, true)) { + KillingSize >= DeadSize - (uint64_t)(KillingStart - DeadStart)) { + if (tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize, + true)) { IntervalMap.erase(OII); return true; } @@ -697,28 +693,28 @@ static bool tryToShortenEnd(Instruction *EarlierWrite, return false; } -static bool tryToShortenBegin(Instruction *EarlierWrite, +static bool tryToShortenBegin(Instruction *DeadI, OverlapIntervalsTy &IntervalMap, - int64_t &EarlierStart, uint64_t &EarlierSize) { - if (IntervalMap.empty() || !isShortenableAtTheBeginning(EarlierWrite)) + int64_t &DeadStart, uint64_t &DeadSize) { + if (IntervalMap.empty() || !isShortenableAtTheBeginning(DeadI)) return false; OverlapIntervalsTy::iterator OII = IntervalMap.begin(); - int64_t LaterStart = OII->second; - uint64_t LaterSize = OII->first - LaterStart; + int64_t KillingStart = OII->second; + uint64_t KillingSize = OII->first - KillingStart; - assert(OII->first - LaterStart >= 0 && "Size expected to be positive"); + assert(OII->first - KillingStart >= 0 && "Size expected to be positive"); - if (LaterStart <= EarlierStart && - // Note: "EarlierStart - LaterStart" is known to be non negative due to + if (KillingStart <= DeadStart && + // Note: "DeadStart - KillingStart" is known to be non negative due to // preceding check. - LaterSize > (uint64_t)(EarlierStart - LaterStart)) { - // Note: "LaterSize - (uint64_t)(EarlierStart - LaterStart)" is known to be - // positive due to preceding checks. - assert(LaterSize - (uint64_t)(EarlierStart - LaterStart) < EarlierSize && + KillingSize > (uint64_t)(DeadStart - KillingStart)) { + // Note: "KillingSize - (uint64_t)(DeadStart - DeadStart)" is known to + // be positive due to preceding checks. + assert(KillingSize - (uint64_t)(DeadStart - KillingStart) < DeadSize && "Should have been handled as OW_Complete"); - if (tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart, - LaterSize, false)) { + if (tryToShorten(DeadI, DeadStart, DeadSize, KillingStart, KillingSize, + false)) { IntervalMap.erase(OII); return true; } @@ -731,66 +727,65 @@ static bool removePartiallyOverlappedStores(const DataLayout &DL, const TargetLibraryInfo &TLI) { bool Changed = false; for (auto OI : IOL) { - Instruction *EarlierWrite = OI.first; - MemoryLocation Loc = getLocForWrite(EarlierWrite, TLI); - assert(isRemovable(EarlierWrite) && "Expect only removable instruction"); + Instruction *DeadI = OI.first; + MemoryLocation Loc = getLocForWrite(DeadI, TLI); + assert(isRemovable(DeadI) && "Expect only removable instruction"); const Value *Ptr = Loc.Ptr->stripPointerCasts(); - int64_t EarlierStart = 0; - uint64_t EarlierSize = Loc.Size.getValue(); - GetPointerBaseWithConstantOffset(Ptr, EarlierStart, DL); + int64_t DeadStart = 0; + uint64_t DeadSize = Loc.Size.getValue(); + GetPointerBaseWithConstantOffset(Ptr, DeadStart, DL); OverlapIntervalsTy &IntervalMap = OI.second; - Changed |= - tryToShortenEnd(EarlierWrite, IntervalMap, EarlierStart, EarlierSize); + Changed |= tryToShortenEnd(DeadI, IntervalMap, DeadStart, DeadSize); if (IntervalMap.empty()) continue; - Changed |= - tryToShortenBegin(EarlierWrite, IntervalMap, EarlierStart, EarlierSize); + Changed |= tryToShortenBegin(DeadI, IntervalMap, DeadStart, DeadSize); } return Changed; } -static Constant *tryToMergePartialOverlappingStores( - StoreInst *Earlier, StoreInst *Later, int64_t InstWriteOffset, - int64_t DepWriteOffset, const DataLayout &DL, BatchAAResults &AA, - DominatorTree *DT) { - - if (Earlier && isa(Earlier->getValueOperand()) && - DL.typeSizeEqualsStoreSize(Earlier->getValueOperand()->getType()) && - Later && isa(Later->getValueOperand()) && - DL.typeSizeEqualsStoreSize(Later->getValueOperand()->getType()) && - memoryIsNotModifiedBetween(Earlier, Later, AA, DL, DT)) { +static Constant * +tryToMergePartialOverlappingStores(StoreInst *KillingI, StoreInst *DeadI, + int64_t KillingOffset, int64_t DeadOffset, + const DataLayout &DL, BatchAAResults &AA, + DominatorTree *DT) { + + if (DeadI && isa(DeadI->getValueOperand()) && + DL.typeSizeEqualsStoreSize(DeadI->getValueOperand()->getType()) && + KillingI && isa(KillingI->getValueOperand()) && + DL.typeSizeEqualsStoreSize(KillingI->getValueOperand()->getType()) && + memoryIsNotModifiedBetween(DeadI, KillingI, AA, DL, DT)) { // If the store we find is: // a) partially overwritten by the store to 'Loc' - // b) the later store is fully contained in the earlier one and + // b) the killing store is fully contained in the dead one and // c) they both have a constant value // d) none of the two stores need padding - // Merge the two stores, replacing the earlier store's value with a + // Merge the two stores, replacing the dead store's value with a // merge of both values. // TODO: Deal with other constant types (vectors, etc), and probably // some mem intrinsics (if needed) - APInt EarlierValue = - cast(Earlier->getValueOperand())->getValue(); - APInt LaterValue = cast(Later->getValueOperand())->getValue(); - unsigned LaterBits = LaterValue.getBitWidth(); - assert(EarlierValue.getBitWidth() > LaterValue.getBitWidth()); - LaterValue = LaterValue.zext(EarlierValue.getBitWidth()); + APInt DeadValue = cast(DeadI->getValueOperand())->getValue(); + APInt KillingValue = + cast(KillingI->getValueOperand())->getValue(); + unsigned KillingBits = KillingValue.getBitWidth(); + assert(DeadValue.getBitWidth() > KillingValue.getBitWidth()); + KillingValue = KillingValue.zext(DeadValue.getBitWidth()); // Offset of the smaller store inside the larger store - unsigned BitOffsetDiff = (InstWriteOffset - DepWriteOffset) * 8; - unsigned LShiftAmount = DL.isBigEndian() ? EarlierValue.getBitWidth() - - BitOffsetDiff - LaterBits - : BitOffsetDiff; - APInt Mask = APInt::getBitsSet(EarlierValue.getBitWidth(), LShiftAmount, - LShiftAmount + LaterBits); + unsigned BitOffsetDiff = (KillingOffset - DeadOffset) * 8; + unsigned LShiftAmount = + DL.isBigEndian() ? DeadValue.getBitWidth() - BitOffsetDiff - KillingBits + : BitOffsetDiff; + APInt Mask = APInt::getBitsSet(DeadValue.getBitWidth(), LShiftAmount, + LShiftAmount + KillingBits); // Clear the bits we'll be replacing, then OR with the smaller // store, shifted appropriately. - APInt Merged = (EarlierValue & ~Mask) | (LaterValue << LShiftAmount); - LLVM_DEBUG(dbgs() << "DSE: Merge Stores:\n Earlier: " << *Earlier - << "\n Later: " << *Later + APInt Merged = (DeadValue & ~Mask) | (KillingValue << LShiftAmount); + LLVM_DEBUG(dbgs() << "DSE: Merge Stores:\n Dead: " << *DeadI + << "\n Killing: " << *KillingI << "\n Merged Value: " << Merged << '\n'); - return ConstantInt::get(Earlier->getValueOperand()->getType(), Merged); + return ConstantInt::get(DeadI->getValueOperand()->getType(), Merged); } return nullptr; } @@ -933,121 +928,126 @@ struct DSEState { ContainsIrreducibleLoops = mayContainIrreducibleControl(F, &LI); } - /// Return 'OW_Complete' if a store to the 'Later' location (by \p LaterI - /// instruction) completely overwrites a store to the 'Earlier' location. - /// (by \p EarlierI instruction). - /// Return OW_MaybePartial if \p Later does not completely overwrite - /// \p Earlier, but they both write to the same underlying object. In that - /// case, use isPartialOverwrite to check if \p Later partially overwrites - /// \p Earlier. Returns 'OW_Unknown' if nothing can be determined. - OverwriteResult - isOverwrite(const Instruction *LaterI, const Instruction *EarlierI, - const MemoryLocation &Later, const MemoryLocation &Earlier, - int64_t &EarlierOff, int64_t &LaterOff) { + /// Return 'OW_Complete' if a store to the 'KillingLoc' location (by \p + /// KillingI instruction) completely overwrites a store to the 'DeadLoc' + /// location (by \p DeadI instruction). + /// Return OW_MaybePartial if \p KillingI does not completely overwrite + /// \p DeadI, but they both write to the same underlying object. In that + /// case, use isPartialOverwrite to check if \p KillingI partially overwrites + /// \p DeadI. Returns 'OW_Unknown' if nothing can be determined. + OverwriteResult isOverwrite(const Instruction *KillingI, + const Instruction *DeadI, + const MemoryLocation &KillingLoc, + const MemoryLocation &DeadLoc, + int64_t &KillingOff, int64_t &DeadOff) { // AliasAnalysis does not always account for loops. Limit overwrite checks - // to dependencies for which we can guarantee they are independant of any + // to dependencies for which we can guarantee they are independent of any // loops they are in. - if (!isGuaranteedLoopIndependent(EarlierI, LaterI, Earlier)) + if (!isGuaranteedLoopIndependent(DeadI, KillingI, DeadLoc)) return OW_Unknown; // FIXME: Vet that this works for size upper-bounds. Seems unlikely that we'll // get imprecise values here, though (except for unknown sizes). - if (!Later.Size.isPrecise() || !Earlier.Size.isPrecise()) { + if (!KillingLoc.Size.isPrecise() || !DeadLoc.Size.isPrecise()) { // In case no constant size is known, try to an IR values for the number // of bytes written and check if they match. - const auto *LaterMemI = dyn_cast(LaterI); - const auto *EarlierMemI = dyn_cast(EarlierI); - if (LaterMemI && EarlierMemI) { - const Value *LaterV = LaterMemI->getLength(); - const Value *EarlierV = EarlierMemI->getLength(); - if (LaterV == EarlierV && BatchAA.isMustAlias(Earlier, Later)) + const auto *KillingMemI = dyn_cast(KillingI); + const auto *DeadMemI = dyn_cast(DeadI); + if (KillingMemI && DeadMemI) { + const Value *KillingV = KillingMemI->getLength(); + const Value *DeadV = DeadMemI->getLength(); + if (KillingV == DeadV && BatchAA.isMustAlias(DeadLoc, KillingLoc)) return OW_Complete; } // Masked stores have imprecise locations, but we can reason about them // to some extent. - return isMaskedStoreOverwrite(LaterI, EarlierI, BatchAA); + return isMaskedStoreOverwrite(KillingI, DeadI, BatchAA); } - const uint64_t LaterSize = Later.Size.getValue(); - const uint64_t EarlierSize = Earlier.Size.getValue(); + const uint64_t KillingSize = KillingLoc.Size.getValue(); + const uint64_t DeadSize = DeadLoc.Size.getValue(); // Query the alias information - AliasResult AAR = BatchAA.alias(Later, Earlier); + AliasResult AAR = BatchAA.alias(KillingLoc, DeadLoc); - // If the start pointers are the same, we just have to compare sizes to see if - // the later store was larger than the earlier store. + // If the start pointers are the same, we just have to compare sizes to see + // if the killing store was larger than the dead store. if (AAR == AliasResult::MustAlias) { - // Make sure that the Later size is >= the Earlier size. - if (LaterSize >= EarlierSize) + // Make sure that the KillingSize size is >= the DeadSize size. + if (KillingSize >= DeadSize) return OW_Complete; } // If we hit a partial alias we may have a full overwrite if (AAR == AliasResult::PartialAlias && AAR.hasOffset()) { int32_t Off = AAR.getOffset(); - if (Off >= 0 && (uint64_t)Off + EarlierSize <= LaterSize) + if (Off >= 0 && (uint64_t)Off + DeadSize <= KillingSize) return OW_Complete; } - // Check to see if the later store is to the entire object (either a global, - // an alloca, or a byval/inalloca argument). If so, then it clearly + // Check to see if the killing store is to the entire object (either a + // global, an alloca, or a byval/inalloca argument). If so, then it clearly // overwrites any other store to the same object. - const Value *P1 = Earlier.Ptr->stripPointerCasts(); - const Value *P2 = Later.Ptr->stripPointerCasts(); - const Value *UO1 = getUnderlyingObject(P1), *UO2 = getUnderlyingObject(P2); + const Value *DeadPtr = DeadLoc.Ptr->stripPointerCasts(); + const Value *KillingPtr = KillingLoc.Ptr->stripPointerCasts(); + const Value *DeadUndObj = getUnderlyingObject(DeadPtr); + const Value *KillingUndObj = getUnderlyingObject(KillingPtr); // If we can't resolve the same pointers to the same object, then we can't // analyze them at all. - if (UO1 != UO2) + if (DeadUndObj != KillingUndObj) return OW_Unknown; - // If the "Later" store is to a recognizable object, get its size. - uint64_t ObjectSize = getPointerSize(UO2, DL, TLI, &F); - if (ObjectSize != MemoryLocation::UnknownSize) - if (ObjectSize == LaterSize && ObjectSize >= EarlierSize) + // If the KillingI store is to a recognizable object, get its size. + uint64_t KillingUndObjSize = getPointerSize(KillingUndObj, DL, TLI, &F); + if (KillingUndObjSize != MemoryLocation::UnknownSize) + if (KillingUndObjSize == KillingSize && KillingUndObjSize >= DeadSize) return OW_Complete; // Okay, we have stores to two completely different pointers. Try to // decompose the pointer into a "base + constant_offset" form. If the base // pointers are equal, then we can reason about the two stores. - EarlierOff = 0; - LaterOff = 0; - const Value *BP1 = GetPointerBaseWithConstantOffset(P1, EarlierOff, DL); - const Value *BP2 = GetPointerBaseWithConstantOffset(P2, LaterOff, DL); - - // If the base pointers still differ, we have two completely different stores. - if (BP1 != BP2) + DeadOff = 0; + KillingOff = 0; + const Value *DeadBasePtr = + GetPointerBaseWithConstantOffset(DeadPtr, DeadOff, DL); + const Value *KillingBasePtr = + GetPointerBaseWithConstantOffset(KillingPtr, KillingOff, DL); + + // If the base pointers still differ, we have two completely different + // stores. + if (DeadBasePtr != KillingBasePtr) return OW_Unknown; - // The later access completely overlaps the earlier store if and only if - // both start and end of the earlier one is "inside" the later one: - // |<->|--earlier--|<->| - // |-------later-------| + // The killing access completely overlaps the dead store if and only if + // both start and end of the dead one is "inside" the killing one: + // |<->|--dead--|<->| + // |-----killing------| // Accesses may overlap if and only if start of one of them is "inside" // another one: - // |<->|--earlier--|<----->| - // |-------later-------| + // |<->|--dead--|<-------->| + // |-------killing--------| // OR - // |----- earlier -----| - // |<->|---later---|<----->| + // |-------dead-------| + // |<->|---killing---|<----->| // // We have to be careful here as *Off is signed while *.Size is unsigned. - // Check if the earlier access starts "not before" the later one. - if (EarlierOff >= LaterOff) { - // If the earlier access ends "not after" the later access then the earlier - // one is completely overwritten by the later one. - if (uint64_t(EarlierOff - LaterOff) + EarlierSize <= LaterSize) + // Check if the dead access starts "not before" the killing one. + if (DeadOff >= KillingOff) { + // If the dead access ends "not after" the killing access then the + // dead one is completely overwritten by the killing one. + if (uint64_t(DeadOff - KillingOff) + DeadSize <= KillingSize) return OW_Complete; - // If start of the earlier access is "before" end of the later access then - // accesses overlap. - else if ((uint64_t)(EarlierOff - LaterOff) < LaterSize) + // If start of the dead access is "before" end of the killing access + // then accesses overlap. + else if ((uint64_t)(DeadOff - KillingOff) < KillingSize) return OW_MaybePartial; } - // If start of the later access is "before" end of the earlier access then + // If start of the killing access is "before" end of the dead access then // accesses overlap. - else if ((uint64_t)(LaterOff - EarlierOff) < EarlierSize) { + else if ((uint64_t)(KillingOff - DeadOff) < DeadSize) { return OW_MaybePartial; } @@ -1143,8 +1143,8 @@ struct DSEState { int64_t InstWriteOffset, DepWriteOffset; if (auto CC = getLocForWriteEx(UseInst)) - return isOverwrite(UseInst, DefInst, *CC, DefLoc, DepWriteOffset, - InstWriteOffset) == OW_Complete; + return isOverwrite(UseInst, DefInst, *CC, DefLoc, InstWriteOffset, + DepWriteOffset) == OW_Complete; return false; } @@ -1246,9 +1246,10 @@ struct DSEState { const Value *LocUO = getUnderlyingObject(Loc.Ptr); return BatchAA.isMustAlias(TermLoc.Ptr, LocUO); } - int64_t InstWriteOffset, DepWriteOffset; - return isOverwrite(MaybeTerm, AccessI, TermLoc, Loc, DepWriteOffset, - InstWriteOffset) == OW_Complete; + int64_t InstWriteOffset = 0; + int64_t DepWriteOffset = 0; + return isOverwrite(MaybeTerm, AccessI, TermLoc, Loc, InstWriteOffset, + DepWriteOffset) == OW_Complete; } // Returns true if \p Use may read from \p DefLoc. @@ -1323,15 +1324,15 @@ struct DSEState { return IsGuaranteedLoopInvariantBase(Ptr); } - // Find a MemoryDef writing to \p DefLoc and dominating \p StartAccess, with - // no read access between them or on any other path to a function exit block - // if \p DefLoc is not accessible after the function returns. If there is no - // such MemoryDef, return None. The returned value may not (completely) - // overwrite \p DefLoc. Currently we bail out when we encounter an aliasing - // MemoryUse (read). + // Find a MemoryDef writing to \p KillingLoc and dominating \p StartAccess, + // with no read access between them or on any other path to a function exit + // block if \p KillingLoc is not accessible after the function returns. If + // there is no such MemoryDef, return None. The returned value may not + // (completely) overwrite \p KillingLoc. Currently we bail out when we + // encounter an aliasing MemoryUse (read). Optional getDomMemoryDef(MemoryDef *KillingDef, MemoryAccess *StartAccess, - const MemoryLocation &DefLoc, const Value *DefUO, + const MemoryLocation &KillingLoc, const Value *KillingUndObj, unsigned &ScanLimit, unsigned &WalkerStepLimit, bool IsMemTerm, unsigned &PartialLimit) { if (ScanLimit == 0 || WalkerStepLimit == 0) { @@ -1383,19 +1384,19 @@ struct DSEState { MemoryDef *CurrentDef = cast(Current); Instruction *CurrentI = CurrentDef->getMemoryInst(); - if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(DefUO))) + if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(KillingUndObj))) continue; // Before we try to remove anything, check for any extra throwing // instructions that block us from DSEing - if (mayThrowBetween(KillingI, CurrentI, DefUO)) { + if (mayThrowBetween(KillingI, CurrentI, KillingUndObj)) { LLVM_DEBUG(dbgs() << " ... skip, may throw!\n"); return None; } // Check for anything that looks like it will be a barrier to further // removal - if (isDSEBarrier(DefUO, CurrentI)) { + if (isDSEBarrier(KillingUndObj, CurrentI)) { LLVM_DEBUG(dbgs() << " ... skip, barrier\n"); return None; } @@ -1404,14 +1405,14 @@ struct DSEState { // clobber, bail out, as the path is not profitable. We skip this check // for intrinsic calls, because the code knows how to handle memcpy // intrinsics. - if (!isa(CurrentI) && isReadClobber(DefLoc, CurrentI)) + if (!isa(CurrentI) && isReadClobber(KillingLoc, CurrentI)) return None; // Quick check if there are direct uses that are read-clobbers. - if (any_of(Current->uses(), [this, &DefLoc, StartAccess](Use &U) { + if (any_of(Current->uses(), [this, &KillingLoc, StartAccess](Use &U) { if (auto *UseOrDef = dyn_cast(U.getUser())) return !MSSA.dominates(StartAccess, UseOrDef) && - isReadClobber(DefLoc, UseOrDef->getMemoryInst()); + isReadClobber(KillingLoc, UseOrDef->getMemoryInst()); return false; })) { LLVM_DEBUG(dbgs() << " ... found a read clobber\n"); @@ -1444,9 +1445,10 @@ struct DSEState { if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) continue; } else { - int64_t InstWriteOffset, DepWriteOffset; - auto OR = isOverwrite(KillingI, CurrentI, DefLoc, *CurrentLoc, - DepWriteOffset, InstWriteOffset); + int64_t KillingOffset = 0; + int64_t DeadOffset = 0; + auto OR = isOverwrite(KillingI, CurrentI, KillingLoc, *CurrentLoc, + KillingOffset, DeadOffset); // If Current does not write to the same object as KillingDef, check // the next candidate. if (OR == OW_Unknown) @@ -1467,30 +1469,30 @@ struct DSEState { }; // Accesses to objects accessible after the function returns can only be - // eliminated if the access is killed along all paths to the exit. Collect + // eliminated if the access is dead along all paths to the exit. Collect // the blocks with killing (=completely overwriting MemoryDefs) and check if - // they cover all paths from EarlierAccess to any function exit. + // they cover all paths from MaybeDeadAccess to any function exit. SmallPtrSet KillingDefs; KillingDefs.insert(KillingDef->getMemoryInst()); - MemoryAccess *EarlierAccess = Current; - Instruction *EarlierMemInst = - cast(EarlierAccess)->getMemoryInst(); - LLVM_DEBUG(dbgs() << " Checking for reads of " << *EarlierAccess << " (" - << *EarlierMemInst << ")\n"); + MemoryAccess *MaybeDeadAccess = Current; + MemoryLocation MaybeDeadLoc = *CurrentLoc; + Instruction *MaybeDeadI = cast(MaybeDeadAccess)->getMemoryInst(); + LLVM_DEBUG(dbgs() << " Checking for reads of " << *MaybeDeadAccess << " (" + << *MaybeDeadI << ")\n"); SmallSetVector WorkList; auto PushMemUses = [&WorkList](MemoryAccess *Acc) { for (Use &U : Acc->uses()) WorkList.insert(cast(U.getUser())); }; - PushMemUses(EarlierAccess); + PushMemUses(MaybeDeadAccess); // Optimistically collect all accesses for reads. If we do not find any // read clobbers, add them to the cache. SmallPtrSet KnownNoReads; - if (!EarlierMemInst->mayReadFromMemory()) - KnownNoReads.insert(EarlierAccess); - // Check if EarlierDef may be read. + if (!MaybeDeadI->mayReadFromMemory()) + KnownNoReads.insert(MaybeDeadAccess); + // Check if DeadDef may be read. for (unsigned I = 0; I < WorkList.size(); I++) { MemoryAccess *UseAccess = WorkList[I]; @@ -1529,7 +1531,7 @@ struct DSEState { // A memory terminator kills all preceeding MemoryDefs and all succeeding // MemoryAccesses. We do not have to check it's users. - if (isMemTerminator(*CurrentLoc, EarlierMemInst, UseInst)) { + if (isMemTerminator(MaybeDeadLoc, MaybeDeadI, UseInst)) { LLVM_DEBUG( dbgs() << " ... skipping, memterminator invalidates following accesses\n"); @@ -1542,14 +1544,14 @@ struct DSEState { continue; } - if (UseInst->mayThrow() && !isInvisibleToCallerBeforeRet(DefUO)) { + if (UseInst->mayThrow() && !isInvisibleToCallerBeforeRet(KillingUndObj)) { LLVM_DEBUG(dbgs() << " ... found throwing instruction\n"); return None; } // Uses which may read the original MemoryDef mean we cannot eliminate the // original MD. Stop walk. - if (isReadClobber(*CurrentLoc, UseInst)) { + if (isReadClobber(MaybeDeadLoc, UseInst)) { LLVM_DEBUG(dbgs() << " ... found read clobber\n"); return None; } @@ -1557,16 +1559,16 @@ struct DSEState { // If this worklist walks back to the original memory access (and the // pointer is not guarenteed loop invariant) then we cannot assume that a // store kills itself. - if (EarlierAccess == UseAccess && - !isGuaranteedLoopInvariant(CurrentLoc->Ptr)) { + if (MaybeDeadAccess == UseAccess && + !isGuaranteedLoopInvariant(MaybeDeadLoc.Ptr)) { LLVM_DEBUG(dbgs() << " ... found not loop invariant self access\n"); return None; } - // Otherwise, for the KillingDef and EarlierAccess we only have to check + // Otherwise, for the KillingDef and MaybeDeadAccess we only have to check // if it reads the memory location. // TODO: It would probably be better to check for self-reads before // calling the function. - if (KillingDef == UseAccess || EarlierAccess == UseAccess) { + if (KillingDef == UseAccess || MaybeDeadAccess == UseAccess) { LLVM_DEBUG(dbgs() << " ... skipping killing def/dom access\n"); continue; } @@ -1575,18 +1577,18 @@ struct DSEState { // the original location. Otherwise we have to check uses of *all* // MemoryDefs we discover, including non-aliasing ones. Otherwise we might // miss cases like the following - // 1 = Def(LoE) ; <----- EarlierDef stores [0,1] + // 1 = Def(LoE) ; <----- DeadDef stores [0,1] // 2 = Def(1) ; (2, 1) = NoAlias, stores [2,3] // Use(2) ; MayAlias 2 *and* 1, loads [0, 3]. // (The Use points to the *first* Def it may alias) // 3 = Def(1) ; <---- Current (3, 2) = NoAlias, (3,1) = MayAlias, // stores [0,1] if (MemoryDef *UseDef = dyn_cast(UseAccess)) { - if (isCompleteOverwrite(*CurrentLoc, EarlierMemInst, UseInst)) { + if (isCompleteOverwrite(MaybeDeadLoc, MaybeDeadI, UseInst)) { BasicBlock *MaybeKillingBlock = UseInst->getParent(); if (PostOrderNumbers.find(MaybeKillingBlock)->second < - PostOrderNumbers.find(EarlierAccess->getBlock())->second) { - if (!isInvisibleToCallerAfterRet(DefUO)) { + PostOrderNumbers.find(MaybeDeadAccess->getBlock())->second) { + if (!isInvisibleToCallerAfterRet(KillingUndObj)) { LLVM_DEBUG(dbgs() << " ... found killing def " << *UseInst << "\n"); KillingDefs.insert(UseInst); @@ -1602,9 +1604,9 @@ struct DSEState { } // For accesses to locations visible after the function returns, make sure - // that the location is killed (=overwritten) along all paths from - // EarlierAccess to the exit. - if (!isInvisibleToCallerAfterRet(DefUO)) { + // that the location is dead (=overwritten) along all paths from + // MaybeDeadAccess to the exit. + if (!isInvisibleToCallerAfterRet(KillingUndObj)) { SmallPtrSet KillingBlocks; for (Instruction *KD : KillingDefs) KillingBlocks.insert(KD->getParent()); @@ -1621,17 +1623,17 @@ struct DSEState { } // If CommonPred is in the set of killing blocks, just check if it - // post-dominates EarlierAccess. + // post-dominates MaybeDeadAccess. if (KillingBlocks.count(CommonPred)) { - if (PDT.dominates(CommonPred, EarlierAccess->getBlock())) - return {EarlierAccess}; + if (PDT.dominates(CommonPred, MaybeDeadAccess->getBlock())) + return {MaybeDeadAccess}; return None; } - // If the common post-dominator does not post-dominate EarlierAccess, - // there is a path from EarlierAccess to an exit not going through a + // If the common post-dominator does not post-dominate MaybeDeadAccess, + // there is a path from MaybeDeadAccess to an exit not going through a // killing block. - if (PDT.dominates(CommonPred, EarlierAccess->getBlock())) { + if (PDT.dominates(CommonPred, MaybeDeadAccess->getBlock())) { SetVector WorkList; // If CommonPred is null, there are multiple exits from the function. @@ -1644,16 +1646,16 @@ struct DSEState { NumCFGTries++; // Check if all paths starting from an exit node go through one of the - // killing blocks before reaching EarlierAccess. + // killing blocks before reaching MaybeDeadAccess. for (unsigned I = 0; I < WorkList.size(); I++) { NumCFGChecks++; BasicBlock *Current = WorkList[I]; if (KillingBlocks.count(Current)) continue; - if (Current == EarlierAccess->getBlock()) + if (Current == MaybeDeadAccess->getBlock()) return None; - // EarlierAccess is reachable from the entry, so we don't have to + // MaybeDeadAccess is reachable from the entry, so we don't have to // explore unreachable blocks further. if (!DT.isReachableFromEntry(Current)) continue; @@ -1665,14 +1667,14 @@ struct DSEState { return None; } NumCFGSuccess++; - return {EarlierAccess}; + return {MaybeDeadAccess}; } return None; } - // No aliasing MemoryUses of EarlierAccess found, EarlierAccess is + // No aliasing MemoryUses of MaybeDeadAccess found, MaybeDeadAccess is // potentially dead. - return {EarlierAccess}; + return {MaybeDeadAccess}; } // Delete dead memory defs @@ -1715,43 +1717,44 @@ struct DSEState { } } - // Check for any extra throws between SI and NI that block DSE. This only - // checks extra maythrows (those that aren't MemoryDef's). MemoryDef that may - // throw are handled during the walk from one def to the next. - bool mayThrowBetween(Instruction *SI, Instruction *NI, - const Value *SILocUnd) { - // First see if we can ignore it by using the fact that SI is an + // Check for any extra throws between \p KillingI and \p DeadI that block + // DSE. This only checks extra maythrows (those that aren't MemoryDef's). + // MemoryDef that may throw are handled during the walk from one def to the + // next. + bool mayThrowBetween(Instruction *KillingI, Instruction *DeadI, + const Value *KillingUndObj) { + // First see if we can ignore it by using the fact that KillingI is an // alloca/alloca like object that is not visible to the caller during // execution of the function. - if (SILocUnd && isInvisibleToCallerBeforeRet(SILocUnd)) + if (KillingUndObj && isInvisibleToCallerBeforeRet(KillingUndObj)) return false; - if (SI->getParent() == NI->getParent()) - return ThrowingBlocks.count(SI->getParent()); + if (KillingI->getParent() == DeadI->getParent()) + return ThrowingBlocks.count(KillingI->getParent()); return !ThrowingBlocks.empty(); } - // Check if \p NI acts as a DSE barrier for \p SI. The following instructions - // act as barriers: - // * A memory instruction that may throw and \p SI accesses a non-stack + // Check if \p DeadI acts as a DSE barrier for \p KillingI. The following + // instructions act as barriers: + // * A memory instruction that may throw and \p KillingI accesses a non-stack // object. // * Atomic stores stronger that monotonic. - bool isDSEBarrier(const Value *SILocUnd, Instruction *NI) { - // If NI may throw it acts as a barrier, unless we are to an alloca/alloca - // like object that does not escape. - if (NI->mayThrow() && !isInvisibleToCallerBeforeRet(SILocUnd)) + bool isDSEBarrier(const Value *KillingUndObj, Instruction *DeadI) { + // If DeadI may throw it acts as a barrier, unless we are to an + // alloca/alloca like object that does not escape. + if (DeadI->mayThrow() && !isInvisibleToCallerBeforeRet(KillingUndObj)) return true; - // If NI is an atomic load/store stronger than monotonic, do not try to + // If DeadI is an atomic load/store stronger than monotonic, do not try to // eliminate/reorder it. - if (NI->isAtomic()) { - if (auto *LI = dyn_cast(NI)) + if (DeadI->isAtomic()) { + if (auto *LI = dyn_cast(DeadI)) return isStrongerThanMonotonic(LI->getOrdering()); - if (auto *SI = dyn_cast(NI)) + if (auto *SI = dyn_cast(DeadI)) return isStrongerThanMonotonic(SI->getOrdering()); - if (auto *ARMW = dyn_cast(NI)) + if (auto *ARMW = dyn_cast(DeadI)) return isStrongerThanMonotonic(ARMW->getOrdering()); - if (auto *CmpXchg = dyn_cast(NI)) + if (auto *CmpXchg = dyn_cast(DeadI)) return isStrongerThanMonotonic(CmpXchg->getSuccessOrdering()) || isStrongerThanMonotonic(CmpXchg->getFailureOrdering()); llvm_unreachable("other instructions should be skipped in MemorySSA"); @@ -1935,27 +1938,27 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, MemoryDef *KillingDef = State.MemDefs[I]; if (State.SkipStores.count(KillingDef)) continue; - Instruction *SI = KillingDef->getMemoryInst(); + Instruction *KillingI = KillingDef->getMemoryInst(); - Optional MaybeSILoc; - if (State.isMemTerminatorInst(SI)) - MaybeSILoc = State.getLocForTerminator(SI).map( + Optional MaybeKillingLoc; + if (State.isMemTerminatorInst(KillingI)) + MaybeKillingLoc = State.getLocForTerminator(KillingI).map( [](const std::pair &P) { return P.first; }); else - MaybeSILoc = State.getLocForWriteEx(SI); + MaybeKillingLoc = State.getLocForWriteEx(KillingI); - if (!MaybeSILoc) { + if (!MaybeKillingLoc) { LLVM_DEBUG(dbgs() << "Failed to find analyzable write location for " - << *SI << "\n"); + << *KillingI << "\n"); continue; } - MemoryLocation SILoc = *MaybeSILoc; - assert(SILoc.Ptr && "SILoc should not be null"); - const Value *SILocUnd = getUnderlyingObject(SILoc.Ptr); + MemoryLocation KillingLoc = *MaybeKillingLoc; + assert(KillingLoc.Ptr && "KillingLoc should not be null"); + const Value *KillingUndObj = getUnderlyingObject(KillingLoc.Ptr); MemoryAccess *Current = KillingDef; LLVM_DEBUG(dbgs() << "Trying to eliminate MemoryDefs killed by " - << *Current << " (" << *SI << ")\n"); + << *KillingDef << " (" << *KillingI << ")\n"); unsigned ScanLimit = MemorySSAScanLimit; unsigned WalkerStepLimit = MemorySSAUpwardsStepLimit; @@ -1965,30 +1968,30 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, ToCheck.insert(KillingDef->getDefiningAccess()); bool Shortend = false; - bool IsMemTerm = State.isMemTerminatorInst(SI); + bool IsMemTerm = State.isMemTerminatorInst(KillingI); // Check if MemoryAccesses in the worklist are killed by KillingDef. for (unsigned I = 0; I < ToCheck.size(); I++) { Current = ToCheck[I]; if (State.SkipStores.count(Current)) continue; - Optional Next = State.getDomMemoryDef( - KillingDef, Current, SILoc, SILocUnd, ScanLimit, WalkerStepLimit, - IsMemTerm, PartialLimit); + Optional MaybeDeadAccess = State.getDomMemoryDef( + KillingDef, Current, KillingLoc, KillingUndObj, ScanLimit, + WalkerStepLimit, IsMemTerm, PartialLimit); - if (!Next) { + if (!MaybeDeadAccess) { LLVM_DEBUG(dbgs() << " finished walk\n"); continue; } - MemoryAccess *EarlierAccess = *Next; - LLVM_DEBUG(dbgs() << " Checking if we can kill " << *EarlierAccess); - if (isa(EarlierAccess)) { + MemoryAccess *DeadAccess = *MaybeDeadAccess; + LLVM_DEBUG(dbgs() << " Checking if we can kill " << *DeadAccess); + if (isa(DeadAccess)) { LLVM_DEBUG(dbgs() << "\n ... adding incoming values to worklist\n"); - for (Value *V : cast(EarlierAccess)->incoming_values()) { + for (Value *V : cast(DeadAccess)->incoming_values()) { MemoryAccess *IncomingAccess = cast(V); BasicBlock *IncomingBlock = IncomingAccess->getBlock(); - BasicBlock *PhiBlock = EarlierAccess->getBlock(); + BasicBlock *PhiBlock = DeadAccess->getBlock(); // We only consider incoming MemoryAccesses that come before the // MemoryPhi. Otherwise we could discover candidates that do not @@ -1999,72 +2002,73 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, } continue; } - auto *NextDef = cast(EarlierAccess); - Instruction *NI = NextDef->getMemoryInst(); - LLVM_DEBUG(dbgs() << " (" << *NI << ")\n"); - ToCheck.insert(NextDef->getDefiningAccess()); + auto *DeadDefAccess = cast(DeadAccess); + Instruction *DeadI = DeadDefAccess->getMemoryInst(); + LLVM_DEBUG(dbgs() << " (" << *DeadI << ")\n"); + ToCheck.insert(DeadDefAccess->getDefiningAccess()); NumGetDomMemoryDefPassed++; if (!DebugCounter::shouldExecute(MemorySSACounter)) continue; - MemoryLocation NILoc = *State.getLocForWriteEx(NI); + MemoryLocation DeadLoc = *State.getLocForWriteEx(DeadI); if (IsMemTerm) { - const Value *NIUnd = getUnderlyingObject(NILoc.Ptr); - if (SILocUnd != NIUnd) + const Value *DeadUndObj = getUnderlyingObject(DeadLoc.Ptr); + if (KillingUndObj != DeadUndObj) continue; - LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *NI - << "\n KILLER: " << *SI << '\n'); - State.deleteDeadInstruction(NI); + LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *DeadI + << "\n KILLER: " << *KillingI << '\n'); + State.deleteDeadInstruction(DeadI); ++NumFastStores; MadeChange = true; } else { - // Check if NI overwrites SI. - int64_t InstWriteOffset, DepWriteOffset; - OverwriteResult OR = State.isOverwrite(SI, NI, SILoc, NILoc, - DepWriteOffset, InstWriteOffset); + // Check if DeadI overwrites KillingI. + int64_t KillingOffset = 0; + int64_t DeadOffset = 0; + OverwriteResult OR = State.isOverwrite( + KillingI, DeadI, KillingLoc, DeadLoc, KillingOffset, DeadOffset); if (OR == OW_MaybePartial) { auto Iter = State.IOLs.insert( std::make_pair( - NI->getParent(), InstOverlapIntervalsTy())); + DeadI->getParent(), InstOverlapIntervalsTy())); auto &IOL = Iter.first->second; - OR = isPartialOverwrite(SILoc, NILoc, DepWriteOffset, InstWriteOffset, - NI, IOL); + OR = isPartialOverwrite(KillingLoc, DeadLoc, KillingOffset, + DeadOffset, DeadI, IOL); } if (EnablePartialStoreMerging && OR == OW_PartialEarlierWithFullLater) { - auto *Earlier = dyn_cast(NI); - auto *Later = dyn_cast(SI); + auto *DeadSI = dyn_cast(DeadI); + auto *KillingSI = dyn_cast(KillingI); // We are re-using tryToMergePartialOverlappingStores, which requires - // Earlier to domiante Later. + // DeadSI to dominate DeadSI. // TODO: implement tryToMergeParialOverlappingStores using MemorySSA. - if (Earlier && Later && DT.dominates(Earlier, Later)) { + if (DeadSI && KillingSI && DT.dominates(DeadSI, KillingSI)) { if (Constant *Merged = tryToMergePartialOverlappingStores( - Earlier, Later, InstWriteOffset, DepWriteOffset, State.DL, + KillingSI, DeadSI, KillingOffset, DeadOffset, State.DL, State.BatchAA, &DT)) { // Update stored value of earlier store to merged constant. - Earlier->setOperand(0, Merged); + DeadSI->setOperand(0, Merged); ++NumModifiedStores; MadeChange = true; Shortend = true; - // Remove later store and remove any outstanding overlap intervals - // for the updated store. - State.deleteDeadInstruction(Later); - auto I = State.IOLs.find(Earlier->getParent()); + // Remove killing store and remove any outstanding overlap + // intervals for the updated store. + State.deleteDeadInstruction(KillingSI); + auto I = State.IOLs.find(DeadSI->getParent()); if (I != State.IOLs.end()) - I->second.erase(Earlier); + I->second.erase(DeadSI); break; } } } if (OR == OW_Complete) { - LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *NI - << "\n KILLER: " << *SI << '\n'); - State.deleteDeadInstruction(NI); + LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *DeadI + << "\n KILLER: " << *KillingI << '\n'); + State.deleteDeadInstruction(DeadI); ++NumFastStores; MadeChange = true; } @@ -2072,10 +2076,11 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, } // Check if the store is a no-op. - if (!Shortend && isRemovable(SI) && - State.storeIsNoop(KillingDef, SILoc, SILocUnd)) { - LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *SI << '\n'); - State.deleteDeadInstruction(SI); + if (!Shortend && isRemovable(KillingI) && + State.storeIsNoop(KillingDef, KillingLoc, KillingUndObj)) { + LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *KillingI + << '\n'); + State.deleteDeadInstruction(KillingI); NumRedundantStores++; MadeChange = true; continue; From 44b44da596b1f99736de42262aae3d417ca51828 Mon Sep 17 00:00:00 2001 From: Evgeniy Brevnov Date: Mon, 22 Nov 2021 19:52:57 +0700 Subject: [PATCH 072/293] [DSE][NFC] Introduce "doesn't overwrite" return code for isOverwrite Add OR_None code to indicate that there is no overwrite. This has no any effect for current uses but will be used in one of the next patches building support for PHI translation. Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D105098 (cherry-picked from 47e2644c89b3) --- .../Scalar/DeadStoreElimination.cpp | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index d4cf3713c7e64..166d76b4e61be 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -327,6 +327,7 @@ enum OverwriteResult { OW_End, OW_PartialEarlierWithFullLater, OW_MaybePartial, + OW_None, OW_Unknown }; @@ -934,6 +935,7 @@ struct DSEState { /// Return OW_MaybePartial if \p KillingI does not completely overwrite /// \p DeadI, but they both write to the same underlying object. In that /// case, use isPartialOverwrite to check if \p KillingI partially overwrites + /// \p DeadI. Returns 'OR_None' if \p KillingI is known to not overwrite the /// \p DeadI. Returns 'OW_Unknown' if nothing can be determined. OverwriteResult isOverwrite(const Instruction *KillingI, const Instruction *DeadI, @@ -996,8 +998,16 @@ struct DSEState { // If we can't resolve the same pointers to the same object, then we can't // analyze them at all. - if (DeadUndObj != KillingUndObj) + if (DeadUndObj != KillingUndObj) { + // Non aliasing stores to different objects don't overlap. Note that + // if the killing store is known to overwrite whole object (out of + // bounds access overwrites whole object as well) then it is assumed to + // completely overwrite any store to the same object even if they don't + // actually alias (see next check). + if (AAR == AliasResult::NoAlias) + return OW_None; return OW_Unknown; + } // If the KillingI store is to a recognizable object, get its size. uint64_t KillingUndObjSize = getPointerSize(KillingUndObj, DL, TLI, &F); @@ -1051,9 +1061,8 @@ struct DSEState { return OW_MaybePartial; } - // Can reach here only if accesses are known not to overlap. There is no - // dedicated code to indicate no overlap so signal "unknown". - return OW_Unknown; + // Can reach here only if accesses are known not to overlap. + return OW_None; } bool isInvisibleToCallerAfterRet(const Value *V) { @@ -1451,7 +1460,7 @@ struct DSEState { KillingOffset, DeadOffset); // If Current does not write to the same object as KillingDef, check // the next candidate. - if (OR == OW_Unknown) + if (OR == OW_Unknown || OR == OW_None) continue; else if (OR == OW_MaybePartial) { // If KillingDef only partially overwrites Current, check the next @@ -1460,6 +1469,7 @@ struct DSEState { // which are less likely to be removable in the end. if (PartialLimit <= 1) { WalkerStepLimit -= 1; + LLVM_DEBUG(dbgs() << " ... reached partial limit ... continue with next access\n"); continue; } PartialLimit -= 1; From 649a4bd8b165336a974a33fb34eb412496d145dd Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sat, 27 Nov 2021 13:04:28 +0000 Subject: [PATCH 073/293] [DSE] Optimize defining access of defs while walking upwards. This patch extends the code that walks memory defs upwards to find clobbering accesses to also try to optimize the clobbering defining access. We should be able to find set the optimized access of our starting def (KillingDef), if the following holds: 1. It is the first call of getDomMemoryDef for KillingDef (so Current == KillingDef->getDefiningAccess(). 2. No potentially aliasing defs are skipped. Then if a (partly) aliasing def is encountered, it can be used as optimized access for KillingDef. No further optimizations can be applied to KillingDef. I'd appreciate a careful look, as the existing documentation is not too clear on what is expected for optimized accesses. The motivation for this patch is to use the optimized accesses to cover more cases of redundant stores as follow-up to D111727. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D112313 (cherry-picked from 25dad1064bf1) --- .../Scalar/DeadStoreElimination.cpp | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 166d76b4e61be..7efe123336260 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -157,6 +157,16 @@ static cl::opt MemorySSAPathCheckLimit( cl::desc("The maximum number of blocks to check when trying to prove that " "all paths to an exit go through a killing block (default = 50)")); +// This flags allows or disallows DSE to optimize MemorySSA during its +// traversal. Note that DSE optimizing MemorySSA may impact other passes +// downstream of the DSE invocation and can lead to issues not being +// reproducible in isolation (i.e. when MemorySSA is built from scratch). In +// those cases, the flag can be used to check if DSE's MemorySSA optimizations +// impact follow-up passes. +static cl::opt + OptimizeMemorySSA("dse-optimize-memoryssa", cl::init(false), cl::Hidden, + cl::desc("Allow DSE to optimize memory accesses")); + //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// @@ -1353,6 +1363,15 @@ struct DSEState { Instruction *KillingI = KillingDef->getMemoryInst(); LLVM_DEBUG(dbgs() << " trying to get dominating access\n"); + // Only optimize defining access of KillingDef when directly starting at its + // defining access. The defining access also must only access KillingLoc. At + // the moment we only support instructions with a single write location, so + // it should be sufficient to disable optimizations for instructions that + // also read from memory. + bool CanOptimize = OptimizeMemorySSA && + KillingDef->getDefiningAccess() == StartAccess && + !KillingI->mayReadFromMemory(); + // Find the next clobbering Mod access for DefLoc, starting at StartAccess. Optional CurrentLoc; for (;; Current = cast(Current)->getDefiningAccess()) { @@ -1393,8 +1412,10 @@ struct DSEState { MemoryDef *CurrentDef = cast(Current); Instruction *CurrentI = CurrentDef->getMemoryInst(); - if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(KillingUndObj))) + if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(KillingUndObj))) { + CanOptimize = false; continue; + } // Before we try to remove anything, check for any extra throwing // instructions that block us from DSEing @@ -1435,8 +1456,10 @@ struct DSEState { // If Current does not have an analyzable write location, skip it CurrentLoc = getLocForWriteEx(CurrentI); - if (!CurrentLoc) + if (!CurrentLoc) { + CanOptimize = false; continue; + } // AliasAnalysis does not account for loops. Limit elimination to // candidates for which we can guarantee they always store to the same @@ -1444,6 +1467,7 @@ struct DSEState { if (!isGuaranteedLoopIndependent(CurrentI, KillingI, *CurrentLoc)) { LLVM_DEBUG(dbgs() << " ... not guaranteed loop independent\n"); WalkerStepLimit -= 1; + CanOptimize = false; continue; } @@ -1451,13 +1475,29 @@ struct DSEState { // If the killing def is a memory terminator (e.g. lifetime.end), check // the next candidate if the current Current does not write the same // underlying object as the terminator. - if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) + if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) { + CanOptimize = false; continue; + } } else { int64_t KillingOffset = 0; int64_t DeadOffset = 0; auto OR = isOverwrite(KillingI, CurrentI, KillingLoc, *CurrentLoc, KillingOffset, DeadOffset); + if (CanOptimize) { + // CurrentDef is the earliest write clobber of KillingDef. Use it as + // optimized access. Do not optimize if CurrentDef is already the + // defining access of KillingDef. + if (CurrentDef != KillingDef->getDefiningAccess() && + (OR == OW_Complete || OR == OW_MaybePartial)) + KillingDef->setOptimized(CurrentDef); + + // Once a may-aliasing def is encountered do not set an optimized + // access. + if (OR != OW_None) + CanOptimize = false; + } + // If Current does not write to the same object as KillingDef, check // the next candidate. if (OR == OW_Unknown || OR == OW_None) From 63454b3994343653c7a4efa7d1126e9e4a74196a Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 30 Nov 2021 15:40:14 +0000 Subject: [PATCH 074/293] [DSE] Use optimized access if available for redundant store elimination. Using the optimized access enables additional optimizations in cases where the defining access is a non-aliasing store. Alternatively we could also walk upwards and skip non-aliasing defs here, but my experiments so far showed that this will noticeably increase compile-time for little extra gain compared to just using the optimized access. Improvements of dse.NumRedundantStores on MultiSource/CINT2006/CPF2006 on X86 with -O3: test-suite...-typeset/consumer-typeset.test 1.00 76.00 7500.0% test-suite.../Benchmarks/Bullet/bullet.test 3.00 12.00 300.0% test-suite...006/453.povray/453.povray.test 3.00 6.00 100.0% test-suite...telecomm-gsm/telecomm-gsm.test 1.00 2.00 100.0% test-suite...ediabench/gsm/toast/toast.test 1.00 2.00 100.0% test-suite...marks/7zip/7zip-benchmark.test 1.00 2.00 100.0% test-suite...ications/JM/lencod/lencod.test 7.00 10.00 42.9% test-suite...6/464.h264ref/464.h264ref.test 6.00 8.00 33.3% test-suite...ications/JM/ldecod/ldecod.test 6.00 7.00 16.7% test-suite...006/447.dealII/447.dealII.test 33.00 33.00 0.0% test-suite...6/471.omnetpp/471.omnetpp.test NaN 1.00 nan% test-suite...006/450.soplex/450.soplex.test NaN 2.00 nan% test-suite.../CINT2006/403.gcc/403.gcc.test NaN 7.00 nan% test-suite...lications/ClamAV/clamscan.test NaN 1.00 nan% test-suite...CI_Purple/SMG2000/smg2000.test NaN 3.00 nan% Follow-up to D111727. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D112315 (cherry-picked from c9ad356266f3) --- .../Scalar/DeadStoreElimination.cpp | 9 ++- .../stores-of-existing-values.ll | 61 ++++++++++++------- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index 7efe123336260..f31a425e57827 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1935,7 +1935,14 @@ struct DSEState { if (SkipStores.contains(Def) || MSSA.isLiveOnEntryDef(Def) || !isRemovable(Def->getMemoryInst())) continue; - auto *UpperDef = dyn_cast(Def->getDefiningAccess()); + MemoryDef *UpperDef; + // To conserve compile-time, we avoid walking to the next clobbering def. + // Instead, we just try to get the optimized access, if it exists. DSE + // will try to optimize defs during the earlier traversal. + if (Def->isOptimized()) + UpperDef = dyn_cast(Def->getOptimized()); + else + UpperDef = dyn_cast(Def->getDefiningAccess()); if (!UpperDef || MSSA.isLiveOnEntryDef(UpperDef)) continue; diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index 8419dcadf3e19..ad6a8adfc7a5d 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -1,5 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -basic-aa -dse -S %s | FileCheck %s +; RUN: opt -basic-aa -dse -dse-optimize-memoryssa=false -S %s | FileCheck --check-prefixes=CHECK,UNOPT %s +; RUN: opt -basic-aa -dse -dse-optimize-memoryssa -S %s | FileCheck --check-prefixes=CHECK,OPT %s +; RUN: opt -basic-aa -dse -S %s | FileCheck --check-prefixes=CHECK,UNOPT %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" @@ -315,17 +317,28 @@ bb3: ; The store in bb3 can be eliminated, because the store in bb1 cannot alias it. define void @test10(i32* noalias %P, i32* %Q, i1 %c) { -; CHECK-LABEL: @test10( -; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 -; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] -; CHECK: bb1: -; CHECK-NEXT: store i32 10, i32* [[Q:%.*]], align 4 -; CHECK-NEXT: br label [[BB3:%.*]] -; CHECK: bb2: -; CHECK-NEXT: ret void -; CHECK: bb3: -; CHECK-NEXT: store i32 0, i32* [[P]], align 4 -; CHECK-NEXT: ret void +; UNOPT-LABEL: @test10( +; UNOPT-NEXT: store i32 0, i32* [[P:%.*]], align 4 +; UNOPT-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; UNOPT: bb1: +; UNOPT-NEXT: store i32 10, i32* [[Q:%.*]], align 4 +; UNOPT-NEXT: br label [[BB3:%.*]] +; UNOPT: bb2: +; UNOPT-NEXT: ret void +; UNOPT: bb3: +; UNOPT-NEXT: store i32 0, i32* [[P]], align 4 +; UNOPT-NEXT: ret void +; +; OPT-LABEL: @test10( +; OPT-NEXT: store i32 0, i32* [[P:%.*]], align 4 +; OPT-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; OPT: bb1: +; OPT-NEXT: store i32 10, i32* [[Q:%.*]], align 4 +; OPT-NEXT: br label [[BB3:%.*]] +; OPT: bb2: +; OPT-NEXT: ret void +; OPT: bb3: +; OPT-NEXT: ret void ; store i32 0, i32* %P br i1 %c, label %bb1, label %bb2 @@ -412,13 +425,19 @@ define void @test12_memset_simple(i8* %ptr) { } define void @test12_memset_other_store_in_between(i8* %ptr) { -; CHECK-LABEL: @test12_memset_other_store_in_between( -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) -; CHECK-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 -; CHECK-NEXT: store i8 8, i8* [[PTR_4]], align 1 -; CHECK-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5 -; CHECK-NEXT: store i8 0, i8* [[PTR_5]], align 1 -; CHECK-NEXT: ret void +; UNOPT-LABEL: @test12_memset_other_store_in_between( +; UNOPT-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) +; UNOPT-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 +; UNOPT-NEXT: store i8 8, i8* [[PTR_4]], align 1 +; UNOPT-NEXT: [[PTR_5:%.*]] = getelementptr i8, i8* [[PTR]], i64 5 +; UNOPT-NEXT: store i8 0, i8* [[PTR_5]], align 1 +; UNOPT-NEXT: ret void +; +; OPT-LABEL: @test12_memset_other_store_in_between( +; OPT-NEXT: call void @llvm.memset.p0i8.i64(i8* [[PTR:%.*]], i8 0, i64 10, i1 false) +; OPT-NEXT: [[PTR_4:%.*]] = getelementptr i8, i8* [[PTR]], i64 4 +; OPT-NEXT: store i8 8, i8* [[PTR_4]], align 1 +; OPT-NEXT: ret void ; call void @llvm.memset.p0i8.i64(i8* %ptr, i8 0, i64 10, i1 false) %ptr.4 = getelementptr i8, i8* %ptr, i64 4 @@ -506,8 +525,8 @@ declare i8* @strcat(i8*, i8*) nounwind argmemonly define void @test14_strcat(i8* noalias %P, i8* noalias %Q) { ; CHECK-LABEL: @test14_strcat( -; CHECK-NEXT: call i8* @strcat(i8* [[P:%.*]], i8* [[Q:%.*]]) -; CHECK-NEXT: call i8* @strcat(i8* [[P]], i8* [[Q]]) +; CHECK-NEXT: [[CALL1:%.*]] = call i8* @strcat(i8* [[P:%.*]], i8* [[Q:%.*]]) +; CHECK-NEXT: [[CALL2:%.*]] = call i8* @strcat(i8* [[P]], i8* [[Q]]) ; CHECK-NEXT: ret void ; %call1 = call i8* @strcat(i8* %P, i8* %Q) From d267dc9aab05118440a1bdf16550aab0042a3650 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 1 Dec 2021 08:29:23 +0000 Subject: [PATCH 075/293] [DSE] Allow DSE to optimize MemorySSA by default. This allows for better optimization of 'stores-of-existing-values' and possibly helps passes further down the pipeline. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D113712 (cherry-picked from 7de410440d46) --- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp | 4 ++-- .../DeadStoreElimination/stores-of-existing-values.ll | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index f31a425e57827..5263d5c7e1c82 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -164,8 +164,8 @@ static cl::opt MemorySSAPathCheckLimit( // those cases, the flag can be used to check if DSE's MemorySSA optimizations // impact follow-up passes. static cl::opt - OptimizeMemorySSA("dse-optimize-memoryssa", cl::init(false), cl::Hidden, - cl::desc("Allow DSE to optimize memory accesses")); + OptimizeMemorySSA("dse-optimize-memoryssa", cl::init(true), cl::Hidden, + cl::desc("Allow DSE to optimize memory accesses.")); //===----------------------------------------------------------------------===// // Helper functions diff --git a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll index ad6a8adfc7a5d..b4512606bb604 100644 --- a/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll +++ b/llvm/test/Transforms/DeadStoreElimination/stores-of-existing-values.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -basic-aa -dse -dse-optimize-memoryssa=false -S %s | FileCheck --check-prefixes=CHECK,UNOPT %s ; RUN: opt -basic-aa -dse -dse-optimize-memoryssa -S %s | FileCheck --check-prefixes=CHECK,OPT %s -; RUN: opt -basic-aa -dse -S %s | FileCheck --check-prefixes=CHECK,UNOPT %s +; RUN: opt -basic-aa -dse -S %s | FileCheck --check-prefixes=CHECK,OPT %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" From 15da5c8c55321f9dba4175ec9d623aff7e05c521 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Wed, 1 Dec 2021 14:39:00 -0800 Subject: [PATCH 076/293] Add missing default specifier --- .../Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h index 711c36941495b..93e66b0892f13 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h @@ -210,7 +210,7 @@ class SwiftLanguageRuntimeImpl { virtual bool addImage( llvm::function_ref, uint64_t>( swift::ReflectionSectionKind)> - find_section); + find_section) = 0; virtual bool addImage(swift::remote::RemoteAddress image_start) = 0; virtual bool readELF(swift::remote::RemoteAddress ImageStart, llvm::Optional FileBuffer) = 0; From c6b5e7e7dd298d5765b2ac8648483fe2707bfe35 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 2 Dec 2021 14:50:14 +0000 Subject: [PATCH 077/293] [AnnotationRemarks] Support generating annotation remarks with -O0. This matches the legacy pass manager behavior. If remarks are not enabled the pass is effectively a no-op. (cherry-picked from 770a50b28c00211f9a0ceb549da1f6fd9bb405a8) --- llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h | 1 + llvm/lib/Passes/PassBuilder.cpp | 2 ++ llvm/test/Other/new-pm-O0-defaults.ll | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h b/llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h index d76b55babc745..45983ad9d5716 100644 --- a/llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h +++ b/llvm/include/llvm/Transforms/Scalar/AnnotationRemarks.h @@ -22,6 +22,7 @@ class Function; struct AnnotationRemarksPass : public PassInfoMixin { PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + static bool isRequired() { return true; } }; } // namespace llvm diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 8b8d475417474..5bae7ce91807a 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1998,6 +1998,8 @@ ModulePassManager PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level, if (LTOPreLink) addRequiredLTOPreLinkPasses(MPM); + MPM.addPass(createModuleToFunctionPassAdaptor(AnnotationRemarksPass())); + return MPM; } diff --git a/llvm/test/Other/new-pm-O0-defaults.ll b/llvm/test/Other/new-pm-O0-defaults.ll index e7c4dfdbc7588..1481a2b9d26bf 100644 --- a/llvm/test/Other/new-pm-O0-defaults.ll +++ b/llvm/test/Other/new-pm-O0-defaults.ll @@ -58,8 +58,9 @@ ; CHECK-LTO-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-LTO-NEXT: Running pass: LowerTypeTestsPass ; CHECK-LTO-NEXT: Running pass: LowerTypeTestsPass +; CHECK-CORO-NEXT: Running pass: AnnotationRemarksPass ; CHECK-LTO-NEXT: Running pass: AnnotationRemarksPass -; CHECK-LTO-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-LTO-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-NEXT: Running pass: PrintModulePass ; Make sure we get the IR back out without changes when we print the module. From 35470763232392569e136bec6ccf1ccb44974fef Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 2 Dec 2021 15:41:31 +0000 Subject: [PATCH 078/293] [Clang] Fix LTO pipeline test after 770a50b28c00211f9a. (cherry-picked from 89d645dd3a60cd5bb3cc9a78ad17d3b063cc98bf) --- clang/test/CodeGen/lto-newpm-pipeline.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/CodeGen/lto-newpm-pipeline.c b/clang/test/CodeGen/lto-newpm-pipeline.c index c2cd3a4720cca..a773e10ed6f5b 100644 --- a/clang/test/CodeGen/lto-newpm-pipeline.c +++ b/clang/test/CodeGen/lto-newpm-pipeline.c @@ -32,6 +32,7 @@ // CHECK-FULL-O0-NEXT: Running pass: CoroCleanupPass // CHECK-FULL-O0-NEXT: Running pass: CanonicalizeAliasesPass // CHECK-FULL-O0-NEXT: Running pass: NameAnonGlobalPass +// CHECK-FULL-O0-NEXT: Running pass: AnnotationRemarksPass // CHECK-FULL-O0-NEXT: Running pass: BitcodeWriterPass // CHECK-THIN-O0: Running pass: AlwaysInlinerPass @@ -40,6 +41,7 @@ // CHECK-THIN-O0: Running pass: CoroCleanupPass // CHECK-THIN-O0-NEXT: Running pass: CanonicalizeAliasesPass // CHECK-THIN-O0-NEXT: Running pass: NameAnonGlobalPass +// CHECK-THIN-O0-NEXT: Running pass: AnnotationRemarksPass // CHECK-THIN-O0-NEXT: Running pass: ThinLTOBitcodeWriterPass // TODO: The LTO pre-link pipeline currently invokes From 5897a27e42b181ab4dc0ccc4a7ed9bad47ff2683 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 2 Dec 2021 18:08:54 -0800 Subject: [PATCH 079/293] Simplify logic to identify dyld_sim in Simulator debugging on macos When debugging a Simulator process on macOS (e.g. the iPhone simulator), the process will have both a dyld, and a dyld_sim present. The dyld_sim is an iOS Simulator binary. The dyld is a macOS binary. Both are MH_DYLINKER filetypes. lldb needs to identify & set a breakpoint in dyld, so it has to distinguish between these two. Previously lldb was checking if the inferior target was x86 (indicating macOS) and the OS of the MH_DYLINKER binary was iOS/watchOS/etc -- if so, then this is dyld_sim and we should ignore it. Now with arm64 macOS systems, this check was invalid, and we would set our breakpoint for new binaries being loaded in dyld_sim, causing binary loading to be missed by lldb. This patch uses the Target's ArchSpec triple environment, to see if this process is a simulator process. If this is a Simulator process, then we only recognize a MH_DYLINKER binary with OS type macOS as being dyld. This patch also removes some code that handled pre-2016 era debugservers which didn't give us the OS type for each binary. This was only being used on macOS, where we don't need to handle the presence of very old debugservers. Differential Revision: https://reviews.llvm.org/D115001 rdar://85907839 (cherry picked from commit fddafa110d8628851a48939fe956864b318e8e53) --- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 37 +++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index 95bd3988aaf75..319d0eaa7aa8b 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -540,35 +540,18 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos( const size_t image_infos_size = image_infos.size(); for (size_t i = 0; i < image_infos_size; i++) { if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER) { - // In a "simulator" process (an x86 process that is - // ios/tvos/watchos/bridgeos) we will have two dyld modules -- + // In a "simulator" process we will have two dyld modules -- // a "dyld" that we want to keep track of, and a "dyld_sim" which - // we don't need to keep track of here. If the target is an x86 - // system and the OS of the dyld binary is ios/tvos/watchos/bridgeos, - // then we are looking at dyld_sym. - - // debugserver has only recently (late 2016) started sending up the os - // type for each binary it sees -- so if we don't have an os type, use a - // filename check as our next best guess. - if (image_infos[i].os_type == llvm::Triple::OSType::UnknownOS) { - if (image_infos[i].file_spec.GetFilename() != g_dyld_sim_filename) { - dyld_idx = i; - } - } else if (target_arch.GetTriple().getArch() == llvm::Triple::x86 || - target_arch.GetTriple().getArch() == llvm::Triple::x86_64) { - if (image_infos[i].os_type != llvm::Triple::OSType::IOS && - image_infos[i].os_type != llvm::Triple::TvOS && - image_infos[i].os_type != llvm::Triple::WatchOS) { - // NEED_BRIDGEOS_TRIPLE image_infos[i].os_type != llvm::Triple::BridgeOS) { - dyld_idx = i; - } + // we don't need to keep track of here. dyld_sim will have a non-macosx + // OS. + if (target_arch.GetTriple().getEnvironment() == llvm::Triple::Simulator && + image_infos[i].os_type != llvm::Triple::OSType::MacOSX) { + continue; } - else { - // catch-all for any other environment -- trust that dyld is actually - // dyld - dyld_idx = i; - } - } else if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) { + + dyld_idx = i; + } + if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) { exe_idx = i; } } From 703f6f3cb381c15c7b3116152a9028358e0550b2 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 17 Aug 2021 18:30:48 -0700 Subject: [PATCH 080/293] [lldb] Include arm64 in affected_by_radar_34562999 The same issue impacts arm64, both on-device and on Apple Silicon. (cherry picked from commit c64d1855b9a912cd6e3d0227ecd939c93c68fd9e) --- .../test/API/functionalities/return-value/TestReturnValue.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/functionalities/return-value/TestReturnValue.py b/lldb/test/API/functionalities/return-value/TestReturnValue.py index fe79c46c30f01..54abfe46c5607 100644 --- a/lldb/test/API/functionalities/return-value/TestReturnValue.py +++ b/lldb/test/API/functionalities/return-value/TestReturnValue.py @@ -22,9 +22,10 @@ def affected_by_pr44132(self): return (self.getArchitecture() in ["aarch64", "arm"] and self.getPlatform() in ["freebsd", "linux"]) - # ABIMacOSX_arm can't fetch simple values inside a structure + # ABIMacOSX_arm(64) can't fetch simple values inside a structure def affected_by_radar_34562999(self): - return (self.getArchitecture() == 'armv7' or self.getArchitecture() == 'armv7k') and self.platformIsDarwin() + arch = self.getArchitecture().lower() + return arch in ['arm64', 'arm64e', 'armv7', 'armv7k'] and self.platformIsDarwin() @expectedFailureAll(oslist=["freebsd"], archs=["i386"], bugnumber="llvm.org/pr48376") From 97780e8369bc57c71b0561378d76cea2190994e0 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 17 Aug 2021 18:05:46 -0700 Subject: [PATCH 081/293] [lldb] Extend isAArch64 to arm64 and arm64e This fixes TestMemoryTag on Apple Silicon. (cherry picked from commit a452ca471c0e3d0b9999cd26d16a45b6bc43efee) --- lldb/packages/Python/lldbsuite/test/lldbtest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index cd6eba144391c..4cc1e7d2c2ffa 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1297,7 +1297,8 @@ def getCPUInfo(self): def isAArch64(self): """Returns true if the architecture is AArch64.""" - return self.getArchitecture().lower() == "aarch64" + arch = self.getArchitecture().lower() + return arch in ["aarch64", "arm64", "arm64e"] def isAArch64SVE(self): return self.isAArch64() and "sve" in self.getCPUInfo() From 47cb1dded58895df9eea447e4705743b32ba52a9 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 3 Dec 2021 16:11:42 -0800 Subject: [PATCH 082/293] [lldb] Re-enable XFAILed tests on Apple Silicon --- .../tsan/swift-access-race/TestTsanSwiftAccessRace.py | 1 - lldb/test/API/functionalities/tsan/swift/TestTsanSwift.py | 1 - .../test/API/lang/swift/multi_optionals/TestMultiOptionals.py | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/lldb/test/API/functionalities/tsan/swift-access-race/TestTsanSwiftAccessRace.py b/lldb/test/API/functionalities/tsan/swift-access-race/TestTsanSwiftAccessRace.py index 40d07dbd96c10..138f4fe0d3302 100644 --- a/lldb/test/API/functionalities/tsan/swift-access-race/TestTsanSwiftAccessRace.py +++ b/lldb/test/API/functionalities/tsan/swift-access-race/TestTsanSwiftAccessRace.py @@ -30,7 +30,6 @@ class TsanSwiftAccessRaceTestCase(lldbtest.TestBase): @skipIfLinux @skipUnlessSwiftThreadSanitizer @skipIfAsan # This test does not behave reliable with an ASANified LLDB. - @expectedFailureAll(archs=['arm64']) def test_tsan_swift(self): self.build() self.do_test() diff --git a/lldb/test/API/functionalities/tsan/swift/TestTsanSwift.py b/lldb/test/API/functionalities/tsan/swift/TestTsanSwift.py index 42115486a69ec..e2f8bc2118783 100644 --- a/lldb/test/API/functionalities/tsan/swift/TestTsanSwift.py +++ b/lldb/test/API/functionalities/tsan/swift/TestTsanSwift.py @@ -29,7 +29,6 @@ class TsanSwiftTestCase(lldbtest.TestBase): @skipIfLinux @skipUnlessSwiftThreadSanitizer @skipIfAsan # This test does not behave reliable with an ASANified LLDB. - @expectedFailureAll(archs=['arm64']) def test_tsan_swift(self): self.build() self.do_test() diff --git a/lldb/test/API/lang/swift/multi_optionals/TestMultiOptionals.py b/lldb/test/API/lang/swift/multi_optionals/TestMultiOptionals.py index d36c790d1dabc..a327938565f68 100644 --- a/lldb/test/API/lang/swift/multi_optionals/TestMultiOptionals.py +++ b/lldb/test/API/lang/swift/multi_optionals/TestMultiOptionals.py @@ -12,6 +12,4 @@ import lldbsuite.test.lldbinline as lldbinline from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest, - expectedFailureAll(archs=['arm64', 'arm64e', 'arm64_32'], bugnumber="")]) - +lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) From 6976b2b8be643ec143edc796398ae4768551d73e Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 28 Oct 2021 17:57:41 -0700 Subject: [PATCH 083/293] [lldb] Fix TestMacCatalyst.py (cherry picked from commit 2aa3b56339423969f0c89fe10d81f32ff77db2d2) --- lldb/test/API/macosx/macCatalyst/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/macosx/macCatalyst/Makefile b/lldb/test/API/macosx/macCatalyst/Makefile index 324d0e1543754..d162c33d774f9 100644 --- a/lldb/test/API/macosx/macCatalyst/Makefile +++ b/lldb/test/API/macosx/macCatalyst/Makefile @@ -1,6 +1,7 @@ C_SOURCES := main.c -CFLAGS_EXTRAS := -target $(ARCH)-apple-ios13.0-macabi +override TRIPLE := $(ARCH)-apple-ios13.1-macabi +CFLAGS_EXTRAS := -target $(TRIPLE) # FIXME: rdar://problem/54986190 # There is a Clang driver change missing on llvm.org. From d138bc52da72f9d75a730374ae376829936cca28 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 3 Dec 2021 18:24:29 -0800 Subject: [PATCH 084/293] [lldb] Update TestPlaygrounds.py for Apple Silicon --- lldb/test/API/lang/swift/playgrounds/TestPlaygrounds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/lang/swift/playgrounds/TestPlaygrounds.py b/lldb/test/API/lang/swift/playgrounds/TestPlaygrounds.py index 7169e6edcec9e..a071138cd382f 100644 --- a/lldb/test/API/lang/swift/playgrounds/TestPlaygrounds.py +++ b/lldb/test/API/lang/swift/playgrounds/TestPlaygrounds.py @@ -53,7 +53,7 @@ def get_build_triple(self): version = '7.0' triple = '{}-{}-{}{}'.format(arch, vendor, os, version) else: - triple = 'x86_64-apple-macosx10.10' + triple = '{}-apple-macosx10.10'.format(platform.machine()) return triple def get_run_triple(self): From caa35297c2b00bae83deab38c00e1bfe482d40f1 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 6 Dec 2021 11:48:32 -0800 Subject: [PATCH 085/293] [lldb] Include swiftc version number in mismatch warning --- lldb/source/Target/Process.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 06ddb998cb9b0..7331332f08ddb 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -5897,14 +5897,21 @@ void Process::PrintWarningToolchainMismatch(const SymbolContext &sc) { return; if (sc.GetLanguage() != eLanguageTypeSwift) return; - if (SymbolFile *sym_file = sc.module_sp->GetSymbolFile()) - if (sym_file->GetProducerVersion(*sc.comp_unit) != - swift::version::Version::getCurrentCompilerVersion()) - PrintWarning(Process::Warnings::eWarningsToolchainMismatch, - sc.module_sp.get(), - "%s was compiled with a Swift compiler from a different " - "toolchain. Swift expression evaluation may not work.\n", - sc.module_sp->GetFileSpec().GetFilename().GetCString()); + if (SymbolFile *sym_file = sc.module_sp->GetSymbolFile()) { + llvm::VersionTuple sym_file_version = + sym_file->GetProducerVersion(*sc.comp_unit); + llvm::VersionTuple swift_version = + swift::version::Version::getCurrentCompilerVersion(); + if (sym_file_version != swift_version) + PrintWarning( + Process::Warnings::eWarningsToolchainMismatch, sc.module_sp.get(), + "%s was compiled with a Swift compiler from a different toolchain " + "(version '%s') than the Swift compiler integrated into LLDB " + "(version '%s'). Swift expression evaluation may not work.\n", + sc.module_sp->GetFileSpec().GetFilename().GetCString(), + sym_file_version.getAsString().c_str(), + swift_version.getAsString().c_str()); + } } #endif From 01ca45fe7f563b0b1c705ca20cf5523a840af553 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 6 Dec 2021 15:34:42 -0800 Subject: [PATCH 086/293] [lldb] Remove trivial scoped timer from collectTypeInfo --- lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index c245dedc4b2dc..c521a213766be 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -977,7 +977,6 @@ static uint32_t collectTypeInfo(TypeSystemSwiftTypeRef *module_holder, swift::Demangle::NodePointer node, bool &unresolved_typealias, bool generic_walk = false) { - LLDB_SCOPED_TIMER(); if (!node) return 0; uint32_t swift_flags = eTypeIsSwift; From 7907813e2509ba2720c42d396c69f7a20b0a883f Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 25 Oct 2021 15:49:46 -0700 Subject: [PATCH 087/293] [lldb] Configure CMake policy CMP0116 for standalone builds Using CMake >=3.20 results in many warnings about this new policy. This change silences the warnings by explicitly declaring use of the "OLD" behavior. This applies D101083 to LLDBStandalone.cmake. Differential Revision: https://reviews.llvm.org/D112497 (cherry picked from commit 65dae8b2f20c32632e48922456a305504f4e6fbe) --- lldb/cmake/modules/LLDBStandalone.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lldb/cmake/modules/LLDBStandalone.cmake b/lldb/cmake/modules/LLDBStandalone.cmake index 7fbb76d538f22..ef4d90c92e2b4 100644 --- a/lldb/cmake/modules/LLDBStandalone.cmake +++ b/lldb/cmake/modules/LLDBStandalone.cmake @@ -1,3 +1,9 @@ +# CMP0116: Ninja generators transform `DEPFILE`s from `add_custom_command()` +# New in CMake 3.20. https://cmake.org/cmake/help/latest/policy/CMP0116.html +if(POLICY CMP0116) + cmake_policy(SET CMP0116 OLD) +endif() + option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) find_package(LLVM REQUIRED CONFIG HINTS ${LLVM_DIR} NO_CMAKE_FIND_ROOT_PATH) From 874e6a50a934411ff0c82e672e21da978cb04861 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 6 Dec 2021 16:39:30 -0800 Subject: [PATCH 088/293] Teach isTriviallyCopyableType to return false when the type is an address-discriminated ptrauth type or a struct containing a field that has such a type This fixes a crash in AggExprEmitter::EmitArrayInit that occurs when it tries to initialize an array of a struct with an address-discriminated ptrauth type field from a global. rdar://85173549 --- clang/lib/AST/Type.cpp | 4 ++++ clang/test/CodeGen/ptrauth-in-c-struct.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 65fbaa8c5bf8a..d76ea0dc925bd 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2450,6 +2450,10 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const { if (hasNonTrivialObjCLifetime()) return false; + PrimitiveCopyKind PCK = isNonTrivialToPrimitiveCopy(); + if (PCK != PCK_Trivial && PCK != PCK_VolatileTrivial) + return false; + // C++11 [basic.types]p9 - See Core 2094 // Scalar types, trivially copyable class types, arrays of such types, and // cv-qualified versions of these types are collectively diff --git a/clang/test/CodeGen/ptrauth-in-c-struct.c b/clang/test/CodeGen/ptrauth-in-c-struct.c index 249cfc316f950..220a48f2a14fc 100644 --- a/clang/test/CodeGen/ptrauth-in-c-struct.c +++ b/clang/test/CodeGen/ptrauth-in-c-struct.c @@ -27,6 +27,8 @@ typedef struct { SA getSA(void); void calleeSA(SA); +int g0; + // CHECK: define void @test_copy_constructor_SA(%[[STRUCT_SA]]* %{{.*}}) // CHECK: call void @__copy_constructor_8_8_t0w4_pa1_50_8( @@ -162,3 +164,21 @@ void test_copy_constructor_SI(SI *s) { void test_parameter_SI(SI a) { } + +// CHECK-LABEL: define void @test_array( +// CHECK: %[[F1:.*]] = getelementptr inbounds %[[STRUCT_SA]], %[[STRUCT_SA]]* %{{.*}}, i32 0, i32 1 +// CHECK: %[[V0:.*]] = ptrtoint i32** %[[F1]] to i64 +// CHECK: %[[V1:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V0]], i64 50) +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (i32* @g0 to i64), i32 1, i64 %[[V1]]) +// CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to i32* +// CHECK: store i32* %[[V3]], i32** %[[F1]], align 8 +// CHECK: %[[F12:.*]] = getelementptr inbounds %[[STRUCT_SA]], %[[STRUCT_SA]]* %{{.*}}, i32 0, i32 1 +// CHECK: %[[V4:.*]] = ptrtoint i32** %[[F12]] to i64 +// CHECK: %[[V5:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V4]], i64 50) +// CHECK: %[[V6:.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (i32* @g0 to i64), i32 1, i64 %[[V5]]) +// CHECK: %[[V7:.*]] = inttoptr i64 %[[V6]] to i32* +// CHECK: store i32* %[[V7]], i32** %[[F12]], align 8 + +void test_array(void) { + const SA a[] = {{0, &g0}, {1, &g0}}; +} From cc60adfa30053469647876267f583edcd238c680 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 6 Dec 2021 18:12:41 -0800 Subject: [PATCH 089/293] remove redundant command --- .../API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py b/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py index a648a48d0fac2..7c8ea2ccb05a6 100644 --- a/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py +++ b/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py @@ -103,7 +103,6 @@ def test_dwarf_importer_exprs(self): @swiftTest def test_negative(self): lldb.SBDebugger.MemoryPressureDetected() - self.runCmd("log enable lldb types") self.runCmd("settings set symbols.use-swift-dwarfimporter false") self.build() log = self.getBuildArtifact("types.log") From 6b2c41166280fce943b898386f02c53e1567f98b Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Tue, 30 Nov 2021 22:01:07 -0800 Subject: [PATCH 090/293] [lld-macho] Remove old macho darwin lld During the llvm round table it was generally agreed that the newer macho lld implementation is feature complete enough to replace the old implementation entirely. This will reduce confusion for new users who aren't aware of the history. Differential Revision: https://reviews.llvm.org/D114842 (cherry picked from commit 9e3552523ebd3385487e01e3e7af37b8c0efaf57) --- lld/CMakeLists.txt | 2 - lld/include/lld/Common/Driver.h | 5 - lld/include/lld/Core/Reference.h | 3 +- .../lld/ReaderWriter/MachOLinkingContext.h | 505 ----- lld/include/lld/ReaderWriter/YamlContext.h | 42 - lld/lib/CMakeLists.txt | 3 - lld/lib/Core/CMakeLists.txt | 24 - lld/lib/Core/DefinedAtom.cpp | 81 - lld/lib/Core/Error.cpp | 93 - lld/lib/Core/File.cpp | 28 - lld/lib/Core/LinkingContext.cpp | 69 - lld/lib/Core/Reader.cpp | 113 -- lld/lib/Core/Resolver.cpp | 503 ----- lld/lib/Core/SymbolTable.cpp | 284 --- lld/lib/Core/Writer.cpp | 17 - lld/lib/Driver/CMakeLists.txt | 23 - lld/lib/Driver/DarwinLdDriver.cpp | 1229 ------------ lld/lib/Driver/DarwinLdOptions.td | 250 --- lld/lib/ReaderWriter/CMakeLists.txt | 20 - lld/lib/ReaderWriter/FileArchive.cpp | 227 --- lld/lib/ReaderWriter/MachO/ArchHandler.cpp | 171 -- lld/lib/ReaderWriter/MachO/ArchHandler.h | 322 ---- .../ReaderWriter/MachO/ArchHandler_arm.cpp | 1522 --------------- .../ReaderWriter/MachO/ArchHandler_arm64.cpp | 897 --------- .../ReaderWriter/MachO/ArchHandler_x86.cpp | 643 ------- .../ReaderWriter/MachO/ArchHandler_x86_64.cpp | 899 --------- lld/lib/ReaderWriter/MachO/Atoms.h | 180 -- lld/lib/ReaderWriter/MachO/CMakeLists.txt | 36 - .../ReaderWriter/MachO/CompactUnwindPass.cpp | 580 ------ lld/lib/ReaderWriter/MachO/DebugInfo.h | 106 -- lld/lib/ReaderWriter/MachO/ExecutableAtoms.h | 154 -- lld/lib/ReaderWriter/MachO/File.h | 467 ----- .../ReaderWriter/MachO/FlatNamespaceFile.h | 62 - lld/lib/ReaderWriter/MachO/GOTPass.cpp | 183 -- lld/lib/ReaderWriter/MachO/LayoutPass.cpp | 490 ----- lld/lib/ReaderWriter/MachO/LayoutPass.h | 118 -- .../MachO/MachOLinkingContext.cpp | 1104 ----------- .../ReaderWriter/MachO/MachONormalizedFile.h | 336 ---- .../MachO/MachONormalizedFileBinaryReader.cpp | 614 ------ .../MachO/MachONormalizedFileBinaryUtils.h | 213 --- .../MachO/MachONormalizedFileBinaryWriter.cpp | 1560 ---------------- .../MachO/MachONormalizedFileFromAtoms.cpp | 1657 ----------------- .../MachO/MachONormalizedFileToAtoms.cpp | 1635 ---------------- .../MachO/MachONormalizedFileYAML.cpp | 840 --------- lld/lib/ReaderWriter/MachO/MachOPasses.h | 29 - lld/lib/ReaderWriter/MachO/ObjCPass.cpp | 131 -- lld/lib/ReaderWriter/MachO/SectCreateFile.h | 101 - lld/lib/ReaderWriter/MachO/ShimPass.cpp | 128 -- lld/lib/ReaderWriter/MachO/StubsPass.cpp | 377 ---- lld/lib/ReaderWriter/MachO/TLVPass.cpp | 140 -- lld/lib/ReaderWriter/MachO/WriterMachO.cpp | 70 - lld/lib/ReaderWriter/YAML/CMakeLists.txt | 9 - .../ReaderWriter/YAML/ReaderWriterYAML.cpp | 1403 -------------- lld/test/CMakeLists.txt | 4 - .../darwin/Inputs/native-and-mach-o.objtxt | 17 - .../darwin/Inputs/native-and-mach-o2.objtxt | 19 - lld/test/darwin/cmdline-lto_library.objtxt | 11 - lld/test/darwin/cmdline-objc_gc.objtxt | 15 - .../darwin/cmdline-objc_gc_compaction.objtxt | 15 - lld/test/darwin/cmdline-objc_gc_only.objtxt | 15 - lld/test/darwin/native-and-mach-o.objtxt | 27 - lld/test/mach-o/Inputs/DependencyDump.py | 30 - .../Inputs/MacOSX.sdk/usr/lib/libSystem.tbd | 42 - lld/test/mach-o/Inputs/PIE.yaml | 6 - lld/test/mach-o/Inputs/arm-interworking.yaml | 83 - lld/test/mach-o/Inputs/arm-shims.yaml | 60 - lld/test/mach-o/Inputs/arm64/libSystem.yaml | 13 - lld/test/mach-o/Inputs/armv7/libSystem.yaml | 13 - lld/test/mach-o/Inputs/bar.yaml | 18 - lld/test/mach-o/Inputs/cstring-sections.yaml | 25 - .../mach-o/Inputs/exported_symbols_list.exp | 6 - lld/test/mach-o/Inputs/full.filelist | 3 - lld/test/mach-o/Inputs/got-order.yaml | 53 - lld/test/mach-o/Inputs/got-order2.yaml | 11 - lld/test/mach-o/Inputs/hello-world-arm64.yaml | 8 - lld/test/mach-o/Inputs/hello-world-armv6.yaml | 7 - lld/test/mach-o/Inputs/hello-world-armv7.yaml | 7 - lld/test/mach-o/Inputs/hello-world-x86.yaml | 7 - .../mach-o/Inputs/hello-world-x86_64.yaml | 8 - lld/test/mach-o/Inputs/hw.raw_bytes | 1 - .../mach-o/Inputs/interposing-section.yaml | 6 - .../mach-o/Inputs/lazy-bind-x86_64-2.yaml | 8 - .../mach-o/Inputs/lazy-bind-x86_64-3.yaml | 8 - lld/test/mach-o/Inputs/lazy-bind-x86_64.yaml | 8 - .../usr/lib/libmyshared.dylib | Bin 20628 -> 0 bytes .../lib-search-paths/usr/lib/libmystatic.a | Bin 556 -> 0 bytes .../lib-search-paths/usr/local/lib/file.o | Bin 404 -> 0 bytes lld/test/mach-o/Inputs/libbar.a | Bin 824 -> 0 bytes lld/test/mach-o/Inputs/libfoo.a | Bin 1320 -> 0 bytes .../no-version-min-load-command-object.yaml | 22 - lld/test/mach-o/Inputs/order_file-basic.order | 11 - lld/test/mach-o/Inputs/partial.filelist | 3 - .../Inputs/re-exported-dylib-ordinal.yaml | 21 - .../Inputs/re-exported-dylib-ordinal2.yaml | 18 - .../Inputs/re-exported-dylib-ordinal3.yaml | 19 - lld/test/mach-o/Inputs/swift-version-1.yaml | 18 - .../Inputs/unwind-info-simple-arm64.yaml | 13 - .../Inputs/use-dylib-install-names.yaml | 28 - lld/test/mach-o/Inputs/use-simple-dylib.yaml | 58 - .../mach-o/Inputs/write-final-sections.yaml | 20 - lld/test/mach-o/Inputs/wrong-arch-error.yaml | 24 - lld/test/mach-o/Inputs/x86/libSystem.yaml | 13 - lld/test/mach-o/Inputs/x86_64/libSystem.yaml | 13 - lld/test/mach-o/PIE.yaml | 40 - lld/test/mach-o/align_text.yaml | 45 - lld/test/mach-o/arm-interworking-movw.yaml | 393 ---- lld/test/mach-o/arm-interworking.yaml | 288 --- lld/test/mach-o/arm-shims.yaml | 126 -- .../mach-o/arm-subsections-via-symbols.yaml | 60 - .../mach-o/arm64-reloc-negDelta32-fixup.yaml | 124 -- .../arm64-relocs-errors-delta64-offset.yaml | 65 - lld/test/mach-o/arm64-section-order.yaml | 67 - lld/test/mach-o/bind-opcodes.yaml | 140 -- lld/test/mach-o/cstring-sections.yaml | 65 - .../mach-o/data-in-code-load-command.yaml | 35 - lld/test/mach-o/data-only-dylib.yaml | 27 - lld/test/mach-o/dead-strip-globals.yaml | 31 - lld/test/mach-o/debug-syms.yaml | 249 --- lld/test/mach-o/demangle.yaml | 74 - lld/test/mach-o/dependency_info.yaml | 19 - .../mach-o/do-not-emit-unwind-fde-arm64.yaml | 208 --- lld/test/mach-o/dso_handle.yaml | 62 - lld/test/mach-o/dylib-install-names.yaml | 74 - lld/test/mach-o/eh-frame-relocs-arm64.yaml | 318 ---- lld/test/mach-o/empty-sections.yaml | 9 - .../mach-o/error-simulator-vs-macosx.yaml | 30 - lld/test/mach-o/exe-offsets.yaml | 45 - lld/test/mach-o/exe-segment-overlap.yaml | 44 - lld/test/mach-o/executable-exports.yaml | 46 - lld/test/mach-o/export-trie-order.yaml | 62 - .../mach-o/exported_symbols_list-dylib.yaml | 77 - .../mach-o/exported_symbols_list-obj.yaml | 67 - .../mach-o/exported_symbols_list-undef.yaml | 55 - lld/test/mach-o/fat-archive.yaml | 45 - lld/test/mach-o/filelist.yaml | 18 - .../mach-o/flat_namespace_undef_error.yaml | 17 - .../mach-o/flat_namespace_undef_suppress.yaml | 17 - lld/test/mach-o/force_load-dylib.yaml | 45 - lld/test/mach-o/force_load-x86_64.yaml | 38 - lld/test/mach-o/framework-user-paths.yaml | 41 - .../mach-o/function-starts-load-command.yaml | 32 - lld/test/mach-o/gcc_except_tab-got-arm64.yaml | 53 - lld/test/mach-o/got-order.yaml | 69 - lld/test/mach-o/hello-world-arm64.yaml | 102 - lld/test/mach-o/hello-world-armv6.yaml | 64 - lld/test/mach-o/hello-world-armv7.yaml | 76 - lld/test/mach-o/hello-world-x86.yaml | 62 - lld/test/mach-o/hello-world-x86_64.yaml | 120 -- lld/test/mach-o/image-base.yaml | 28 - lld/test/mach-o/infer-arch.yaml | 29 - lld/test/mach-o/interposing-section.yaml | 72 - lld/test/mach-o/keep_private_externs.yaml | 63 - lld/test/mach-o/lazy-bind-x86_64.yaml | 111 -- lld/test/mach-o/lc_segment_filesize.yaml | 31 - lld/test/mach-o/lib-search-paths.yaml | 16 - lld/test/mach-o/library-order.yaml | 45 - lld/test/mach-o/library-rescan.yaml | 46 - .../libresolve-bizarre-root-override.yaml | 17 - .../libresolve-multiple-syslibroots.yaml | 17 - .../mach-o/libresolve-one-syslibroot.yaml | 25 - lld/test/mach-o/libresolve-simple.yaml | 21 - lld/test/mach-o/libresolve-user-paths.yaml | 20 - lld/test/mach-o/libresolve-z.yaml | 21 - lld/test/mach-o/lit.local.cfg | 4 - lld/test/mach-o/load-commands-size.yaml | 305 --- lld/test/mach-o/mach_header-cpusubtype.yaml | 34 - lld/test/mach-o/mh_bundle_header.yaml | 54 - lld/test/mach-o/mh_dylib_header.yaml | 53 - lld/test/mach-o/objc-category-list-atom.yaml | 70 - .../objc-image-info-host-vs-simulator.yaml | 23 - .../mach-o/objc-image-info-invalid-size.yaml | 20 - .../objc-image-info-invalid-version.yaml | 20 - ...c-image-info-mismatched-swift-version.yaml | 20 - .../mach-o/objc-image-info-pass-output.yaml | 30 - .../objc-image-info-simulator-vs-host.yaml | 23 - .../objc-image-info-unsupported-gc.yaml | 20 - lld/test/mach-o/objc_export_list.yaml | 63 - lld/test/mach-o/order_file-basic.yaml | 75 - lld/test/mach-o/parse-aliases.yaml | 90 - lld/test/mach-o/parse-arm-relocs.yaml | 818 -------- lld/test/mach-o/parse-cfstring32.yaml | 94 - lld/test/mach-o/parse-cfstring64.yaml | 108 -- lld/test/mach-o/parse-compact-unwind32.yaml | 72 - lld/test/mach-o/parse-compact-unwind64.yaml | 76 - lld/test/mach-o/parse-data-in-code-armv7.yaml | 157 -- lld/test/mach-o/parse-data-in-code-x86.yaml | 77 - lld/test/mach-o/parse-data-relocs-arm64.yaml | 244 --- lld/test/mach-o/parse-data-relocs-x86_64.yaml | 372 ---- lld/test/mach-o/parse-data.yaml | 119 -- .../mach-o/parse-eh-frame-relocs-x86_64.yaml | 176 -- lld/test/mach-o/parse-eh-frame-x86-anon.yaml | 129 -- .../mach-o/parse-eh-frame-x86-labeled.yaml | 193 -- lld/test/mach-o/parse-eh-frame.yaml | 88 - lld/test/mach-o/parse-function.yaml | 100 - lld/test/mach-o/parse-initializers32.yaml | 84 - lld/test/mach-o/parse-initializers64.yaml | 105 -- lld/test/mach-o/parse-literals-error.yaml | 25 - lld/test/mach-o/parse-literals.yaml | 93 - lld/test/mach-o/parse-non-lazy-pointers.yaml | 98 - lld/test/mach-o/parse-relocs-x86.yaml | 296 --- lld/test/mach-o/parse-section-no-symbol.yaml | 23 - lld/test/mach-o/parse-tentative-defs.yaml | 88 - lld/test/mach-o/parse-text-relocs-arm64.yaml | 237 --- lld/test/mach-o/parse-text-relocs-x86_64.yaml | 204 -- lld/test/mach-o/parse-tlv-relocs-x86-64.yaml | 100 - .../mach-o/re-exported-dylib-ordinal.yaml | 46 - lld/test/mach-o/rpath.yaml | 38 - lld/test/mach-o/run-tlv-pass-x86-64.yaml | 144 -- lld/test/mach-o/sdk-version-error.yaml | 22 - lld/test/mach-o/sectalign.yaml | 80 - lld/test/mach-o/sectattrs.yaml | 30 - lld/test/mach-o/sectcreate.yaml | 12 - lld/test/mach-o/seg-protection-arm64.yaml | 78 - lld/test/mach-o/seg-protection-x86_64.yaml | 78 - lld/test/mach-o/source-version.yaml | 28 - lld/test/mach-o/stack-size.yaml | 24 - lld/test/mach-o/string-table.yaml | 66 - lld/test/mach-o/stub-link.s | 21 - .../subsections-via-symbols-default.yaml | 28 - ...olevel_namespace_undef_dynamic_lookup.yaml | 17 - ...evel_namespace_undef_warning_suppress.yaml | 23 - lld/test/mach-o/unwind-info-simple-arm64.yaml | 267 --- .../mach-o/unwind-info-simple-x86_64.yaml | 133 -- .../mach-o/upward-dylib-load-command.yaml | 48 - lld/test/mach-o/upward-dylib-paths.yaml | 18 - lld/test/mach-o/usage.yaml | 8 - lld/test/mach-o/use-dylib.yaml | 39 - lld/test/mach-o/use-simple-dylib.yaml | 73 - .../version-min-load-command-object.yaml | 35 - lld/test/mach-o/version-min-load-command.yaml | 43 - lld/test/mach-o/write-final-sections.yaml | 165 -- lld/test/mach-o/wrong-arch-error.yaml | 28 - lld/tools/lld/CMakeLists.txt | 3 +- lld/tools/lld/lld.cpp | 15 +- lld/unittests/CMakeLists.txt | 16 - lld/unittests/DriverTests/CMakeLists.txt | 9 - .../DriverTests/DarwinLdDriverTest.cpp | 263 --- lld/unittests/MachOTests/CMakeLists.txt | 14 - .../MachONormalizedFileBinaryReaderTests.cpp | 753 -------- .../MachONormalizedFileBinaryWriterTests.cpp | 695 ------- .../MachONormalizedFileToAtomsTests.cpp | 140 -- .../MachONormalizedFileYAMLTests.cpp | 762 -------- .../MachOTests/empty_obj_x86_armv7.txt | 1272 ------------- .../utils/gn/secondary/lld/tools/lld/BUILD.gn | 2 - 244 files changed, 7 insertions(+), 36448 deletions(-) delete mode 100644 lld/include/lld/ReaderWriter/MachOLinkingContext.h delete mode 100644 lld/include/lld/ReaderWriter/YamlContext.h delete mode 100644 lld/lib/CMakeLists.txt delete mode 100644 lld/lib/Core/CMakeLists.txt delete mode 100644 lld/lib/Core/DefinedAtom.cpp delete mode 100644 lld/lib/Core/Error.cpp delete mode 100644 lld/lib/Core/File.cpp delete mode 100644 lld/lib/Core/LinkingContext.cpp delete mode 100644 lld/lib/Core/Reader.cpp delete mode 100644 lld/lib/Core/Resolver.cpp delete mode 100644 lld/lib/Core/SymbolTable.cpp delete mode 100644 lld/lib/Core/Writer.cpp delete mode 100644 lld/lib/Driver/CMakeLists.txt delete mode 100644 lld/lib/Driver/DarwinLdDriver.cpp delete mode 100644 lld/lib/Driver/DarwinLdOptions.td delete mode 100644 lld/lib/ReaderWriter/CMakeLists.txt delete mode 100644 lld/lib/ReaderWriter/FileArchive.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/ArchHandler.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/ArchHandler.h delete mode 100644 lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/Atoms.h delete mode 100644 lld/lib/ReaderWriter/MachO/CMakeLists.txt delete mode 100644 lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/DebugInfo.h delete mode 100644 lld/lib/ReaderWriter/MachO/ExecutableAtoms.h delete mode 100644 lld/lib/ReaderWriter/MachO/File.h delete mode 100644 lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h delete mode 100644 lld/lib/ReaderWriter/MachO/GOTPass.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/LayoutPass.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/LayoutPass.h delete mode 100644 lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/MachONormalizedFile.h delete mode 100644 lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h delete mode 100644 lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/MachOPasses.h delete mode 100644 lld/lib/ReaderWriter/MachO/ObjCPass.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/SectCreateFile.h delete mode 100644 lld/lib/ReaderWriter/MachO/ShimPass.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/StubsPass.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/TLVPass.cpp delete mode 100644 lld/lib/ReaderWriter/MachO/WriterMachO.cpp delete mode 100644 lld/lib/ReaderWriter/YAML/CMakeLists.txt delete mode 100644 lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp delete mode 100644 lld/test/darwin/Inputs/native-and-mach-o.objtxt delete mode 100644 lld/test/darwin/Inputs/native-and-mach-o2.objtxt delete mode 100644 lld/test/darwin/cmdline-lto_library.objtxt delete mode 100644 lld/test/darwin/cmdline-objc_gc.objtxt delete mode 100644 lld/test/darwin/cmdline-objc_gc_compaction.objtxt delete mode 100644 lld/test/darwin/cmdline-objc_gc_only.objtxt delete mode 100644 lld/test/darwin/native-and-mach-o.objtxt delete mode 100755 lld/test/mach-o/Inputs/DependencyDump.py delete mode 100644 lld/test/mach-o/Inputs/MacOSX.sdk/usr/lib/libSystem.tbd delete mode 100644 lld/test/mach-o/Inputs/PIE.yaml delete mode 100644 lld/test/mach-o/Inputs/arm-interworking.yaml delete mode 100644 lld/test/mach-o/Inputs/arm-shims.yaml delete mode 100644 lld/test/mach-o/Inputs/arm64/libSystem.yaml delete mode 100644 lld/test/mach-o/Inputs/armv7/libSystem.yaml delete mode 100644 lld/test/mach-o/Inputs/bar.yaml delete mode 100644 lld/test/mach-o/Inputs/cstring-sections.yaml delete mode 100644 lld/test/mach-o/Inputs/exported_symbols_list.exp delete mode 100644 lld/test/mach-o/Inputs/full.filelist delete mode 100644 lld/test/mach-o/Inputs/got-order.yaml delete mode 100644 lld/test/mach-o/Inputs/got-order2.yaml delete mode 100644 lld/test/mach-o/Inputs/hello-world-arm64.yaml delete mode 100644 lld/test/mach-o/Inputs/hello-world-armv6.yaml delete mode 100644 lld/test/mach-o/Inputs/hello-world-armv7.yaml delete mode 100644 lld/test/mach-o/Inputs/hello-world-x86.yaml delete mode 100644 lld/test/mach-o/Inputs/hello-world-x86_64.yaml delete mode 100644 lld/test/mach-o/Inputs/hw.raw_bytes delete mode 100644 lld/test/mach-o/Inputs/interposing-section.yaml delete mode 100644 lld/test/mach-o/Inputs/lazy-bind-x86_64-2.yaml delete mode 100644 lld/test/mach-o/Inputs/lazy-bind-x86_64-3.yaml delete mode 100644 lld/test/mach-o/Inputs/lazy-bind-x86_64.yaml delete mode 100755 lld/test/mach-o/Inputs/lib-search-paths/usr/lib/libmyshared.dylib delete mode 100644 lld/test/mach-o/Inputs/lib-search-paths/usr/lib/libmystatic.a delete mode 100644 lld/test/mach-o/Inputs/lib-search-paths/usr/local/lib/file.o delete mode 100644 lld/test/mach-o/Inputs/libbar.a delete mode 100644 lld/test/mach-o/Inputs/libfoo.a delete mode 100644 lld/test/mach-o/Inputs/no-version-min-load-command-object.yaml delete mode 100644 lld/test/mach-o/Inputs/order_file-basic.order delete mode 100644 lld/test/mach-o/Inputs/partial.filelist delete mode 100644 lld/test/mach-o/Inputs/re-exported-dylib-ordinal.yaml delete mode 100644 lld/test/mach-o/Inputs/re-exported-dylib-ordinal2.yaml delete mode 100644 lld/test/mach-o/Inputs/re-exported-dylib-ordinal3.yaml delete mode 100644 lld/test/mach-o/Inputs/swift-version-1.yaml delete mode 100644 lld/test/mach-o/Inputs/unwind-info-simple-arm64.yaml delete mode 100644 lld/test/mach-o/Inputs/use-dylib-install-names.yaml delete mode 100644 lld/test/mach-o/Inputs/use-simple-dylib.yaml delete mode 100644 lld/test/mach-o/Inputs/write-final-sections.yaml delete mode 100644 lld/test/mach-o/Inputs/wrong-arch-error.yaml delete mode 100644 lld/test/mach-o/Inputs/x86/libSystem.yaml delete mode 100644 lld/test/mach-o/Inputs/x86_64/libSystem.yaml delete mode 100644 lld/test/mach-o/PIE.yaml delete mode 100644 lld/test/mach-o/align_text.yaml delete mode 100644 lld/test/mach-o/arm-interworking-movw.yaml delete mode 100644 lld/test/mach-o/arm-interworking.yaml delete mode 100644 lld/test/mach-o/arm-shims.yaml delete mode 100644 lld/test/mach-o/arm-subsections-via-symbols.yaml delete mode 100644 lld/test/mach-o/arm64-reloc-negDelta32-fixup.yaml delete mode 100644 lld/test/mach-o/arm64-relocs-errors-delta64-offset.yaml delete mode 100644 lld/test/mach-o/arm64-section-order.yaml delete mode 100644 lld/test/mach-o/bind-opcodes.yaml delete mode 100644 lld/test/mach-o/cstring-sections.yaml delete mode 100644 lld/test/mach-o/data-in-code-load-command.yaml delete mode 100644 lld/test/mach-o/data-only-dylib.yaml delete mode 100644 lld/test/mach-o/dead-strip-globals.yaml delete mode 100644 lld/test/mach-o/debug-syms.yaml delete mode 100644 lld/test/mach-o/demangle.yaml delete mode 100644 lld/test/mach-o/dependency_info.yaml delete mode 100644 lld/test/mach-o/do-not-emit-unwind-fde-arm64.yaml delete mode 100644 lld/test/mach-o/dso_handle.yaml delete mode 100644 lld/test/mach-o/dylib-install-names.yaml delete mode 100644 lld/test/mach-o/eh-frame-relocs-arm64.yaml delete mode 100644 lld/test/mach-o/empty-sections.yaml delete mode 100644 lld/test/mach-o/error-simulator-vs-macosx.yaml delete mode 100644 lld/test/mach-o/exe-offsets.yaml delete mode 100644 lld/test/mach-o/exe-segment-overlap.yaml delete mode 100644 lld/test/mach-o/executable-exports.yaml delete mode 100644 lld/test/mach-o/export-trie-order.yaml delete mode 100644 lld/test/mach-o/exported_symbols_list-dylib.yaml delete mode 100644 lld/test/mach-o/exported_symbols_list-obj.yaml delete mode 100644 lld/test/mach-o/exported_symbols_list-undef.yaml delete mode 100644 lld/test/mach-o/fat-archive.yaml delete mode 100644 lld/test/mach-o/filelist.yaml delete mode 100644 lld/test/mach-o/flat_namespace_undef_error.yaml delete mode 100644 lld/test/mach-o/flat_namespace_undef_suppress.yaml delete mode 100644 lld/test/mach-o/force_load-dylib.yaml delete mode 100644 lld/test/mach-o/force_load-x86_64.yaml delete mode 100644 lld/test/mach-o/framework-user-paths.yaml delete mode 100644 lld/test/mach-o/function-starts-load-command.yaml delete mode 100644 lld/test/mach-o/gcc_except_tab-got-arm64.yaml delete mode 100644 lld/test/mach-o/got-order.yaml delete mode 100644 lld/test/mach-o/hello-world-arm64.yaml delete mode 100644 lld/test/mach-o/hello-world-armv6.yaml delete mode 100644 lld/test/mach-o/hello-world-armv7.yaml delete mode 100644 lld/test/mach-o/hello-world-x86.yaml delete mode 100644 lld/test/mach-o/hello-world-x86_64.yaml delete mode 100644 lld/test/mach-o/image-base.yaml delete mode 100644 lld/test/mach-o/infer-arch.yaml delete mode 100644 lld/test/mach-o/interposing-section.yaml delete mode 100644 lld/test/mach-o/keep_private_externs.yaml delete mode 100644 lld/test/mach-o/lazy-bind-x86_64.yaml delete mode 100644 lld/test/mach-o/lc_segment_filesize.yaml delete mode 100644 lld/test/mach-o/lib-search-paths.yaml delete mode 100644 lld/test/mach-o/library-order.yaml delete mode 100644 lld/test/mach-o/library-rescan.yaml delete mode 100644 lld/test/mach-o/libresolve-bizarre-root-override.yaml delete mode 100644 lld/test/mach-o/libresolve-multiple-syslibroots.yaml delete mode 100644 lld/test/mach-o/libresolve-one-syslibroot.yaml delete mode 100644 lld/test/mach-o/libresolve-simple.yaml delete mode 100644 lld/test/mach-o/libresolve-user-paths.yaml delete mode 100644 lld/test/mach-o/libresolve-z.yaml delete mode 100644 lld/test/mach-o/lit.local.cfg delete mode 100644 lld/test/mach-o/load-commands-size.yaml delete mode 100644 lld/test/mach-o/mach_header-cpusubtype.yaml delete mode 100644 lld/test/mach-o/mh_bundle_header.yaml delete mode 100644 lld/test/mach-o/mh_dylib_header.yaml delete mode 100644 lld/test/mach-o/objc-category-list-atom.yaml delete mode 100644 lld/test/mach-o/objc-image-info-host-vs-simulator.yaml delete mode 100644 lld/test/mach-o/objc-image-info-invalid-size.yaml delete mode 100644 lld/test/mach-o/objc-image-info-invalid-version.yaml delete mode 100644 lld/test/mach-o/objc-image-info-mismatched-swift-version.yaml delete mode 100644 lld/test/mach-o/objc-image-info-pass-output.yaml delete mode 100644 lld/test/mach-o/objc-image-info-simulator-vs-host.yaml delete mode 100644 lld/test/mach-o/objc-image-info-unsupported-gc.yaml delete mode 100644 lld/test/mach-o/objc_export_list.yaml delete mode 100644 lld/test/mach-o/order_file-basic.yaml delete mode 100644 lld/test/mach-o/parse-aliases.yaml delete mode 100644 lld/test/mach-o/parse-arm-relocs.yaml delete mode 100644 lld/test/mach-o/parse-cfstring32.yaml delete mode 100644 lld/test/mach-o/parse-cfstring64.yaml delete mode 100644 lld/test/mach-o/parse-compact-unwind32.yaml delete mode 100644 lld/test/mach-o/parse-compact-unwind64.yaml delete mode 100644 lld/test/mach-o/parse-data-in-code-armv7.yaml delete mode 100644 lld/test/mach-o/parse-data-in-code-x86.yaml delete mode 100644 lld/test/mach-o/parse-data-relocs-arm64.yaml delete mode 100644 lld/test/mach-o/parse-data-relocs-x86_64.yaml delete mode 100644 lld/test/mach-o/parse-data.yaml delete mode 100644 lld/test/mach-o/parse-eh-frame-relocs-x86_64.yaml delete mode 100644 lld/test/mach-o/parse-eh-frame-x86-anon.yaml delete mode 100644 lld/test/mach-o/parse-eh-frame-x86-labeled.yaml delete mode 100644 lld/test/mach-o/parse-eh-frame.yaml delete mode 100644 lld/test/mach-o/parse-function.yaml delete mode 100644 lld/test/mach-o/parse-initializers32.yaml delete mode 100644 lld/test/mach-o/parse-initializers64.yaml delete mode 100644 lld/test/mach-o/parse-literals-error.yaml delete mode 100644 lld/test/mach-o/parse-literals.yaml delete mode 100644 lld/test/mach-o/parse-non-lazy-pointers.yaml delete mode 100644 lld/test/mach-o/parse-relocs-x86.yaml delete mode 100644 lld/test/mach-o/parse-section-no-symbol.yaml delete mode 100644 lld/test/mach-o/parse-tentative-defs.yaml delete mode 100644 lld/test/mach-o/parse-text-relocs-arm64.yaml delete mode 100644 lld/test/mach-o/parse-text-relocs-x86_64.yaml delete mode 100644 lld/test/mach-o/parse-tlv-relocs-x86-64.yaml delete mode 100644 lld/test/mach-o/re-exported-dylib-ordinal.yaml delete mode 100644 lld/test/mach-o/rpath.yaml delete mode 100644 lld/test/mach-o/run-tlv-pass-x86-64.yaml delete mode 100644 lld/test/mach-o/sdk-version-error.yaml delete mode 100644 lld/test/mach-o/sectalign.yaml delete mode 100644 lld/test/mach-o/sectattrs.yaml delete mode 100644 lld/test/mach-o/sectcreate.yaml delete mode 100644 lld/test/mach-o/seg-protection-arm64.yaml delete mode 100644 lld/test/mach-o/seg-protection-x86_64.yaml delete mode 100644 lld/test/mach-o/source-version.yaml delete mode 100644 lld/test/mach-o/stack-size.yaml delete mode 100644 lld/test/mach-o/string-table.yaml delete mode 100644 lld/test/mach-o/stub-link.s delete mode 100644 lld/test/mach-o/subsections-via-symbols-default.yaml delete mode 100644 lld/test/mach-o/twolevel_namespace_undef_dynamic_lookup.yaml delete mode 100644 lld/test/mach-o/twolevel_namespace_undef_warning_suppress.yaml delete mode 100644 lld/test/mach-o/unwind-info-simple-arm64.yaml delete mode 100644 lld/test/mach-o/unwind-info-simple-x86_64.yaml delete mode 100644 lld/test/mach-o/upward-dylib-load-command.yaml delete mode 100644 lld/test/mach-o/upward-dylib-paths.yaml delete mode 100644 lld/test/mach-o/usage.yaml delete mode 100644 lld/test/mach-o/use-dylib.yaml delete mode 100644 lld/test/mach-o/use-simple-dylib.yaml delete mode 100644 lld/test/mach-o/version-min-load-command-object.yaml delete mode 100644 lld/test/mach-o/version-min-load-command.yaml delete mode 100644 lld/test/mach-o/write-final-sections.yaml delete mode 100644 lld/test/mach-o/wrong-arch-error.yaml delete mode 100644 lld/unittests/CMakeLists.txt delete mode 100644 lld/unittests/DriverTests/CMakeLists.txt delete mode 100644 lld/unittests/DriverTests/DarwinLdDriverTest.cpp delete mode 100644 lld/unittests/MachOTests/CMakeLists.txt delete mode 100644 lld/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp delete mode 100644 lld/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp delete mode 100644 lld/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp delete mode 100644 lld/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp delete mode 100644 lld/unittests/MachOTests/empty_obj_x86_armv7.txt diff --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt index 2e99564f4e3e9..a4c7dc391c63a 100644 --- a/lld/CMakeLists.txt +++ b/lld/CMakeLists.txt @@ -195,12 +195,10 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) endif() add_subdirectory(Common) -add_subdirectory(lib) add_subdirectory(tools/lld) if (LLVM_INCLUDE_TESTS) add_subdirectory(test) - add_subdirectory(unittests) endif() add_subdirectory(docs) diff --git a/lld/include/lld/Common/Driver.h b/lld/include/lld/Common/Driver.h index eb5bc7b82b9ba..0e505a16463e7 100644 --- a/lld/include/lld/Common/Driver.h +++ b/lld/include/lld/Common/Driver.h @@ -42,11 +42,6 @@ bool link(llvm::ArrayRef args, bool canExitEarly, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS); } -namespace mach_o { -bool link(llvm::ArrayRef args, bool canExitEarly, - llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS); -} - namespace macho { bool link(llvm::ArrayRef args, bool canExitEarly, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS); diff --git a/lld/include/lld/Core/Reference.h b/lld/include/lld/Core/Reference.h index b104f84954747..7a6c36aecfc59 100644 --- a/lld/include/lld/Core/Reference.h +++ b/lld/include/lld/Core/Reference.h @@ -42,9 +42,8 @@ class Reference { public: /// Which universe defines the kindValue(). enum class KindNamespace { - all = 0, + all = 0, testing = 1, - mach_o = 2, }; KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; } diff --git a/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/lld/include/lld/ReaderWriter/MachOLinkingContext.h deleted file mode 100644 index 974f323bc612c..0000000000000 --- a/lld/include/lld/ReaderWriter/MachOLinkingContext.h +++ /dev/null @@ -1,505 +0,0 @@ -//===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H -#define LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H - -#include "lld/Core/LinkingContext.h" -#include "lld/Core/Reader.h" -#include "lld/Core/Writer.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/BinaryFormat/MachO.h" -#include "llvm/Support/ErrorHandling.h" -#include - -using llvm::MachO::HeaderFileType; - -namespace lld { - -namespace mach_o { -class ArchHandler; -class MachODylibFile; -class MachOFile; -class SectCreateFile; -} - -class MachOLinkingContext : public LinkingContext { -public: - MachOLinkingContext(); - ~MachOLinkingContext() override; - - enum Arch { - arch_unknown, - arch_ppc, - arch_x86, - arch_x86_64, - arch_armv6, - arch_armv7, - arch_armv7s, - arch_arm64, - }; - - enum class OS { - unknown, - macOSX, - iOS, - iOS_simulator - }; - - enum class ExportMode { - globals, // Default, all global symbols exported. - exported, // -exported_symbol[s_list], only listed symbols exported. - unexported // -unexported_symbol[s_list], no listed symbol exported. - }; - - enum class DebugInfoMode { - addDebugMap, // Default - noDebugMap // -S option - }; - - enum class UndefinedMode { - error, - warning, - suppress, - dynamicLookup - }; - - enum ObjCConstraint { - objc_unknown = 0, - objc_supports_gc = 2, - objc_gc_only = 4, - // Image optimized by dyld = 8 - // GC compaction = 16 - objc_retainReleaseForSimulator = 32, - objc_retainRelease - }; - - /// Initializes the context to sane default values given the specified output - /// file type, arch, os, and minimum os version. This should be called before - /// other setXXX() methods. - void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion, - bool exportDynamicSymbols); - - void addPasses(PassManager &pm) override; - bool validateImpl() override; - std::string demangle(StringRef symbolName) const override; - - void createImplicitFiles(std::vector> &) override; - - /// Creates a new file which is owned by the context. Returns a pointer to - /// the new file. - template - typename std::enable_if::value, T *>::type - make_file(Args &&... args) const { - auto file = std::unique_ptr(new T(std::forward(args)...)); - auto *filePtr = file.get(); - auto *ctx = const_cast(this); - ctx->getNodes().push_back(std::make_unique(std::move(file))); - return filePtr; - } - - uint32_t getCPUType() const; - uint32_t getCPUSubType() const; - - bool addEntryPointLoadCommand() const; - bool addUnixThreadLoadCommand() const; - bool outputTypeHasEntry() const; - bool is64Bit() const; - - virtual uint64_t pageZeroSize() const { return _pageZeroSize; } - virtual uint64_t pageSize() const { return _pageSize; } - - mach_o::ArchHandler &archHandler() const; - - HeaderFileType outputMachOType() const { return _outputMachOType; } - - Arch arch() const { return _arch; } - StringRef archName() const { return nameFromArch(_arch); } - OS os() const { return _os; } - - ExportMode exportMode() const { return _exportMode; } - void setExportMode(ExportMode mode) { _exportMode = mode; } - void addExportSymbol(StringRef sym); - bool exportRestrictMode() const { return _exportMode != ExportMode::globals; } - bool exportSymbolNamed(StringRef sym) const; - - DebugInfoMode debugInfoMode() const { return _debugInfoMode; } - void setDebugInfoMode(DebugInfoMode mode) { - _debugInfoMode = mode; - } - - void appendOrderedSymbol(StringRef symbol, StringRef filename); - - bool keepPrivateExterns() const { return _keepPrivateExterns; } - void setKeepPrivateExterns(bool v) { _keepPrivateExterns = v; } - bool demangleSymbols() const { return _demangle; } - void setDemangleSymbols(bool d) { _demangle = d; } - bool mergeObjCCategories() const { return _mergeObjCCategories; } - void setMergeObjCCategories(bool v) { _mergeObjCCategories = v; } - /// Create file at specified path which will contain a binary encoding - /// of all input and output file paths. - std::error_code createDependencyFile(StringRef path); - void addInputFileDependency(StringRef path) const; - void addInputFileNotFound(StringRef path) const; - void addOutputFileDependency(StringRef path) const; - - bool minOS(StringRef mac, StringRef iOS) const; - void setDoNothing(bool value) { _doNothing = value; } - bool doNothing() const { return _doNothing; } - bool printAtoms() const { return _printAtoms; } - bool testingFileUsage() const { return _testingFileUsage; } - const StringRefVector &searchDirs() const { return _searchDirs; } - const StringRefVector &frameworkDirs() const { return _frameworkDirs; } - void setSysLibRoots(const StringRefVector &paths); - const StringRefVector &sysLibRoots() const { return _syslibRoots; } - bool PIE() const { return _pie; } - void setPIE(bool pie) { _pie = pie; } - bool generateVersionLoadCommand() const { - return _generateVersionLoadCommand; - } - void setGenerateVersionLoadCommand(bool v) { - _generateVersionLoadCommand = v; - } - - bool generateFunctionStartsLoadCommand() const { - return _generateFunctionStartsLoadCommand; - } - void setGenerateFunctionStartsLoadCommand(bool v) { - _generateFunctionStartsLoadCommand = v; - } - - bool generateDataInCodeLoadCommand() const { - return _generateDataInCodeLoadCommand; - } - void setGenerateDataInCodeLoadCommand(bool v) { - _generateDataInCodeLoadCommand = v; - } - - uint64_t stackSize() const { return _stackSize; } - void setStackSize(uint64_t stackSize) { _stackSize = stackSize; } - - uint64_t baseAddress() const { return _baseAddress; } - void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; } - - ObjCConstraint objcConstraint() const { return _objcConstraint; } - - uint32_t osMinVersion() const { return _osMinVersion; } - - uint32_t sdkVersion() const { return _sdkVersion; } - void setSdkVersion(uint64_t v) { _sdkVersion = v; } - - uint64_t sourceVersion() const { return _sourceVersion; } - void setSourceVersion(uint64_t v) { _sourceVersion = v; } - - uint32_t swiftVersion() const { return _swiftVersion; } - - /// Checks whether a given path on the filesystem exists. - /// - /// When running in -test_file_usage mode, this method consults an - /// internally maintained list of files that exist (provided by -path_exists) - /// instead of the actual filesystem. - bool pathExists(StringRef path) const; - - /// Like pathExists() but only used on files - not directories. - bool fileExists(StringRef path) const; - - /// Adds any library search paths derived from the given base, possibly - /// modified by -syslibroots. - /// - /// The set of paths added consists of approximately all syslibroot-prepended - /// versions of libPath that exist, or the original libPath if there are none - /// for whatever reason. With various edge-cases for compatibility. - void addModifiedSearchDir(StringRef libPath, bool isSystemPath = false); - - /// Determine whether -lFoo can be resolve within the given path, and - /// return the filename if so. - /// - /// The -lFoo option is documented to search for libFoo.dylib and libFoo.a in - /// that order, unless Foo ends in ".o", in which case only the exact file - /// matches (e.g. -lfoo.o would only find foo.o). - llvm::Optional searchDirForLibrary(StringRef path, - StringRef libName) const; - - /// Iterates through all search path entries looking for libName (as - /// specified by -lFoo). - llvm::Optional searchLibrary(StringRef libName) const; - - /// Add a framework search path. Internally, this method may be prepended - /// the path with syslibroot. - void addFrameworkSearchDir(StringRef fwPath, bool isSystemPath = false); - - /// Iterates through all framework directories looking for - /// Foo.framework/Foo (when fwName = "Foo"). - llvm::Optional findPathForFramework(StringRef fwName) const; - - /// The dylib's binary compatibility version, in the raw uint32 format. - /// - /// When building a dynamic library, this is the compatibility version that - /// gets embedded into the result. Other Mach-O binaries that link against - /// this library will store the compatibility version in its load command. At - /// runtime, the loader will verify that the binary is compatible with the - /// installed dynamic library. - uint32_t compatibilityVersion() const { return _compatibilityVersion; } - - /// The dylib's current version, in the raw uint32 format. - /// - /// When building a dynamic library, this is the current version that gets - /// embedded into the result. Other Mach-O binaries that link against - /// this library will store the compatibility version in its load command. - uint32_t currentVersion() const { return _currentVersion; } - - /// The dylib's install name. - /// - /// Binaries that link against the dylib will embed this path into the dylib - /// load command. When loading the binaries at runtime, this is the location - /// on disk that the loader will look for the dylib. - StringRef installName() const { return _installName; } - - /// Whether or not the dylib has side effects during initialization. - /// - /// Dylibs marked as being dead strippable provide the guarantee that loading - /// the dylib has no side effects, allowing the linker to strip out the dylib - /// when linking a binary that does not use any of its symbols. - bool deadStrippableDylib() const { return _deadStrippableDylib; } - - /// Whether or not to use flat namespace. - /// - /// MachO usually uses a two-level namespace, where each external symbol - /// referenced by the target is associated with the dylib that will provide - /// the symbol's definition at runtime. Using flat namespace overrides this - /// behavior: the linker searches all dylibs on the command line and all - /// dylibs those original dylibs depend on, but does not record which dylib - /// an external symbol came from. At runtime dyld again searches all images - /// and uses the first definition it finds. In addition, any undefines in - /// loaded flat_namespace dylibs must be resolvable at build time. - bool useFlatNamespace() const { return _flatNamespace; } - - /// How to handle undefined symbols. - /// - /// Options are: - /// * error: Report an error and terminate linking. - /// * warning: Report a warning, but continue linking. - /// * suppress: Ignore and continue linking. - /// * dynamic_lookup: For use with -twolevel namespace: Records source dylibs - /// for symbols that are defined in a linked dylib at static link time. - /// Undefined symbols are handled by searching all loaded images at - /// runtime. - UndefinedMode undefinedMode() const { return _undefinedMode; } - - /// The path to the executable that will load the bundle at runtime. - /// - /// When building a Mach-O bundle, this executable will be examined if there - /// are undefined symbols after the main link phase. It is expected that this - /// binary will be loading the bundle at runtime and will provide the symbols - /// at that point. - StringRef bundleLoader() const { return _bundleLoader; } - - void setCompatibilityVersion(uint32_t vers) { _compatibilityVersion = vers; } - void setCurrentVersion(uint32_t vers) { _currentVersion = vers; } - void setInstallName(StringRef name) { _installName = name; } - void setDeadStrippableDylib(bool deadStrippable) { - _deadStrippableDylib = deadStrippable; - } - void setUseFlatNamespace(bool flatNamespace) { - _flatNamespace = flatNamespace; - } - - void setUndefinedMode(UndefinedMode undefinedMode) { - _undefinedMode = undefinedMode; - } - - void setBundleLoader(StringRef loader) { _bundleLoader = loader; } - void setPrintAtoms(bool value=true) { _printAtoms = value; } - void setTestingFileUsage(bool value = true) { - _testingFileUsage = value; - } - void addExistingPathForDebug(StringRef path) { - _existingPaths.insert(path); - } - - void addRpath(StringRef rpath); - const StringRefVector &rpaths() const { return _rpaths; } - - /// Add section alignment constraint on final layout. - void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align); - - /// Add a section based on a command-line sectcreate option. - void addSectCreateSection(StringRef seg, StringRef sect, - std::unique_ptr content); - - /// Returns true if specified section had alignment constraints. - bool sectionAligned(StringRef seg, StringRef sect, uint16_t &align) const; - - StringRef dyldPath() const { return "/usr/lib/dyld"; } - - /// Stub creation Pass should be run. - bool needsStubsPass() const; - - // GOT creation Pass should be run. - bool needsGOTPass() const; - - /// Pass to add TLV sections. - bool needsTLVPass() const; - - /// Pass to transform __compact_unwind into __unwind_info should be run. - bool needsCompactUnwindPass() const; - - /// Pass to add shims switching between thumb and arm mode. - bool needsShimPass() const; - - /// Pass to add objc image info and optimized objc data. - bool needsObjCPass() const; - - /// Magic symbol name stubs will need to help lazy bind. - StringRef binderSymbolName() const; - - /// Used to keep track of direct and indirect dylibs. - void registerDylib(mach_o::MachODylibFile *dylib, bool upward) const; - - // Reads a file from disk to memory. Returns only a needed chunk - // if a fat binary. - ErrorOr> getMemoryBuffer(StringRef path); - - /// Used to find indirect dylibs. Instantiates a MachODylibFile if one - /// has not already been made for the requested dylib. Uses -L and -F - /// search paths to allow indirect dylibs to be overridden. - mach_o::MachODylibFile* findIndirectDylib(StringRef path); - - uint32_t dylibCurrentVersion(StringRef installName) const; - - uint32_t dylibCompatVersion(StringRef installName) const; - - ArrayRef allDylibs() const { - return _allDylibs; - } - - /// Creates a copy (owned by this MachOLinkingContext) of a string. - StringRef copy(StringRef str) { return str.copy(_allocator); } - - /// If the memoryBuffer is a fat file with a slice for the current arch, - /// this method will return the offset and size of that slice. - bool sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset, uint32_t &size); - - /// Returns if a command line option specified dylib is an upward link. - bool isUpwardDylib(StringRef installName) const; - - static bool isThinObjectFile(StringRef path, Arch &arch); - static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype); - static Arch archFromName(StringRef archName); - static StringRef nameFromArch(Arch arch); - static uint32_t cpuTypeFromArch(Arch arch); - static uint32_t cpuSubtypeFromArch(Arch arch); - static bool is64Bit(Arch arch); - static bool isHostEndian(Arch arch); - static bool isBigEndian(Arch arch); - - /// Construct 32-bit value from string "X.Y.Z" where - /// bits are xxxx.yy.zz. Largest number is 65535.255.255 - static bool parsePackedVersion(StringRef str, uint32_t &result); - - /// Construct 64-bit value from string "A.B.C.D.E" where - /// bits are aaaa.bb.cc.dd.ee. Largest number is 16777215.1023.1023.1023.1023 - static bool parsePackedVersion(StringRef str, uint64_t &result); - - void finalizeInputFiles() override; - - llvm::Error handleLoadedFile(File &file) override; - - bool customAtomOrderer(const DefinedAtom *left, const DefinedAtom *right, - bool &leftBeforeRight) const; - - /// Return the 'flat namespace' file. This is the file that supplies - /// atoms for otherwise undefined symbols when the -flat_namespace or - /// -undefined dynamic_lookup options are used. - File* flatNamespaceFile() const { return _flatNamespaceFile; } - -private: - Writer &writer() const override; - mach_o::MachODylibFile* loadIndirectDylib(StringRef path); - struct ArchInfo { - StringRef archName; - MachOLinkingContext::Arch arch; - bool littleEndian; - uint32_t cputype; - uint32_t cpusubtype; - }; - - struct SectionAlign { - StringRef segmentName; - StringRef sectionName; - uint16_t align; - }; - - struct OrderFileNode { - StringRef fileFilter; - unsigned order; - }; - - static bool findOrderOrdinal(const std::vector &nodes, - const DefinedAtom *atom, unsigned &ordinal); - - static ArchInfo _s_archInfos[]; - - std::set _existingPaths; // For testing only. - StringRefVector _searchDirs; - StringRefVector _syslibRoots; - StringRefVector _frameworkDirs; - HeaderFileType _outputMachOType = llvm::MachO::MH_EXECUTE; - bool _outputMachOTypeStatic = false; // Disambiguate static vs dynamic prog - bool _doNothing = false; // for -help and -v which just print info - bool _pie = false; - Arch _arch = arch_unknown; - OS _os = OS::macOSX; - uint32_t _osMinVersion = 0; - uint32_t _sdkVersion = 0; - uint64_t _sourceVersion = 0; - uint64_t _pageZeroSize = 0; - uint64_t _pageSize = 4096; - uint64_t _baseAddress = 0; - uint64_t _stackSize = 0; - uint32_t _compatibilityVersion = 0; - uint32_t _currentVersion = 0; - ObjCConstraint _objcConstraint = objc_unknown; - uint32_t _swiftVersion = 0; - StringRef _installName; - StringRefVector _rpaths; - bool _flatNamespace = false; - UndefinedMode _undefinedMode = UndefinedMode::error; - bool _deadStrippableDylib = false; - bool _printAtoms = false; - bool _testingFileUsage = false; - bool _keepPrivateExterns = false; - bool _demangle = false; - bool _mergeObjCCategories = true; - bool _generateVersionLoadCommand = false; - bool _generateFunctionStartsLoadCommand = false; - bool _generateDataInCodeLoadCommand = false; - StringRef _bundleLoader; - mutable std::unique_ptr _archHandler; - mutable std::unique_ptr _writer; - std::vector _sectAligns; - mutable llvm::StringMap _pathToDylibMap; - mutable std::vector _allDylibs; - mutable std::set _upwardDylibs; - mutable std::vector> _indirectDylibs; - mutable std::mutex _dylibsMutex; - ExportMode _exportMode = ExportMode::globals; - llvm::StringSet<> _exportedSymbols; - DebugInfoMode _debugInfoMode = DebugInfoMode::addDebugMap; - std::unique_ptr _dependencyInfo; - llvm::StringMap> _orderFiles; - unsigned _orderFileEntries = 0; - File *_flatNamespaceFile = nullptr; - mach_o::SectCreateFile *_sectCreateFile = nullptr; -}; - -} // end namespace lld - -#endif // LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H diff --git a/lld/include/lld/ReaderWriter/YamlContext.h b/lld/include/lld/ReaderWriter/YamlContext.h deleted file mode 100644 index dc133e3627de3..0000000000000 --- a/lld/include/lld/ReaderWriter/YamlContext.h +++ /dev/null @@ -1,42 +0,0 @@ -//===- lld/ReaderWriter/YamlContext.h - object used in YAML I/O context ---===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLD_READER_WRITER_YAML_CONTEXT_H -#define LLD_READER_WRITER_YAML_CONTEXT_H - -#include "lld/Common/LLVM.h" -#include -#include -#include - -namespace lld { -class File; -class LinkingContext; -class Registry; -namespace mach_o { -namespace normalized { -struct NormalizedFile; -} -} - -using lld::mach_o::normalized::NormalizedFile; - -/// When YAML I/O is used in lld, the yaml context always holds a YamlContext -/// object. We need to support hetergenous yaml documents which each require -/// different context info. This struct supports all clients. -struct YamlContext { - const LinkingContext *_ctx = nullptr; - const Registry *_registry = nullptr; - File *_file = nullptr; - NormalizedFile *_normalizeMachOFile = nullptr; - StringRef _path; -}; - -} // end namespace lld - -#endif // LLD_READER_WRITER_YAML_CONTEXT_H diff --git a/lld/lib/CMakeLists.txt b/lld/lib/CMakeLists.txt deleted file mode 100644 index 8884efcfe9ba9..0000000000000 --- a/lld/lib/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_subdirectory(Core) -add_subdirectory(Driver) -add_subdirectory(ReaderWriter) diff --git a/lld/lib/Core/CMakeLists.txt b/lld/lib/Core/CMakeLists.txt deleted file mode 100644 index d5e507536b720..0000000000000 --- a/lld/lib/Core/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -add_lld_library(lldCore - DefinedAtom.cpp - Error.cpp - File.cpp - LinkingContext.cpp - Reader.cpp - Resolver.cpp - SymbolTable.cpp - Writer.cpp - - ADDITIONAL_HEADER_DIRS - ${LLD_INCLUDE_DIR}/lld/Core - - LINK_COMPONENTS - BinaryFormat - MC - Support - - LINK_LIBS - ${LLVM_PTHREAD_LIB} - - DEPENDS - intrinsics_gen - ) diff --git a/lld/lib/Core/DefinedAtom.cpp b/lld/lib/Core/DefinedAtom.cpp deleted file mode 100644 index 3c1eece16841d..0000000000000 --- a/lld/lib/Core/DefinedAtom.cpp +++ /dev/null @@ -1,81 +0,0 @@ -//===- DefinedAtom.cpp ------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/ErrorHandling.h" -#include "lld/Core/DefinedAtom.h" -#include "lld/Core/File.h" - -namespace lld { - -DefinedAtom::ContentPermissions DefinedAtom::permissions() const { - // By default base permissions on content type. - return permissions(this->contentType()); -} - -// Utility function for deriving permissions from content type -DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) { - switch (type) { - case typeCode: - case typeResolver: - case typeBranchIsland: - case typeBranchShim: - case typeStub: - case typeStubHelper: - case typeMachHeader: - return permR_X; - - case typeConstant: - case typeCString: - case typeUTF16String: - case typeCFI: - case typeLSDA: - case typeLiteral4: - case typeLiteral8: - case typeLiteral16: - case typeDTraceDOF: - case typeCompactUnwindInfo: - case typeProcessedUnwindInfo: - case typeObjCImageInfo: - case typeObjCMethodList: - return permR__; - - case typeData: - case typeDataFast: - case typeZeroFill: - case typeZeroFillFast: - case typeObjC1Class: - case typeLazyPointer: - case typeLazyDylibPointer: - case typeNonLazyPointer: - case typeThunkTLV: - return permRW_; - - case typeGOT: - case typeConstData: - case typeCFString: - case typeInitializerPtr: - case typeTerminatorPtr: - case typeCStringPtr: - case typeObjCClassPtr: - case typeObjC2CategoryList: - case typeInterposingTuples: - case typeTLVInitialData: - case typeTLVInitialZeroFill: - case typeTLVInitializerPtr: - return permRW_L; - - case typeUnknown: - case typeTempLTO: - case typeSectCreate: - case typeDSOHandle: - return permUnknown; - } - llvm_unreachable("unknown content type"); -} - -} // namespace diff --git a/lld/lib/Core/Error.cpp b/lld/lib/Core/Error.cpp deleted file mode 100644 index a4f4b1b8af484..0000000000000 --- a/lld/lib/Core/Error.cpp +++ /dev/null @@ -1,93 +0,0 @@ -//===- Error.cpp - system_error extensions for lld --------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/Error.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/ErrorHandling.h" -#include -#include -#include - -using namespace lld; - -namespace { -class _YamlReaderErrorCategory : public std::error_category { -public: - const char* name() const noexcept override { - return "lld.yaml.reader"; - } - - std::string message(int ev) const override { - switch (static_cast(ev)) { - case YamlReaderError::unknown_keyword: - return "Unknown keyword found in yaml file"; - case YamlReaderError::illegal_value: - return "Bad value found in yaml file"; - } - llvm_unreachable("An enumerator of YamlReaderError does not have a " - "message defined."); - } -}; -} // end anonymous namespace - -const std::error_category &lld::YamlReaderCategory() { - static _YamlReaderErrorCategory o; - return o; -} - -namespace lld { - -/// Temporary class to enable make_dynamic_error_code() until -/// llvm::ErrorOr<> is updated to work with error encapsulations -/// other than error_code. -class dynamic_error_category : public std::error_category { -public: - ~dynamic_error_category() override = default; - - const char *name() const noexcept override { - return "lld.dynamic_error"; - } - - std::string message(int ev) const override { - assert(ev >= 0); - assert(ev < (int)_messages.size()); - // The value is an index into the string vector. - return _messages[ev]; - } - - int add(std::string msg) { - std::lock_guard lock(_mutex); - // Value zero is always the success value. - if (_messages.empty()) - _messages.push_back("Success"); - _messages.push_back(msg); - // Return the index of the string just appended. - return _messages.size() - 1; - } - -private: - std::vector _messages; - std::recursive_mutex _mutex; -}; - -static dynamic_error_category categorySingleton; - -std::error_code make_dynamic_error_code(StringRef msg) { - return std::error_code(categorySingleton.add(std::string(msg)), - categorySingleton); -} - -char GenericError::ID = 0; - -GenericError::GenericError(Twine Msg) : Msg(Msg.str()) { } - -void GenericError::log(raw_ostream &OS) const { - OS << Msg; -} - -} // namespace lld diff --git a/lld/lib/Core/File.cpp b/lld/lib/Core/File.cpp deleted file mode 100644 index ce33923c136eb..0000000000000 --- a/lld/lib/Core/File.cpp +++ /dev/null @@ -1,28 +0,0 @@ -//===- Core/File.cpp - A Container of Atoms -------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/File.h" -#include - -namespace lld { - -File::~File() = default; - -File::AtomVector File::_noDefinedAtoms; -File::AtomVector File::_noUndefinedAtoms; -File::AtomVector File::_noSharedLibraryAtoms; -File::AtomVector File::_noAbsoluteAtoms; - -std::error_code File::parse() { - std::lock_guard lock(_parseMutex); - if (!_lastError.hasValue()) - _lastError = doParse(); - return _lastError.getValue(); -} - -} // end namespace lld diff --git a/lld/lib/Core/LinkingContext.cpp b/lld/lib/Core/LinkingContext.cpp deleted file mode 100644 index 911ae606678d7..0000000000000 --- a/lld/lib/Core/LinkingContext.cpp +++ /dev/null @@ -1,69 +0,0 @@ -//===- lib/Core/LinkingContext.cpp - Linker Context Object Interface ------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/LinkingContext.h" -#include "lld/Core/File.h" -#include "lld/Core/Node.h" -#include "lld/Core/Simple.h" -#include "lld/Core/Writer.h" -#include - -namespace lld { - -LinkingContext::LinkingContext() = default; - -LinkingContext::~LinkingContext() = default; - -bool LinkingContext::validate() { - return validateImpl(); -} - -llvm::Error LinkingContext::writeFile(const File &linkedFile) const { - return this->writer().writeFile(linkedFile, _outputPath); -} - -std::unique_ptr LinkingContext::createEntrySymbolFile() const { - return createEntrySymbolFile(""); -} - -std::unique_ptr -LinkingContext::createEntrySymbolFile(StringRef filename) const { - if (entrySymbolName().empty()) - return nullptr; - std::unique_ptr entryFile(new SimpleFile(filename, - File::kindEntryObject)); - entryFile->addAtom( - *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName()))); - return std::move(entryFile); -} - -std::unique_ptr LinkingContext::createUndefinedSymbolFile() const { - return createUndefinedSymbolFile(""); -} - -std::unique_ptr -LinkingContext::createUndefinedSymbolFile(StringRef filename) const { - if (_initialUndefinedSymbols.empty()) - return nullptr; - std::unique_ptr undefinedSymFile( - new SimpleFile(filename, File::kindUndefinedSymsObject)); - for (StringRef undefSym : _initialUndefinedSymbols) - undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom( - *undefinedSymFile, undefSym))); - return std::move(undefinedSymFile); -} - -void LinkingContext::createInternalFiles( - std::vector> &result) const { - if (std::unique_ptr file = createEntrySymbolFile()) - result.push_back(std::move(file)); - if (std::unique_ptr file = createUndefinedSymbolFile()) - result.push_back(std::move(file)); -} - -} // end namespace lld diff --git a/lld/lib/Core/Reader.cpp b/lld/lib/Core/Reader.cpp deleted file mode 100644 index 3592d87ce627c..0000000000000 --- a/lld/lib/Core/Reader.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//===- lib/Core/Reader.cpp ------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/Reader.h" -#include "lld/Core/File.h" -#include "lld/Core/Reference.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/BinaryFormat/Magic.h" -#include "llvm/Support/Errc.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include -#include - -using llvm::file_magic; -using llvm::identify_magic; - -namespace lld { - -YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() = default; - -void Registry::add(std::unique_ptr reader) { - _readers.push_back(std::move(reader)); -} - -void Registry::add(std::unique_ptr handler) { - _yamlHandlers.push_back(std::move(handler)); -} - -ErrorOr> -Registry::loadFile(std::unique_ptr mb) const { - // Get file magic. - StringRef content(mb->getBufferStart(), mb->getBufferSize()); - file_magic fileType = identify_magic(content); - - // Ask each registered reader if it can handle this file type or extension. - for (const std::unique_ptr &reader : _readers) { - if (!reader->canParse(fileType, mb->getMemBufferRef())) - continue; - return reader->loadFile(std::move(mb), *this); - } - - // No Reader could parse this file. - return make_error_code(llvm::errc::executable_format_error); -} - -static const Registry::KindStrings kindStrings[] = { - {Reference::kindLayoutAfter, "layout-after"}, - {Reference::kindAssociate, "associate"}, - LLD_KIND_STRING_END}; - -Registry::Registry() { - addKindTable(Reference::KindNamespace::all, Reference::KindArch::all, - kindStrings); -} - -bool Registry::handleTaggedDoc(llvm::yaml::IO &io, - const lld::File *&file) const { - for (const std::unique_ptr &h : _yamlHandlers) - if (h->handledDocTag(io, file)) - return true; - return false; -} - -void Registry::addKindTable(Reference::KindNamespace ns, - Reference::KindArch arch, - const KindStrings array[]) { - KindEntry entry = { ns, arch, array }; - _kindEntries.push_back(entry); -} - -bool Registry::referenceKindFromString(StringRef inputStr, - Reference::KindNamespace &ns, - Reference::KindArch &arch, - Reference::KindValue &value) const { - for (const KindEntry &entry : _kindEntries) { - for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) { - if (!inputStr.equals(pair->name)) - continue; - ns = entry.ns; - arch = entry.arch; - value = pair->value; - return true; - } - } - return false; -} - -bool Registry::referenceKindToString(Reference::KindNamespace ns, - Reference::KindArch arch, - Reference::KindValue value, - StringRef &str) const { - for (const KindEntry &entry : _kindEntries) { - if (entry.ns != ns) - continue; - if (entry.arch != arch) - continue; - for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) { - if (pair->value != value) - continue; - str = pair->name; - return true; - } - } - return false; -} - -} // end namespace lld diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp deleted file mode 100644 index 17a46056f00c1..0000000000000 --- a/lld/lib/Core/Resolver.cpp +++ /dev/null @@ -1,503 +0,0 @@ -//===- Core/Resolver.cpp - Resolves Atom References -----------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/Resolver.h" -#include "lld/Common/LLVM.h" -#include "lld/Core/ArchiveLibraryFile.h" -#include "lld/Core/Atom.h" -#include "lld/Core/File.h" -#include "lld/Core/Instrumentation.h" -#include "lld/Core/LinkingContext.h" -#include "lld/Core/SharedLibraryFile.h" -#include "lld/Core/SymbolTable.h" -#include "lld/Core/UndefinedAtom.h" -#include "llvm/ADT/iterator_range.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include - -namespace lld { - -llvm::Expected Resolver::handleFile(File &file) { - if (auto ec = _ctx.handleLoadedFile(file)) - return std::move(ec); - bool undefAdded = false; - for (auto &atom : file.defined().owning_ptrs()) - doDefinedAtom(std::move(atom)); - for (auto &atom : file.undefined().owning_ptrs()) { - if (doUndefinedAtom(std::move(atom))) - undefAdded = true; - } - for (auto &atom : file.sharedLibrary().owning_ptrs()) - doSharedLibraryAtom(std::move(atom)); - for (auto &atom : file.absolute().owning_ptrs()) - doAbsoluteAtom(std::move(atom)); - return undefAdded; -} - -llvm::Expected Resolver::forEachUndefines(File &file, - UndefCallback callback) { - size_t i = _undefineIndex[&file]; - bool undefAdded = false; - do { - for (; i < _undefines.size(); ++i) { - StringRef undefName = _undefines[i]; - if (undefName.empty()) - continue; - const Atom *atom = _symbolTable.findByName(undefName); - if (!isa(atom) || _symbolTable.isCoalescedAway(atom)) { - // The symbol was resolved by some other file. Cache the result. - _undefines[i] = ""; - continue; - } - auto undefAddedOrError = callback(undefName); - if (auto ec = undefAddedOrError.takeError()) - return std::move(ec); - undefAdded |= undefAddedOrError.get(); - } - } while (i < _undefines.size()); - _undefineIndex[&file] = i; - return undefAdded; -} - -llvm::Expected Resolver::handleArchiveFile(File &file) { - ArchiveLibraryFile *archiveFile = cast(&file); - return forEachUndefines(file, - [&](StringRef undefName) -> llvm::Expected { - if (File *member = archiveFile->find(undefName)) { - member->setOrdinal(_ctx.getNextOrdinalAndIncrement()); - return handleFile(*member); - } - return false; - }); -} - -llvm::Error Resolver::handleSharedLibrary(File &file) { - // Add all the atoms from the shared library - SharedLibraryFile *sharedLibrary = cast(&file); - auto undefAddedOrError = handleFile(*sharedLibrary); - if (auto ec = undefAddedOrError.takeError()) - return ec; - undefAddedOrError = - forEachUndefines(file, [&](StringRef undefName) -> llvm::Expected { - auto atom = sharedLibrary->exports(undefName); - if (atom.get()) - doSharedLibraryAtom(std::move(atom)); - return false; - }); - - if (auto ec = undefAddedOrError.takeError()) - return ec; - return llvm::Error::success(); -} - -bool Resolver::doUndefinedAtom(OwningAtomPtr atom) { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() - << " UndefinedAtom: " - << llvm::format("0x%09lX", atom.get()) - << ", name=" << atom.get()->name() << "\n"); - - // tell symbol table - bool newUndefAdded = _symbolTable.add(*atom.get()); - if (newUndefAdded) - _undefines.push_back(atom.get()->name()); - - // add to list of known atoms - _atoms.push_back(OwningAtomPtr(atom.release())); - - return newUndefAdded; -} - -// Called on each atom when a file is added. Returns true if a given -// atom is added to the symbol table. -void Resolver::doDefinedAtom(OwningAtomPtr atom) { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() - << " DefinedAtom: " - << llvm::format("0x%09lX", atom.get()) - << ", file=#" - << atom.get()->file().ordinal() - << ", atom=#" - << atom.get()->ordinal() - << ", name=" - << atom.get()->name() - << ", type=" - << atom.get()->contentType() - << "\n"); - - // An atom that should never be dead-stripped is a dead-strip root. - if (_ctx.deadStrip() && - atom.get()->deadStrip() == DefinedAtom::deadStripNever) { - _deadStripRoots.insert(atom.get()); - } - - // add to list of known atoms - _symbolTable.add(*atom.get()); - _atoms.push_back(OwningAtomPtr(atom.release())); -} - -void Resolver::doSharedLibraryAtom(OwningAtomPtr atom) { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() - << " SharedLibraryAtom: " - << llvm::format("0x%09lX", atom.get()) - << ", name=" - << atom.get()->name() - << "\n"); - - // tell symbol table - _symbolTable.add(*atom.get()); - - // add to list of known atoms - _atoms.push_back(OwningAtomPtr(atom.release())); -} - -void Resolver::doAbsoluteAtom(OwningAtomPtr atom) { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() - << " AbsoluteAtom: " - << llvm::format("0x%09lX", atom.get()) - << ", name=" - << atom.get()->name() - << "\n"); - - // tell symbol table - if (atom.get()->scope() != Atom::scopeTranslationUnit) - _symbolTable.add(*atom.get()); - - // add to list of known atoms - _atoms.push_back(OwningAtomPtr(atom.release())); -} - -// Returns true if at least one of N previous files has created an -// undefined symbol. -bool Resolver::undefinesAdded(int begin, int end) { - std::vector> &inputs = _ctx.getNodes(); - for (int i = begin; i < end; ++i) - if (FileNode *node = dyn_cast(inputs[i].get())) - if (_newUndefinesAdded[node->getFile()]) - return true; - return false; -} - -File *Resolver::getFile(int &index) { - std::vector> &inputs = _ctx.getNodes(); - if ((size_t)index >= inputs.size()) - return nullptr; - if (GroupEnd *group = dyn_cast(inputs[index].get())) { - // We are at the end of the current group. If one or more new - // undefined atom has been added in the last groupSize files, we - // reiterate over the files. - int size = group->getSize(); - if (undefinesAdded(index - size, index)) { - index -= size; - return getFile(index); - } - ++index; - return getFile(index); - } - return cast(inputs[index++].get())->getFile(); -} - -// Keep adding atoms until _ctx.getNextFile() returns an error. This -// function is where undefined atoms are resolved. -bool Resolver::resolveUndefines() { - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "******** Resolving undefines:\n"); - ScopedTask task(getDefaultDomain(), "resolveUndefines"); - int index = 0; - std::set seen; - for (;;) { - bool undefAdded = false; - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "Loading file #" << index << "\n"); - File *file = getFile(index); - if (!file) - return true; - if (std::error_code ec = file->parse()) { - llvm::errs() << "Cannot open " + file->path() << ": " << ec.message() - << "\n"; - return false; - } - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "Loaded file: " << file->path() << "\n"); - switch (file->kind()) { - case File::kindErrorObject: - case File::kindNormalizedObject: - case File::kindMachObject: - case File::kindCEntryObject: - case File::kindHeaderObject: - case File::kindEntryObject: - case File::kindUndefinedSymsObject: - case File::kindStubHelperObject: - case File::kindResolverMergedObject: - case File::kindSectCreateObject: { - // The same file may be visited more than once if the file is - // in --start-group and --end-group. Only library files should - // be processed more than once. - if (seen.count(file)) - break; - seen.insert(file); - assert(!file->hasOrdinal()); - file->setOrdinal(_ctx.getNextOrdinalAndIncrement()); - auto undefAddedOrError = handleFile(*file); - if (auto EC = undefAddedOrError.takeError()) { - // FIXME: This should be passed to logAllUnhandledErrors but it needs - // to be passed a Twine instead of a string. - llvm::errs() << "Error in " + file->path() << ": "; - logAllUnhandledErrors(std::move(EC), llvm::errs(), std::string()); - return false; - } - undefAdded = undefAddedOrError.get(); - break; - } - case File::kindArchiveLibrary: { - if (!file->hasOrdinal()) - file->setOrdinal(_ctx.getNextOrdinalAndIncrement()); - auto undefAddedOrError = handleArchiveFile(*file); - if (auto EC = undefAddedOrError.takeError()) { - // FIXME: This should be passed to logAllUnhandledErrors but it needs - // to be passed a Twine instead of a string. - llvm::errs() << "Error in " + file->path() << ": "; - logAllUnhandledErrors(std::move(EC), llvm::errs(), std::string()); - return false; - } - undefAdded = undefAddedOrError.get(); - break; - } - case File::kindSharedLibrary: - if (!file->hasOrdinal()) - file->setOrdinal(_ctx.getNextOrdinalAndIncrement()); - if (auto EC = handleSharedLibrary(*file)) { - // FIXME: This should be passed to logAllUnhandledErrors but it needs - // to be passed a Twine instead of a string. - llvm::errs() << "Error in " + file->path() << ": "; - logAllUnhandledErrors(std::move(EC), llvm::errs(), std::string()); - return false; - } - break; - } - _newUndefinesAdded[file] = undefAdded; - } -} - -// switch all references to undefined or coalesced away atoms -// to the new defined atom -void Resolver::updateReferences() { - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "******** Updating references:\n"); - ScopedTask task(getDefaultDomain(), "updateReferences"); - for (const OwningAtomPtr &atom : _atoms) { - if (const DefinedAtom *defAtom = dyn_cast(atom.get())) { - for (const Reference *ref : *defAtom) { - // A reference of type kindAssociate shouldn't be updated. - // Instead, an atom having such reference will be removed - // if the target atom is coalesced away, so that they will - // go away as a group. - if (ref->kindNamespace() == lld::Reference::KindNamespace::all && - ref->kindValue() == lld::Reference::kindAssociate) { - if (_symbolTable.isCoalescedAway(atom.get())) - _deadAtoms.insert(ref->target()); - continue; - } - const Atom *newTarget = _symbolTable.replacement(ref->target()); - const_cast(ref)->setTarget(newTarget); - } - } - } -} - -// For dead code stripping, recursively mark atoms "live" -void Resolver::markLive(const Atom *atom) { - // Mark the atom is live. If it's already marked live, then stop recursion. - auto exists = _liveAtoms.insert(atom); - if (!exists.second) - return; - - // Mark all atoms it references as live - if (const DefinedAtom *defAtom = dyn_cast(atom)) { - for (const Reference *ref : *defAtom) - markLive(ref->target()); - for (auto &p : llvm::make_range(_reverseRef.equal_range(defAtom))) { - const Atom *target = p.second; - markLive(target); - } - } -} - -static bool isBackref(const Reference *ref) { - if (ref->kindNamespace() != lld::Reference::KindNamespace::all) - return false; - return (ref->kindValue() == lld::Reference::kindLayoutAfter); -} - -// remove all atoms not actually used -void Resolver::deadStripOptimize() { - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "******** Dead stripping unused atoms:\n"); - ScopedTask task(getDefaultDomain(), "deadStripOptimize"); - // only do this optimization with -dead_strip - if (!_ctx.deadStrip()) - return; - - // Some type of references prevent referring atoms to be dead-striped. - // Make a reverse map of such references before traversing the graph. - // While traversing the list of atoms, mark AbsoluteAtoms as live - // in order to avoid reclaim. - for (const OwningAtomPtr &atom : _atoms) { - if (const DefinedAtom *defAtom = dyn_cast(atom.get())) - for (const Reference *ref : *defAtom) - if (isBackref(ref)) - _reverseRef.insert(std::make_pair(ref->target(), atom.get())); - if (const AbsoluteAtom *absAtom = dyn_cast(atom.get())) - markLive(absAtom); - } - - // By default, shared libraries are built with all globals as dead strip roots - if (_ctx.globalsAreDeadStripRoots()) - for (const OwningAtomPtr &atom : _atoms) - if (const DefinedAtom *defAtom = dyn_cast(atom.get())) - if (defAtom->scope() == DefinedAtom::scopeGlobal) - _deadStripRoots.insert(defAtom); - - // Or, use list of names that are dead strip roots. - for (const StringRef &name : _ctx.deadStripRoots()) { - const Atom *symAtom = _symbolTable.findByName(name); - assert(symAtom); - _deadStripRoots.insert(symAtom); - } - - // mark all roots as live, and recursively all atoms they reference - for (const Atom *dsrAtom : _deadStripRoots) - markLive(dsrAtom); - - // now remove all non-live atoms from _atoms - _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), - [&](OwningAtomPtr &a) { - return _liveAtoms.count(a.get()) == 0; - }), - _atoms.end()); -} - -// error out if some undefines remain -bool Resolver::checkUndefines() { - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "******** Checking for undefines:\n"); - - // build vector of remaining undefined symbols - std::vector undefinedAtoms = _symbolTable.undefines(); - if (_ctx.deadStrip()) { - // When dead code stripping, we don't care if dead atoms are undefined. - undefinedAtoms.erase( - std::remove_if(undefinedAtoms.begin(), undefinedAtoms.end(), - [&](const Atom *a) { return _liveAtoms.count(a) == 0; }), - undefinedAtoms.end()); - } - - if (undefinedAtoms.empty()) - return false; - - // Warn about unresolved symbols. - bool foundUndefines = false; - for (const UndefinedAtom *undef : undefinedAtoms) { - // Skip over a weak symbol. - if (undef->canBeNull() != UndefinedAtom::canBeNullNever) - continue; - - // If this is a library and undefined symbols are allowed on the - // target platform, skip over it. - if (isa(undef->file()) && _ctx.allowShlibUndefines()) - continue; - - // If the undefine is coalesced away, skip over it. - if (_symbolTable.isCoalescedAway(undef)) - continue; - - // Seems like this symbol is undefined. Warn that. - foundUndefines = true; - if (_ctx.printRemainingUndefines()) { - llvm::errs() << "Undefined symbol: " << undef->file().path() << ": " - << _ctx.demangle(undef->name()) << "\n"; - } - } - if (!foundUndefines) - return false; - if (_ctx.printRemainingUndefines()) - llvm::errs() << "symbol(s) not found\n"; - return true; -} - -// Remove from _atoms all coalesced away atoms. -void Resolver::removeCoalescedAwayAtoms() { - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "******** Removing coalesced away atoms:\n"); - ScopedTask task(getDefaultDomain(), "removeCoalescedAwayAtoms"); - _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), - [&](OwningAtomPtr &a) { - return _symbolTable.isCoalescedAway(a.get()) || - _deadAtoms.count(a.get()); - }), - _atoms.end()); -} - -bool Resolver::resolve() { - DEBUG_WITH_TYPE("resolver", - llvm::dbgs() << "******** Resolving atom references:\n"); - if (!resolveUndefines()) - return false; - updateReferences(); - deadStripOptimize(); - if (checkUndefines()) { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Found undefines... "); - if (!_ctx.allowRemainingUndefines()) { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "which we don't allow\n"); - return false; - } - DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "which we are ok with\n"); - } - removeCoalescedAwayAtoms(); - _result->addAtoms(_atoms); - DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "******** Finished resolver\n"); - return true; -} - -void Resolver::MergedFile::addAtoms( - llvm::MutableArrayRef> all) { - ScopedTask task(getDefaultDomain(), "addAtoms"); - DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n"); - - for (OwningAtomPtr &atom : all) { -#ifndef NDEBUG - if (auto *definedAtom = dyn_cast(atom.get())) { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() - << llvm::format(" 0x%09lX", definedAtom) - << ", file=#" - << definedAtom->file().ordinal() - << ", atom=#" - << definedAtom->ordinal() - << ", name=" - << definedAtom->name() - << ", type=" - << definedAtom->contentType() - << "\n"); - } else { - DEBUG_WITH_TYPE("resolver", llvm::dbgs() - << llvm::format(" 0x%09lX", atom.get()) - << ", name=" - << atom.get()->name() - << "\n"); - } -#endif - addAtom(*atom.release()); - } -} - -} // namespace lld diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp deleted file mode 100644 index 3ce9555aa4942..0000000000000 --- a/lld/lib/Core/SymbolTable.cpp +++ /dev/null @@ -1,284 +0,0 @@ -//===- Core/SymbolTable.cpp - Main Symbol Table ---------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/SymbolTable.h" -#include "lld/Common/LLVM.h" -#include "lld/Core/AbsoluteAtom.h" -#include "lld/Core/Atom.h" -#include "lld/Core/DefinedAtom.h" -#include "lld/Core/File.h" -#include "lld/Core/LinkingContext.h" -#include "lld/Core/Resolver.h" -#include "lld/Core/SharedLibraryAtom.h" -#include "lld/Core/UndefinedAtom.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMapInfo.h" -#include "llvm/ADT/Hashing.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include - -namespace lld { -bool SymbolTable::add(const UndefinedAtom &atom) { return addByName(atom); } - -bool SymbolTable::add(const SharedLibraryAtom &atom) { return addByName(atom); } - -bool SymbolTable::add(const AbsoluteAtom &atom) { return addByName(atom); } - -bool SymbolTable::add(const DefinedAtom &atom) { - if (!atom.name().empty() && - atom.scope() != DefinedAtom::scopeTranslationUnit) { - // Named atoms cannot be merged by content. - assert(atom.merge() != DefinedAtom::mergeByContent); - // Track named atoms that are not scoped to file (static). - return addByName(atom); - } - if (atom.merge() == DefinedAtom::mergeByContent) { - // Named atoms cannot be merged by content. - assert(atom.name().empty()); - // Currently only read-only constants can be merged. - if (atom.permissions() == DefinedAtom::permR__) - return addByContent(atom); - // TODO: support mergeByContent of data atoms by comparing content & fixups. - } - return false; -} - -enum NameCollisionResolution { - NCR_First, - NCR_Second, - NCR_DupDef, - NCR_DupUndef, - NCR_DupShLib, - NCR_Error -}; - -static NameCollisionResolution cases[4][4] = { - //regular absolute undef sharedLib - { - // first is regular - NCR_DupDef, NCR_Error, NCR_First, NCR_First - }, - { - // first is absolute - NCR_Error, NCR_Error, NCR_First, NCR_First - }, - { - // first is undef - NCR_Second, NCR_Second, NCR_DupUndef, NCR_Second - }, - { - // first is sharedLib - NCR_Second, NCR_Second, NCR_First, NCR_DupShLib - } -}; - -static NameCollisionResolution collide(Atom::Definition first, - Atom::Definition second) { - return cases[first][second]; -} - -enum MergeResolution { - MCR_First, - MCR_Second, - MCR_Largest, - MCR_SameSize, - MCR_Error -}; - -static MergeResolution mergeCases[][6] = { - // no tentative weak weakAddress sameNameAndSize largest - {MCR_Error, MCR_First, MCR_First, MCR_First, MCR_SameSize, MCR_Largest}, // no - {MCR_Second, MCR_Largest, MCR_Second, MCR_Second, MCR_SameSize, MCR_Largest}, // tentative - {MCR_Second, MCR_First, MCR_First, MCR_Second, MCR_SameSize, MCR_Largest}, // weak - {MCR_Second, MCR_First, MCR_First, MCR_First, MCR_SameSize, MCR_Largest}, // weakAddress - {MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize}, // sameSize - {MCR_Largest, MCR_Largest, MCR_Largest, MCR_Largest, MCR_SameSize, MCR_Largest}, // largest -}; - -static MergeResolution mergeSelect(DefinedAtom::Merge first, - DefinedAtom::Merge second) { - assert(first != DefinedAtom::mergeByContent); - assert(second != DefinedAtom::mergeByContent); - return mergeCases[first][second]; -} - -bool SymbolTable::addByName(const Atom &newAtom) { - StringRef name = newAtom.name(); - assert(!name.empty()); - const Atom *existing = findByName(name); - if (existing == nullptr) { - // Name is not in symbol table yet, add it associate with this atom. - _nameTable[name] = &newAtom; - return true; - } - - // Do nothing if the same object is added more than once. - if (existing == &newAtom) - return false; - - // Name is already in symbol table and associated with another atom. - bool useNew = true; - switch (collide(existing->definition(), newAtom.definition())) { - case NCR_First: - useNew = false; - break; - case NCR_Second: - useNew = true; - break; - case NCR_DupDef: { - const auto *existingDef = cast(existing); - const auto *newDef = cast(&newAtom); - switch (mergeSelect(existingDef->merge(), newDef->merge())) { - case MCR_First: - useNew = false; - break; - case MCR_Second: - useNew = true; - break; - case MCR_Largest: { - uint64_t existingSize = existingDef->sectionSize(); - uint64_t newSize = newDef->sectionSize(); - useNew = (newSize >= existingSize); - break; - } - case MCR_SameSize: { - uint64_t existingSize = existingDef->sectionSize(); - uint64_t newSize = newDef->sectionSize(); - if (existingSize == newSize) { - useNew = true; - break; - } - llvm::errs() << "Size mismatch: " << existing->name() << " (" - << existingSize << ") " << newAtom.name() << " (" << newSize - << ")\n"; - LLVM_FALLTHROUGH; - } - case MCR_Error: - llvm::errs() << "Duplicate symbols: " << existing->name() << ":" - << existing->file().path() << " and " << newAtom.name() - << ":" << newAtom.file().path() << "\n"; - llvm::report_fatal_error("duplicate symbol error"); - break; - } - break; - } - case NCR_DupUndef: { - const UndefinedAtom* existingUndef = cast(existing); - const UndefinedAtom* newUndef = cast(&newAtom); - - bool sameCanBeNull = (existingUndef->canBeNull() == newUndef->canBeNull()); - if (sameCanBeNull) - useNew = false; - else - useNew = (newUndef->canBeNull() < existingUndef->canBeNull()); - break; - } - case NCR_DupShLib: { - useNew = false; - break; - } - case NCR_Error: - llvm::errs() << "SymbolTable: error while merging " << name << "\n"; - llvm::report_fatal_error("duplicate symbol error"); - break; - } - - if (useNew) { - // Update name table to use new atom. - _nameTable[name] = &newAtom; - // Add existing atom to replacement table. - _replacedAtoms[existing] = &newAtom; - } else { - // New atom is not being used. Add it to replacement table. - _replacedAtoms[&newAtom] = existing; - } - return false; -} - -unsigned SymbolTable::AtomMappingInfo::getHashValue(const DefinedAtom *atom) { - auto content = atom->rawContent(); - return llvm::hash_combine(atom->size(), - atom->contentType(), - llvm::hash_combine_range(content.begin(), - content.end())); -} - -bool SymbolTable::AtomMappingInfo::isEqual(const DefinedAtom * const l, - const DefinedAtom * const r) { - if (l == r) - return true; - if (l == getEmptyKey() || r == getEmptyKey()) - return false; - if (l == getTombstoneKey() || r == getTombstoneKey()) - return false; - if (l->contentType() != r->contentType()) - return false; - if (l->size() != r->size()) - return false; - if (l->sectionChoice() != r->sectionChoice()) - return false; - if (l->sectionChoice() == DefinedAtom::sectionCustomRequired) { - if (!l->customSectionName().equals(r->customSectionName())) - return false; - } - ArrayRef lc = l->rawContent(); - ArrayRef rc = r->rawContent(); - return memcmp(lc.data(), rc.data(), lc.size()) == 0; -} - -bool SymbolTable::addByContent(const DefinedAtom &newAtom) { - AtomContentSet::iterator pos = _contentTable.find(&newAtom); - if (pos == _contentTable.end()) { - _contentTable.insert(&newAtom); - return true; - } - const Atom* existing = *pos; - // New atom is not being used. Add it to replacement table. - _replacedAtoms[&newAtom] = existing; - return false; -} - -const Atom *SymbolTable::findByName(StringRef sym) { - NameToAtom::iterator pos = _nameTable.find(sym); - if (pos == _nameTable.end()) - return nullptr; - return pos->second; -} - -const Atom *SymbolTable::replacement(const Atom *atom) { - // Find the replacement for a given atom. Atoms in _replacedAtoms - // may be chained, so find the last one. - for (;;) { - AtomToAtom::iterator pos = _replacedAtoms.find(atom); - if (pos == _replacedAtoms.end()) - return atom; - atom = pos->second; - } -} - -bool SymbolTable::isCoalescedAway(const Atom *atom) { - return _replacedAtoms.count(atom) > 0; -} - -std::vector SymbolTable::undefines() { - std::vector ret; - for (auto it : _nameTable) { - const Atom *atom = it.second; - assert(atom != nullptr); - if (const auto *undef = dyn_cast(atom)) - if (_replacedAtoms.count(undef) == 0) - ret.push_back(undef); - } - return ret; -} - -} // namespace lld diff --git a/lld/lib/Core/Writer.cpp b/lld/lib/Core/Writer.cpp deleted file mode 100644 index 12788b187e11e..0000000000000 --- a/lld/lib/Core/Writer.cpp +++ /dev/null @@ -1,17 +0,0 @@ -//===- lib/Core/Writer.cpp ------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lld/Core/Writer.h" - -namespace lld { - -Writer::Writer() = default; - -Writer::~Writer() = default; - -} // end namespace lld diff --git a/lld/lib/Driver/CMakeLists.txt b/lld/lib/Driver/CMakeLists.txt deleted file mode 100644 index ff67c282f47e3..0000000000000 --- a/lld/lib/Driver/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -set(LLVM_TARGET_DEFINITIONS DarwinLdOptions.td) -tablegen(LLVM DarwinLdOptions.inc -gen-opt-parser-defs) -add_public_tablegen_target(DriverOptionsTableGen) - -add_lld_library(lldDriver - DarwinLdDriver.cpp - - ADDITIONAL_HEADER_DIRS - ${LLD_INCLUDE_DIR}/lld/Driver - - LINK_COMPONENTS - Option - Support - - LINK_LIBS - lldCommon - lldCore - lldMachO - lldReaderWriter - lldYAML - ) - -add_dependencies(lldDriver DriverOptionsTableGen) diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp deleted file mode 100644 index 21d1257261927..0000000000000 --- a/lld/lib/Driver/DarwinLdDriver.cpp +++ /dev/null @@ -1,1229 +0,0 @@ -//===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// -/// Concrete instance of the Driver for darwin's ld. -/// -//===----------------------------------------------------------------------===// - -#include "lld/Common/Args.h" -#include "lld/Common/ErrorHandler.h" -#include "lld/Common/LLVM.h" -#include "lld/Core/ArchiveLibraryFile.h" -#include "lld/Core/Error.h" -#include "lld/Core/File.h" -#include "lld/Core/Instrumentation.h" -#include "lld/Core/LinkingContext.h" -#include "lld/Core/Node.h" -#include "lld/Core/PassManager.h" -#include "lld/Core/Resolver.h" -#include "lld/Core/SharedLibraryFile.h" -#include "lld/Core/Simple.h" -#include "lld/ReaderWriter/MachOLinkingContext.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" -#include "llvm/BinaryFormat/MachO.h" -#include "llvm/Option/Arg.h" -#include "llvm/Option/ArgList.h" -#include "llvm/Option/OptTable.h" -#include "llvm/Option/Option.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include -#include -#include -#include - -using namespace lld; - -namespace { - -// Create enum with OPT_xxx values for each option in DarwinLdOptions.td -enum { - OPT_INVALID = 0, -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELP, META, VALUES) \ - OPT_##ID, -#include "DarwinLdOptions.inc" -#undef OPTION -}; - -// Create prefix string literals used in DarwinLdOptions.td -#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; -#include "DarwinLdOptions.inc" -#undef PREFIX - -// Create table mapping all options defined in DarwinLdOptions.td -static const llvm::opt::OptTable::Info InfoTable[] = { -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ - HELPTEXT, METAVAR, VALUES) \ - {PREFIX, NAME, HELPTEXT, \ - METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \ - PARAM, FLAGS, OPT_##GROUP, \ - OPT_##ALIAS, ALIASARGS, VALUES}, -#include "DarwinLdOptions.inc" -#undef OPTION -}; - -// Create OptTable class for parsing actual command line arguments -class DarwinLdOptTable : public llvm::opt::OptTable { -public: - DarwinLdOptTable() : OptTable(InfoTable) {} -}; - -static std::vector> -makeErrorFile(StringRef path, std::error_code ec) { - std::vector> result; - result.push_back(std::make_unique(path, ec)); - return result; -} - -static std::vector> -parseMemberFiles(std::unique_ptr file) { - std::vector> members; - if (auto *archive = dyn_cast(file.get())) { - if (std::error_code ec = archive->parseAllMembers(members)) - return makeErrorFile(file->path(), ec); - } else { - members.push_back(std::move(file)); - } - return members; -} - -std::vector> loadFile(MachOLinkingContext &ctx, - StringRef path, bool wholeArchive, - bool upwardDylib) { - if (ctx.logInputFiles()) - message(path); - - ErrorOr> mbOrErr = ctx.getMemoryBuffer(path); - if (std::error_code ec = mbOrErr.getError()) - return makeErrorFile(path, ec); - ErrorOr> fileOrErr = - ctx.registry().loadFile(std::move(mbOrErr.get())); - if (std::error_code ec = fileOrErr.getError()) - return makeErrorFile(path, ec); - std::unique_ptr &file = fileOrErr.get(); - - // If file is a dylib, inform LinkingContext about it. - if (SharedLibraryFile *shl = dyn_cast(file.get())) { - if (std::error_code ec = shl->parse()) - return makeErrorFile(path, ec); - ctx.registerDylib(reinterpret_cast(shl), - upwardDylib); - } - if (wholeArchive) - return parseMemberFiles(std::move(file)); - std::vector> files; - files.push_back(std::move(file)); - return files; -} - -} // end anonymous namespace - -// Test may be running on Windows. Canonicalize the path -// separator to '/' to get consistent outputs for tests. -static std::string canonicalizePath(StringRef path) { - char sep = llvm::sys::path::get_separator().front(); - if (sep != '/') { - std::string fixedPath = std::string(path); - std::replace(fixedPath.begin(), fixedPath.end(), sep, '/'); - return fixedPath; - } else { - return std::string(path); - } -} - -static void addFile(StringRef path, MachOLinkingContext &ctx, - bool loadWholeArchive, bool upwardDylib) { - std::vector> files = - loadFile(ctx, path, loadWholeArchive, upwardDylib); - for (std::unique_ptr &file : files) - ctx.getNodes().push_back(std::make_unique(std::move(file))); -} - -// Export lists are one symbol per line. Blank lines are ignored. -// Trailing comments start with #. -static std::error_code parseExportsList(StringRef exportFilePath, - MachOLinkingContext &ctx) { - // Map in export list file. - ErrorOr> mb = - MemoryBuffer::getFileOrSTDIN(exportFilePath); - if (std::error_code ec = mb.getError()) - return ec; - ctx.addInputFileDependency(exportFilePath); - StringRef buffer = mb->get()->getBuffer(); - while (!buffer.empty()) { - // Split off each line in the file. - std::pair lineAndRest = buffer.split('\n'); - StringRef line = lineAndRest.first; - // Ignore trailing # comments. - std::pair symAndComment = line.split('#'); - StringRef sym = symAndComment.first.trim(); - if (!sym.empty()) - ctx.addExportSymbol(sym); - buffer = lineAndRest.second; - } - return std::error_code(); -} - -/// Order files are one symbol per line. Blank lines are ignored. -/// Trailing comments start with #. Symbol names can be prefixed with an -/// architecture name and/or .o leaf name. Examples: -/// _foo -/// bar.o:_bar -/// libfrob.a(bar.o):_bar -/// x86_64:_foo64 -static std::error_code parseOrderFile(StringRef orderFilePath, - MachOLinkingContext &ctx) { - // Map in order file. - ErrorOr> mb = - MemoryBuffer::getFileOrSTDIN(orderFilePath); - if (std::error_code ec = mb.getError()) - return ec; - ctx.addInputFileDependency(orderFilePath); - StringRef buffer = mb->get()->getBuffer(); - while (!buffer.empty()) { - // Split off each line in the file. - std::pair lineAndRest = buffer.split('\n'); - StringRef line = lineAndRest.first; - buffer = lineAndRest.second; - // Ignore trailing # comments. - std::pair symAndComment = line.split('#'); - if (symAndComment.first.empty()) - continue; - StringRef sym = symAndComment.first.trim(); - if (sym.empty()) - continue; - // Check for prefix. - StringRef prefix; - std::pair prefixAndSym = sym.split(':'); - if (!prefixAndSym.second.empty()) { - sym = prefixAndSym.second; - prefix = prefixAndSym.first; - if (!prefix.endswith(".o") && !prefix.endswith(".o)")) { - // If arch name prefix does not match arch being linked, ignore symbol. - if (!ctx.archName().equals(prefix)) - continue; - prefix = ""; - } - } else - sym = prefixAndSym.first; - if (!sym.empty()) { - ctx.appendOrderedSymbol(sym, prefix); - // llvm::errs() << sym << ", prefix=" << prefix << "\n"; - } - } - return std::error_code(); -} - -// -// There are two variants of the -filelist option: -// -// -filelist -// In this variant, the path is to a text file which contains one file path -// per line. There are no comments or trimming of whitespace. -// -// -fileList , -// In this variant, the path is to a text file which contains a partial path -// per line. The prefix is prepended to each partial path. -// -static llvm::Error loadFileList(StringRef fileListPath, - MachOLinkingContext &ctx, bool forceLoad) { - // If there is a comma, split off . - std::pair opt = fileListPath.split(','); - StringRef filePath = opt.first; - StringRef dirName = opt.second; - ctx.addInputFileDependency(filePath); - // Map in file list file. - ErrorOr> mb = - MemoryBuffer::getFileOrSTDIN(filePath); - if (std::error_code ec = mb.getError()) - return llvm::errorCodeToError(ec); - StringRef buffer = mb->get()->getBuffer(); - while (!buffer.empty()) { - // Split off each line in the file. - std::pair lineAndRest = buffer.split('\n'); - StringRef line = lineAndRest.first; - StringRef path; - if (!dirName.empty()) { - // If there is a then prepend dir to each line. - SmallString<256> fullPath; - fullPath.assign(dirName); - llvm::sys::path::append(fullPath, Twine(line)); - path = ctx.copy(fullPath.str()); - } else { - // No use whole line as input file path. - path = ctx.copy(line); - } - if (!ctx.pathExists(path)) { - return llvm::make_error(Twine("File not found '") - + path - + "'"); - } - if (ctx.testingFileUsage()) { - message("Found filelist entry " + canonicalizePath(path)); - } - addFile(path, ctx, forceLoad, false); - buffer = lineAndRest.second; - } - return llvm::Error::success(); -} - -/// Parse number assuming it is base 16, but allow 0x prefix. -static bool parseNumberBase16(StringRef numStr, uint64_t &baseAddress) { - if (numStr.startswith_insensitive("0x")) - numStr = numStr.drop_front(2); - return numStr.getAsInteger(16, baseAddress); -} - -static void parseLLVMOptions(const LinkingContext &ctx) { - // Honor -mllvm - if (!ctx.llvmOptions().empty()) { - unsigned numArgs = ctx.llvmOptions().size(); - auto **args = new const char *[numArgs + 2]; - args[0] = "lld (LLVM option parsing)"; - for (unsigned i = 0; i != numArgs; ++i) - args[i + 1] = ctx.llvmOptions()[i]; - args[numArgs + 1] = nullptr; - llvm::cl::ResetAllOptionOccurrences(); - llvm::cl::ParseCommandLineOptions(numArgs + 1, args); - } -} - -namespace lld { -namespace mach_o { - -bool parse(llvm::ArrayRef args, MachOLinkingContext &ctx) { - // Parse command line options using DarwinLdOptions.td - DarwinLdOptTable table; - unsigned missingIndex; - unsigned missingCount; - llvm::opt::InputArgList parsedArgs = - table.ParseArgs(args.slice(1), missingIndex, missingCount); - if (missingCount) { - error("missing arg value for '" + - Twine(parsedArgs.getArgString(missingIndex)) + "' expected " + - Twine(missingCount) + " argument(s)."); - return false; - } - - for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN)) { - warn("ignoring unknown argument: " + - Twine(unknownArg->getAsString(parsedArgs))); - } - - errorHandler().verbose = parsedArgs.hasArg(OPT_v); - errorHandler().errorLimit = args::getInteger(parsedArgs, OPT_error_limit, 20); - - // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static ) - llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE; - bool isStaticExecutable = false; - if (llvm::opt::Arg *kind = parsedArgs.getLastArg( - OPT_dylib, OPT_relocatable, OPT_bundle, OPT_static, OPT_preload)) { - switch (kind->getOption().getID()) { - case OPT_dylib: - fileType = llvm::MachO::MH_DYLIB; - break; - case OPT_relocatable: - fileType = llvm::MachO::MH_OBJECT; - break; - case OPT_bundle: - fileType = llvm::MachO::MH_BUNDLE; - break; - case OPT_static: - fileType = llvm::MachO::MH_EXECUTE; - isStaticExecutable = true; - break; - case OPT_preload: - fileType = llvm::MachO::MH_PRELOAD; - break; - } - } - - // Handle -arch xxx - MachOLinkingContext::Arch arch = MachOLinkingContext::arch_unknown; - if (llvm::opt::Arg *archStr = parsedArgs.getLastArg(OPT_arch)) { - arch = MachOLinkingContext::archFromName(archStr->getValue()); - if (arch == MachOLinkingContext::arch_unknown) { - error("unknown arch named '" + Twine(archStr->getValue()) + "'"); - return false; - } - } - // If no -arch specified, scan input files to find first non-fat .o file. - if (arch == MachOLinkingContext::arch_unknown) { - for (auto &inFile : parsedArgs.filtered(OPT_INPUT)) { - // This is expensive because it opens and maps the file. But that is - // ok because no -arch is rare. - if (MachOLinkingContext::isThinObjectFile(inFile->getValue(), arch)) - break; - } - if (arch == MachOLinkingContext::arch_unknown && - !parsedArgs.getLastArg(OPT_test_file_usage)) { - // If no -arch and no options at all, print usage message. - if (parsedArgs.size() == 0) { - table.printHelp(llvm::outs(), - (std::string(args[0]) + " [options] file...").c_str(), - "LLVM Linker", false); - } else { - error("-arch not specified and could not be inferred"); - } - return false; - } - } - - // Handle -macosx_version_min or -ios_version_min - MachOLinkingContext::OS os = MachOLinkingContext::OS::unknown; - uint32_t minOSVersion = 0; - if (llvm::opt::Arg *minOS = - parsedArgs.getLastArg(OPT_macosx_version_min, OPT_ios_version_min, - OPT_ios_simulator_version_min)) { - switch (minOS->getOption().getID()) { - case OPT_macosx_version_min: - os = MachOLinkingContext::OS::macOSX; - if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), - minOSVersion)) { - error("malformed macosx_version_min value"); - return false; - } - break; - case OPT_ios_version_min: - os = MachOLinkingContext::OS::iOS; - if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), - minOSVersion)) { - error("malformed ios_version_min value"); - return false; - } - break; - case OPT_ios_simulator_version_min: - os = MachOLinkingContext::OS::iOS_simulator; - if (MachOLinkingContext::parsePackedVersion(minOS->getValue(), - minOSVersion)) { - error("malformed ios_simulator_version_min value"); - return false; - } - break; - } - } else { - // No min-os version on command line, check environment variables - } - - // Handle export_dynamic - // FIXME: Should we warn when this applies to something other than a static - // executable or dylib? Those are the only cases where this has an effect. - // Note, this has to come before ctx.configure() so that we get the correct - // value for _globalsAreDeadStripRoots. - bool exportDynamicSymbols = parsedArgs.hasArg(OPT_export_dynamic); - - // Now that there's enough information parsed in, let the linking context - // set up default values. - ctx.configure(fileType, arch, os, minOSVersion, exportDynamicSymbols); - - // Handle -e xxx - if (llvm::opt::Arg *entry = parsedArgs.getLastArg(OPT_entry)) - ctx.setEntrySymbolName(entry->getValue()); - - // Handle -o xxx - if (llvm::opt::Arg *outpath = parsedArgs.getLastArg(OPT_output)) - ctx.setOutputPath(outpath->getValue()); - else - ctx.setOutputPath("a.out"); - - // Handle -image_base XXX and -seg1addr XXXX - if (llvm::opt::Arg *imageBase = parsedArgs.getLastArg(OPT_image_base)) { - uint64_t baseAddress; - if (parseNumberBase16(imageBase->getValue(), baseAddress)) { - error("image_base expects a hex number"); - return false; - } else if (baseAddress < ctx.pageZeroSize()) { - error("image_base overlaps with __PAGEZERO"); - return false; - } else if (baseAddress % ctx.pageSize()) { - error("image_base must be a multiple of page size (0x" + - llvm::utohexstr(ctx.pageSize()) + ")"); - return false; - } - - ctx.setBaseAddress(baseAddress); - } - - // Handle -dead_strip - if (parsedArgs.getLastArg(OPT_dead_strip)) - ctx.setDeadStripping(true); - - bool globalWholeArchive = false; - // Handle -all_load - if (parsedArgs.getLastArg(OPT_all_load)) - globalWholeArchive = true; - - // Handle -install_name - if (llvm::opt::Arg *installName = parsedArgs.getLastArg(OPT_install_name)) - ctx.setInstallName(installName->getValue()); - else - ctx.setInstallName(ctx.outputPath()); - - // Handle -mark_dead_strippable_dylib - if (parsedArgs.getLastArg(OPT_mark_dead_strippable_dylib)) - ctx.setDeadStrippableDylib(true); - - // Handle -compatibility_version and -current_version - if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_compatibility_version)) { - if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) { - error("-compatibility_version can only be used with -dylib"); - return false; - } - uint32_t parsedVers; - if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { - error("-compatibility_version value is malformed"); - return false; - } - ctx.setCompatibilityVersion(parsedVers); - } - - if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_current_version)) { - if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) { - error("-current_version can only be used with -dylib"); - return false; - } - uint32_t parsedVers; - if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) { - error("-current_version value is malformed"); - return false; - } - ctx.setCurrentVersion(parsedVers); - } - - // Handle -bundle_loader - if (llvm::opt::Arg *loader = parsedArgs.getLastArg(OPT_bundle_loader)) - ctx.setBundleLoader(loader->getValue()); - - // Handle -sectalign segname sectname align - for (auto &alignArg : parsedArgs.filtered(OPT_sectalign)) { - const char* segName = alignArg->getValue(0); - const char* sectName = alignArg->getValue(1); - const char* alignStr = alignArg->getValue(2); - if ((alignStr[0] == '0') && (alignStr[1] == 'x')) - alignStr += 2; - unsigned long long alignValue; - if (llvm::getAsUnsignedInteger(alignStr, 16, alignValue)) { - error("-sectalign alignment value '" + Twine(alignStr) + - "' not a valid number"); - return false; - } - uint16_t align = 1 << llvm::countTrailingZeros(alignValue); - if (!llvm::isPowerOf2_64(alignValue)) { - std::string Msg; - llvm::raw_string_ostream OS(Msg); - OS << "alignment for '-sectalign " << segName << " " << sectName - << llvm::format(" 0x%llX", alignValue) - << "' is not a power of two, using " << llvm::format("0x%08X", align); - OS.flush(); - warn(Msg); - } - ctx.addSectionAlignment(segName, sectName, align); - } - - // Handle -mllvm - for (auto &llvmArg : parsedArgs.filtered(OPT_mllvm)) { - ctx.appendLLVMOption(llvmArg->getValue()); - } - - // Handle -print_atoms - if (parsedArgs.getLastArg(OPT_print_atoms)) - ctx.setPrintAtoms(); - - // Handle -t (trace) option. - if (parsedArgs.getLastArg(OPT_t)) - ctx.setLogInputFiles(true); - - // Handle -demangle option. - if (parsedArgs.getLastArg(OPT_demangle)) - ctx.setDemangleSymbols(true); - - // Handle -keep_private_externs - if (parsedArgs.getLastArg(OPT_keep_private_externs)) { - ctx.setKeepPrivateExterns(true); - if (ctx.outputMachOType() != llvm::MachO::MH_OBJECT) - warn("-keep_private_externs only used in -r mode"); - } - - // Handle -dependency_info used by Xcode. - if (llvm::opt::Arg *depInfo = parsedArgs.getLastArg(OPT_dependency_info)) - if (std::error_code ec = ctx.createDependencyFile(depInfo->getValue())) - warn(ec.message() + ", processing '-dependency_info " + - depInfo->getValue()); - - // In -test_file_usage mode, we'll be given an explicit list of paths that - // exist. We'll also be expected to print out information about how we located - // libraries and so on that the user specified, but not to actually do any - // linking. - if (parsedArgs.getLastArg(OPT_test_file_usage)) { - ctx.setTestingFileUsage(); - - // With paths existing by fiat, linking is not going to end well. - ctx.setDoNothing(true); - - // Only bother looking for an existence override if we're going to use it. - for (auto existingPath : parsedArgs.filtered(OPT_path_exists)) { - ctx.addExistingPathForDebug(existingPath->getValue()); - } - } - - // Register possible input file parsers. - if (!ctx.doNothing()) { - ctx.registry().addSupportMachOObjects(ctx); - ctx.registry().addSupportArchives(ctx.logInputFiles()); - ctx.registry().addSupportYamlFiles(); - } - - // Now construct the set of library search directories, following ld64's - // baroque set of accumulated hacks. Mostly, the algorithm constructs - // { syslibroots } x { libpaths } - // - // Unfortunately, there are numerous exceptions: - // 1. Only absolute paths get modified by syslibroot options. - // 2. If there is just 1 -syslibroot, system paths not found in it are - // skipped. - // 3. If the last -syslibroot is "/", all of them are ignored entirely. - // 4. If { syslibroots } x path == {}, the original path is kept. - std::vector sysLibRoots; - for (auto syslibRoot : parsedArgs.filtered(OPT_syslibroot)) { - sysLibRoots.push_back(syslibRoot->getValue()); - } - if (!sysLibRoots.empty()) { - // Ignore all if last -syslibroot is "/". - if (sysLibRoots.back() != "/") - ctx.setSysLibRoots(sysLibRoots); - } - - // Paths specified with -L come first, and are not considered system paths for - // the case where there is precisely 1 -syslibroot. - for (auto libPath : parsedArgs.filtered(OPT_L)) { - ctx.addModifiedSearchDir(libPath->getValue()); - } - - // Process -F directories (where to look for frameworks). - for (auto fwPath : parsedArgs.filtered(OPT_F)) { - ctx.addFrameworkSearchDir(fwPath->getValue()); - } - - // -Z suppresses the standard search paths. - if (!parsedArgs.hasArg(OPT_Z)) { - ctx.addModifiedSearchDir("/usr/lib", true); - ctx.addModifiedSearchDir("/usr/local/lib", true); - ctx.addFrameworkSearchDir("/Library/Frameworks", true); - ctx.addFrameworkSearchDir("/System/Library/Frameworks", true); - } - - // Now that we've constructed the final set of search paths, print out those - // search paths in verbose mode. - if (errorHandler().verbose) { - message("Library search paths:"); - for (auto path : ctx.searchDirs()) { - message(" " + path); - } - message("Framework search paths:"); - for (auto path : ctx.frameworkDirs()) { - message(" " + path); - } - } - - // Handle -exported_symbols_list - for (auto expFile : parsedArgs.filtered(OPT_exported_symbols_list)) { - if (ctx.exportMode() == MachOLinkingContext::ExportMode::unexported) { - error("-exported_symbols_list cannot be combined with " - "-unexported_symbol[s_list]"); - return false; - } - ctx.setExportMode(MachOLinkingContext::ExportMode::exported); - if (std::error_code ec = parseExportsList(expFile->getValue(), ctx)) { - error(ec.message() + ", processing '-exported_symbols_list " + - expFile->getValue()); - return false; - } - } - - // Handle -exported_symbol - for (auto symbol : parsedArgs.filtered(OPT_exported_symbol)) { - if (ctx.exportMode() == MachOLinkingContext::ExportMode::unexported) { - error("-exported_symbol cannot be combined with " - "-unexported_symbol[s_list]"); - return false; - } - ctx.setExportMode(MachOLinkingContext::ExportMode::exported); - ctx.addExportSymbol(symbol->getValue()); - } - - // Handle -unexported_symbols_list - for (auto expFile : parsedArgs.filtered(OPT_unexported_symbols_list)) { - if (ctx.exportMode() == MachOLinkingContext::ExportMode::exported) { - error("-unexported_symbols_list cannot be combined with " - "-exported_symbol[s_list]"); - return false; - } - ctx.setExportMode(MachOLinkingContext::ExportMode::unexported); - if (std::error_code ec = parseExportsList(expFile->getValue(), ctx)) { - error(ec.message() + ", processing '-unexported_symbols_list " + - expFile->getValue()); - return false; - } - } - - // Handle -unexported_symbol - for (auto symbol : parsedArgs.filtered(OPT_unexported_symbol)) { - if (ctx.exportMode() == MachOLinkingContext::ExportMode::exported) { - error("-unexported_symbol cannot be combined with " - "-exported_symbol[s_list]"); - return false; - } - ctx.setExportMode(MachOLinkingContext::ExportMode::unexported); - ctx.addExportSymbol(symbol->getValue()); - } - - // Handle obosolete -multi_module and -single_module - if (llvm::opt::Arg *mod = - parsedArgs.getLastArg(OPT_multi_module, OPT_single_module)) { - if (mod->getOption().getID() == OPT_multi_module) - warn("-multi_module is obsolete and being ignored"); - else if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) - warn("-single_module being ignored. It is only for use when producing a " - "dylib"); - } - - // Handle obsolete ObjC options: -objc_gc_compaction, -objc_gc, -objc_gc_only - if (parsedArgs.getLastArg(OPT_objc_gc_compaction)) { - error("-objc_gc_compaction is not supported"); - return false; - } - - if (parsedArgs.getLastArg(OPT_objc_gc)) { - error("-objc_gc is not supported"); - return false; - } - - if (parsedArgs.getLastArg(OPT_objc_gc_only)) { - error("-objc_gc_only is not supported"); - return false; - } - - // Handle -pie or -no_pie - if (llvm::opt::Arg *pie = parsedArgs.getLastArg(OPT_pie, OPT_no_pie)) { - switch (ctx.outputMachOType()) { - case llvm::MachO::MH_EXECUTE: - switch (ctx.os()) { - case MachOLinkingContext::OS::macOSX: - if ((minOSVersion < 0x000A0500) && - (pie->getOption().getID() == OPT_pie)) { - error("-pie can only be used when targeting Mac OS X 10.5 or later"); - return false; - } - break; - case MachOLinkingContext::OS::iOS: - if ((minOSVersion < 0x00040200) && - (pie->getOption().getID() == OPT_pie)) { - error("-pie can only be used when targeting iOS 4.2 or later"); - return false; - } - break; - case MachOLinkingContext::OS::iOS_simulator: - if (pie->getOption().getID() == OPT_no_pie) { - error("iOS simulator programs must be built PIE"); - return false; - } - break; - case MachOLinkingContext::OS::unknown: - break; - } - ctx.setPIE(pie->getOption().getID() == OPT_pie); - break; - case llvm::MachO::MH_PRELOAD: - break; - case llvm::MachO::MH_DYLIB: - case llvm::MachO::MH_BUNDLE: - warn(pie->getSpelling() + - " being ignored. It is only used when linking main executables"); - break; - default: - error(pie->getSpelling() + - " can only used when linking main executables"); - return false; - } - } - - // Handle -version_load_command or -no_version_load_command - { - bool flagOn = false; - bool flagOff = false; - if (auto *arg = parsedArgs.getLastArg(OPT_version_load_command, - OPT_no_version_load_command)) { - flagOn = arg->getOption().getID() == OPT_version_load_command; - flagOff = arg->getOption().getID() == OPT_no_version_load_command; - } - - // default to adding version load command for dynamic code, - // static code must opt-in - switch (ctx.outputMachOType()) { - case llvm::MachO::MH_OBJECT: - ctx.setGenerateVersionLoadCommand(false); - break; - case llvm::MachO::MH_EXECUTE: - // dynamic executables default to generating a version load command, - // while static executables only generate it if required. - if (isStaticExecutable) { - if (flagOn) - ctx.setGenerateVersionLoadCommand(true); - } else { - if (!flagOff) - ctx.setGenerateVersionLoadCommand(true); - } - break; - case llvm::MachO::MH_PRELOAD: - case llvm::MachO::MH_KEXT_BUNDLE: - if (flagOn) - ctx.setGenerateVersionLoadCommand(true); - break; - case llvm::MachO::MH_DYLINKER: - case llvm::MachO::MH_DYLIB: - case llvm::MachO::MH_BUNDLE: - if (!flagOff) - ctx.setGenerateVersionLoadCommand(true); - break; - case llvm::MachO::MH_FVMLIB: - case llvm::MachO::MH_DYLDLINK: - case llvm::MachO::MH_DYLIB_STUB: - case llvm::MachO::MH_DSYM: - // We don't generate load commands for these file types, even if - // forced on. - break; - } - } - - // Handle -function_starts or -no_function_starts - { - bool flagOn = false; - bool flagOff = false; - if (auto *arg = parsedArgs.getLastArg(OPT_function_starts, - OPT_no_function_starts)) { - flagOn = arg->getOption().getID() == OPT_function_starts; - flagOff = arg->getOption().getID() == OPT_no_function_starts; - } - - // default to adding functions start for dynamic code, static code must - // opt-in - switch (ctx.outputMachOType()) { - case llvm::MachO::MH_OBJECT: - ctx.setGenerateFunctionStartsLoadCommand(false); - break; - case llvm::MachO::MH_EXECUTE: - // dynamic executables default to generating a version load command, - // while static executables only generate it if required. - if (isStaticExecutable) { - if (flagOn) - ctx.setGenerateFunctionStartsLoadCommand(true); - } else { - if (!flagOff) - ctx.setGenerateFunctionStartsLoadCommand(true); - } - break; - case llvm::MachO::MH_PRELOAD: - case llvm::MachO::MH_KEXT_BUNDLE: - if (flagOn) - ctx.setGenerateFunctionStartsLoadCommand(true); - break; - case llvm::MachO::MH_DYLINKER: - case llvm::MachO::MH_DYLIB: - case llvm::MachO::MH_BUNDLE: - if (!flagOff) - ctx.setGenerateFunctionStartsLoadCommand(true); - break; - case llvm::MachO::MH_FVMLIB: - case llvm::MachO::MH_DYLDLINK: - case llvm::MachO::MH_DYLIB_STUB: - case llvm::MachO::MH_DSYM: - // We don't generate load commands for these file types, even if - // forced on. - break; - } - } - - // Handle -data_in_code_info or -no_data_in_code_info - { - bool flagOn = false; - bool flagOff = false; - if (auto *arg = parsedArgs.getLastArg(OPT_data_in_code_info, - OPT_no_data_in_code_info)) { - flagOn = arg->getOption().getID() == OPT_data_in_code_info; - flagOff = arg->getOption().getID() == OPT_no_data_in_code_info; - } - - // default to adding data in code for dynamic code, static code must - // opt-in - switch (ctx.outputMachOType()) { - case llvm::MachO::MH_OBJECT: - if (!flagOff) - ctx.setGenerateDataInCodeLoadCommand(true); - break; - case llvm::MachO::MH_EXECUTE: - // dynamic executables default to generating a version load command, - // while static executables only generate it if required. - if (isStaticExecutable) { - if (flagOn) - ctx.setGenerateDataInCodeLoadCommand(true); - } else { - if (!flagOff) - ctx.setGenerateDataInCodeLoadCommand(true); - } - break; - case llvm::MachO::MH_PRELOAD: - case llvm::MachO::MH_KEXT_BUNDLE: - if (flagOn) - ctx.setGenerateDataInCodeLoadCommand(true); - break; - case llvm::MachO::MH_DYLINKER: - case llvm::MachO::MH_DYLIB: - case llvm::MachO::MH_BUNDLE: - if (!flagOff) - ctx.setGenerateDataInCodeLoadCommand(true); - break; - case llvm::MachO::MH_FVMLIB: - case llvm::MachO::MH_DYLDLINK: - case llvm::MachO::MH_DYLIB_STUB: - case llvm::MachO::MH_DSYM: - // We don't generate load commands for these file types, even if - // forced on. - break; - } - } - - // Handle sdk_version - if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_sdk_version)) { - uint32_t sdkVersion = 0; - if (MachOLinkingContext::parsePackedVersion(arg->getValue(), - sdkVersion)) { - error("malformed sdkVersion value"); - return false; - } - ctx.setSdkVersion(sdkVersion); - } else if (ctx.generateVersionLoadCommand()) { - // If we don't have an sdk version, but were going to emit a load command - // with min_version, then we need to give a warning as we have no sdk - // version to put in that command. - // FIXME: We need to decide whether to make this an error. - warn("-sdk_version is required when emitting min version load command. " - "Setting sdk version to match provided min version"); - ctx.setSdkVersion(ctx.osMinVersion()); - } - - // Handle source_version - if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_source_version)) { - uint64_t version = 0; - if (MachOLinkingContext::parsePackedVersion(arg->getValue(), - version)) { - error("malformed source_version value"); - return false; - } - ctx.setSourceVersion(version); - } - - // Handle stack_size - if (llvm::opt::Arg *stackSize = parsedArgs.getLastArg(OPT_stack_size)) { - uint64_t stackSizeVal; - if (parseNumberBase16(stackSize->getValue(), stackSizeVal)) { - error("stack_size expects a hex number"); - return false; - } - if ((stackSizeVal % ctx.pageSize()) != 0) { - error("stack_size must be a multiple of page size (0x" + - llvm::utohexstr(ctx.pageSize()) + ")"); - return false; - } - - ctx.setStackSize(stackSizeVal); - } - - // Handle debug info handling options: -S - if (parsedArgs.hasArg(OPT_S)) - ctx.setDebugInfoMode(MachOLinkingContext::DebugInfoMode::noDebugMap); - - // Handle -order_file - for (auto orderFile : parsedArgs.filtered(OPT_order_file)) { - if (std::error_code ec = parseOrderFile(orderFile->getValue(), ctx)) { - error(ec.message() + ", processing '-order_file " + orderFile->getValue() - + "'"); - return false; - } - } - - // Handle -flat_namespace. - if (llvm::opt::Arg *ns = - parsedArgs.getLastArg(OPT_flat_namespace, OPT_twolevel_namespace)) { - if (ns->getOption().getID() == OPT_flat_namespace) - ctx.setUseFlatNamespace(true); - } - - // Handle -undefined - if (llvm::opt::Arg *undef = parsedArgs.getLastArg(OPT_undefined)) { - MachOLinkingContext::UndefinedMode UndefMode; - if (StringRef(undef->getValue()).equals("error")) - UndefMode = MachOLinkingContext::UndefinedMode::error; - else if (StringRef(undef->getValue()).equals("warning")) - UndefMode = MachOLinkingContext::UndefinedMode::warning; - else if (StringRef(undef->getValue()).equals("suppress")) - UndefMode = MachOLinkingContext::UndefinedMode::suppress; - else if (StringRef(undef->getValue()).equals("dynamic_lookup")) - UndefMode = MachOLinkingContext::UndefinedMode::dynamicLookup; - else { - error("invalid option to -undefined [ warning | error | suppress | " - "dynamic_lookup ]"); - return false; - } - - if (ctx.useFlatNamespace()) { - // If we're using -flat_namespace then 'warning', 'suppress' and - // 'dynamic_lookup' are all equivalent, so map them to 'suppress'. - if (UndefMode != MachOLinkingContext::UndefinedMode::error) - UndefMode = MachOLinkingContext::UndefinedMode::suppress; - } else { - // If we're using -twolevel_namespace then 'warning' and 'suppress' are - // illegal. Emit a diagnostic if they've been (mis)used. - if (UndefMode == MachOLinkingContext::UndefinedMode::warning || - UndefMode == MachOLinkingContext::UndefinedMode::suppress) { - error("can't use -undefined warning or suppress with " - "-twolevel_namespace"); - return false; - } - } - - ctx.setUndefinedMode(UndefMode); - } - - // Handle -no_objc_category_merging. - if (parsedArgs.getLastArg(OPT_no_objc_category_merging)) - ctx.setMergeObjCCategories(false); - - // Handle -rpath - if (parsedArgs.hasArg(OPT_rpath)) { - switch (ctx.outputMachOType()) { - case llvm::MachO::MH_EXECUTE: - case llvm::MachO::MH_DYLIB: - case llvm::MachO::MH_BUNDLE: - if (!ctx.minOS("10.5", "2.0")) { - if (ctx.os() == MachOLinkingContext::OS::macOSX) - error("-rpath can only be used when targeting OS X 10.5 or later"); - else - error("-rpath can only be used when targeting iOS 2.0 or later"); - return false; - } - break; - default: - error("-rpath can only be used when creating a dynamic final linked " - "image"); - return false; - } - - for (auto rPath : parsedArgs.filtered(OPT_rpath)) { - ctx.addRpath(rPath->getValue()); - } - } - - // Parse the LLVM options before we process files in case the file handling - // makes use of things like LLVM_DEBUG(). - parseLLVMOptions(ctx); - - // Handle input files and sectcreate. - for (auto &arg : parsedArgs) { - bool upward; - llvm::Optional resolvedPath; - switch (arg->getOption().getID()) { - default: - continue; - case OPT_INPUT: - addFile(arg->getValue(), ctx, globalWholeArchive, false); - break; - case OPT_upward_library: - addFile(arg->getValue(), ctx, false, true); - break; - case OPT_force_load: - addFile(arg->getValue(), ctx, true, false); - break; - case OPT_l: - case OPT_upward_l: - upward = (arg->getOption().getID() == OPT_upward_l); - resolvedPath = ctx.searchLibrary(arg->getValue()); - if (!resolvedPath) { - error("Unable to find library for " + arg->getSpelling() + - arg->getValue()); - return false; - } else if (ctx.testingFileUsage()) { - message(Twine("Found ") + (upward ? "upward " : " ") + "library " + - canonicalizePath(resolvedPath.getValue())); - } - addFile(resolvedPath.getValue(), ctx, globalWholeArchive, upward); - break; - case OPT_framework: - case OPT_upward_framework: - upward = (arg->getOption().getID() == OPT_upward_framework); - resolvedPath = ctx.findPathForFramework(arg->getValue()); - if (!resolvedPath) { - error("Unable to find framework for " + arg->getSpelling() + " " + - arg->getValue()); - return false; - } else if (ctx.testingFileUsage()) { - message(Twine("Found ") + (upward ? "upward " : " ") + "framework " + - canonicalizePath(resolvedPath.getValue())); - } - addFile(resolvedPath.getValue(), ctx, globalWholeArchive, upward); - break; - case OPT_filelist: - if (auto ec = loadFileList(arg->getValue(), ctx, globalWholeArchive)) { - handleAllErrors(std::move(ec), [&](const llvm::ErrorInfoBase &EI) { - error(EI.message() + ", processing '-filelist " + arg->getValue()); - }); - return false; - } - break; - case OPT_sectcreate: { - const char* seg = arg->getValue(0); - const char* sect = arg->getValue(1); - const char* fileName = arg->getValue(2); - - ErrorOr> contentOrErr = - MemoryBuffer::getFile(fileName); - - if (!contentOrErr) { - error("can't open -sectcreate file " + Twine(fileName)); - return false; - } - - ctx.addSectCreateSection(seg, sect, std::move(*contentOrErr)); - } - break; - } - } - - if (ctx.getNodes().empty()) { - error("No input files"); - return false; - } - - // Validate the combination of options used. - return ctx.validate(); -} - -static void createFiles(MachOLinkingContext &ctx, bool Implicit) { - std::vector> Files; - if (Implicit) - ctx.createImplicitFiles(Files); - else - ctx.createInternalFiles(Files); - for (auto i = Files.rbegin(), e = Files.rend(); i != e; ++i) { - auto &members = ctx.getNodes(); - members.insert(members.begin(), std::make_unique(std::move(*i))); - } -} - -/// This is where the link is actually performed. -bool link(llvm::ArrayRef args, bool CanExitEarly, - raw_ostream &StdoutOS, raw_ostream &StderrOS) { - lld::stdoutOS = &StdoutOS; - lld::stderrOS = &StderrOS; - - errorHandler().logName = args::getFilenameWithoutExe(args[0]); - errorHandler().errorLimitExceededMsg = - "too many errors emitted, stopping now (use " - "'-error-limit 0' to see all errors)"; - errorHandler().exitEarly = CanExitEarly; - StderrOS.enable_colors(StderrOS.has_colors()); - - MachOLinkingContext ctx; - if (!parse(args, ctx)) - return false; - if (ctx.doNothing()) - return true; - if (ctx.getNodes().empty()) - return false; - - for (std::unique_ptr &ie : ctx.getNodes()) - if (FileNode *node = dyn_cast(ie.get())) - node->getFile()->parse(); - - createFiles(ctx, false /* Implicit */); - - // Give target a chance to add files - createFiles(ctx, true /* Implicit */); - - // Give target a chance to postprocess input files. - // Mach-O uses this chance to move all object files before library files. - ctx.finalizeInputFiles(); - - // Do core linking. - ScopedTask resolveTask(getDefaultDomain(), "Resolve"); - Resolver resolver(ctx); - if (!resolver.resolve()) - return false; - SimpleFile *merged = nullptr; - { - std::unique_ptr mergedFile = resolver.resultFile(); - merged = mergedFile.get(); - auto &members = ctx.getNodes(); - members.insert(members.begin(), - std::make_unique(std::move(mergedFile))); - } - resolveTask.end(); - - // Run passes on linked atoms. - ScopedTask passTask(getDefaultDomain(), "Passes"); - PassManager pm; - ctx.addPasses(pm); - if (auto ec = pm.runOnFile(*merged)) { - // FIXME: This should be passed to logAllUnhandledErrors but it needs - // to be passed a Twine instead of a string. - lld::errs() << "Failed to run passes on file '" << ctx.outputPath() - << "': "; - logAllUnhandledErrors(std::move(ec), lld::errs(), std::string()); - return false; - } - - passTask.end(); - - // Give linked atoms to Writer to generate output file. - ScopedTask writeTask(getDefaultDomain(), "Write"); - if (auto ec = ctx.writeFile(*merged)) { - // FIXME: This should be passed to logAllUnhandledErrors but it needs - // to be passed a Twine instead of a string. - lld::errs() << "Failed to write file '" << ctx.outputPath() << "': "; - logAllUnhandledErrors(std::move(ec), lld::errs(), std::string()); - return false; - } - - // Call exit() if we can to avoid calling destructors. - if (CanExitEarly) - exitLld(errorCount() ? 1 : 0); - - - return true; -} - -} // end namespace mach_o -} // end namespace lld diff --git a/lld/lib/Driver/DarwinLdOptions.td b/lld/lib/Driver/DarwinLdOptions.td deleted file mode 100644 index 3bbde8bf1c1cc..0000000000000 --- a/lld/lib/Driver/DarwinLdOptions.td +++ /dev/null @@ -1,250 +0,0 @@ -include "llvm/Option/OptParser.td" - - -// output kinds -def grp_kind : OptionGroup<"outs">, HelpText<"OUTPUT KIND">; -def relocatable : Flag<["-"], "r">, - HelpText<"Create relocatable object file">, Group; -def static : Flag<["-"], "static">, - HelpText<"Create static executable">, Group; -def dynamic : Flag<["-"], "dynamic">, - HelpText<"Create dynamic executable (default)">,Group; -def dylib : Flag<["-"], "dylib">, - HelpText<"Create dynamic library">, Group; -def bundle : Flag<["-"], "bundle">, - HelpText<"Create dynamic bundle">, Group; -def execute : Flag<["-"], "execute">, - HelpText<"Create main executable (default)">, Group; -def preload : Flag<["-"], "preload">, - HelpText<"Create binary for use with embedded systems">, Group; - -// optimizations -def grp_opts : OptionGroup<"opts">, HelpText<"OPTIMIZATIONS">; -def dead_strip : Flag<["-"], "dead_strip">, - HelpText<"Remove unreference code and data">, Group; -def macosx_version_min : Separate<["-"], "macosx_version_min">, - MetaVarName<"">, - HelpText<"Minimum Mac OS X version">, Group; -def ios_version_min : Separate<["-"], "ios_version_min">, - MetaVarName<"">, - HelpText<"Minimum iOS version">, Group; -def iphoneos_version_min : Separate<["-"], "iphoneos_version_min">, - Alias; -def ios_simulator_version_min : Separate<["-"], "ios_simulator_version_min">, - MetaVarName<"">, - HelpText<"Minimum iOS simulator version">, Group; -def sdk_version : Separate<["-"], "sdk_version">, - MetaVarName<"">, - HelpText<"SDK version">, Group; -def source_version : Separate<["-"], "source_version">, - MetaVarName<"">, - HelpText<"Source version">, Group; -def version_load_command : Flag<["-"], "version_load_command">, - HelpText<"Force generation of a version load command">, Group; -def no_version_load_command : Flag<["-"], "no_version_load_command">, - HelpText<"Disable generation of a version load command">, Group; -def function_starts : Flag<["-"], "function_starts">, - HelpText<"Force generation of a function starts load command">, - Group; -def no_function_starts : Flag<["-"], "no_function_starts">, - HelpText<"Disable generation of a function starts load command">, - Group; -def data_in_code_info : Flag<["-"], "data_in_code_info">, - HelpText<"Force generation of a data in code load command">, - Group; -def no_data_in_code_info : Flag<["-"], "no_data_in_code_info">, - HelpText<"Disable generation of a data in code load command">, - Group; -def mllvm : Separate<["-"], "mllvm">, - MetaVarName<"