diff options
author | Vitaly Buka <vitalybuka@google.com> | 2025-04-23 21:13:38 -0700 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2025-04-23 21:13:38 -0700 |
commit | 954f7975df606d4ad568ea3102cb1e09baa919d5 (patch) | |
tree | 697c657421c380b3077f08987830952dce26bdb3 | |
parent | b4ae58e13bbbc62272a900cac5e1f158c437e8c1 (diff) | |
parent | cb8495c0fcf32592c6fcd23429b702dccb57d2eb (diff) | |
download | llvm-users/vitalybuka/spr/main.drivercfi-allow-cfi-with-minimal-runtime.zip llvm-users/vitalybuka/spr/main.drivercfi-allow-cfi-with-minimal-runtime.tar.gz llvm-users/vitalybuka/spr/main.drivercfi-allow-cfi-with-minimal-runtime.tar.bz2 |
[𝘀𝗽𝗿] changes introduced through rebaseusers/vitalybuka/spr/main.drivercfi-allow-cfi-with-minimal-runtime
Created using spr 1.3.4
[skip ci]
28 files changed, 507 insertions, 175 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f598ef59..7c933f4 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2232,10 +2232,15 @@ static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, // within RHS. We don't need to look at the characters of one string that // would appear before the start of the other string if they were merged. CharUnits Offset = RHS.Offset - LHS.Offset; - if (Offset.isNegative()) + if (Offset.isNegative()) { + if (LHSString.Bytes.size() < (size_t)-Offset.getQuantity()) + return false; LHSString.Bytes = LHSString.Bytes.drop_front(-Offset.getQuantity()); - else + } else { + if (RHSString.Bytes.size() < (size_t)Offset.getQuantity()) + return false; RHSString.Bytes = RHSString.Bytes.drop_front(Offset.getQuantity()); + } bool LHSIsLonger = LHSString.Bytes.size() > RHSString.Bytes.size(); StringRef Longer = LHSIsLonger ? LHSString.Bytes : RHSString.Bytes; diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 5545cbc..0f54aa5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1076,6 +1076,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setFriendConstraintRefersToEnclosingTemplate( FunctionDeclBits.getNextBit()); FD->setUsesSEHTry(FunctionDeclBits.getNextBit()); + FD->setIsDestroyingOperatorDelete(FunctionDeclBits.getNextBit()); + FD->setIsTypeAwareOperatorNewOrDelete(FunctionDeclBits.getNextBit()); FD->EndRangeLoc = readSourceLocation(); if (FD->isExplicitlyDefaulted()) diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 3a7a234..d1f92ce 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -847,6 +847,8 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { FunctionDeclBits.addBit(D->isInstantiatedFromMemberTemplate()); FunctionDeclBits.addBit(D->FriendConstraintRefersToEnclosingTemplate()); FunctionDeclBits.addBit(D->usesSEHTry()); + FunctionDeclBits.addBit(D->isDestroyingOperatorDelete()); + FunctionDeclBits.addBit(D->isTypeAwareOperatorNewOrDelete()); Record.push_back(FunctionDeclBits); Record.AddSourceLocation(D->getEndLoc()); diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp index 42e6ae3..8fb19fc 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -119,6 +119,14 @@ constexpr auto b3 = name1() == name1(); // ref-error {{must be initialized by a constexpr auto b4 = name1() == name2(); static_assert(!b4); +constexpr auto bar(const char *p) { return p + __builtin_strlen(p); } +constexpr auto b5 = bar(p1) == p1; +static_assert(!b5); +constexpr auto b6 = bar(p1) == ""; // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{comparison of addresses of potentially overlapping literals}} +constexpr auto b7 = bar(p1) + 1 == ""; // both-error {{must be initialized by a constant expression}} \ + // both-note {{comparison against pointer '&"test1"[6]' that points past the end of a complete object has unspecified value}} + namespace UninitializedFields { class A { public: diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c index 19da8ed..bb3a9d3 100644 --- a/clang/test/Driver/riscv-cpus.c +++ b/clang/test/Driver/riscv-cpus.c @@ -726,3 +726,37 @@ // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=andes-nx45 | FileCheck -check-prefix=MTUNE-ANDES-NX45 %s // MTUNE-ANDES-NX45: "-tune-cpu" "andes-nx45" + +// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=andes-a45 | FileCheck -check-prefix=MCPU-ANDES-A45 %s +// MCPU-ANDES-A45: "-target-cpu" "andes-a45" +// MCPU-ANDES-A45-SAME: "-target-feature" "+m" +// MCPU-ANDES-A45-SAME: "-target-feature" "+a" +// MCPU-ANDES-A45-SAME: "-target-feature" "+f" +// MCPU-ANDES-A45-SAME: "-target-feature" "+d" +// MCPU-ANDES-A45-SAME: "-target-feature" "+c" +// MCPU-ANDES-A45-SAME: "-target-feature" "+zicsr" +// MCPU-ANDES-A45-SAME: "-target-feature" "+zifencei" +// MCPU-ANDES-A45-SAME: "-target-feature" "+zba" +// MCPU-ANDES-A45-SAME: "-target-feature" "+zbb" +// MCPU-ANDES-A45-SAME: "-target-feature" "+zbs" +// MCPU-ANDES-A45-SAME: "-target-abi" "ilp32d" + +// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=andes-a45 | FileCheck -check-prefix=MTUNE-ANDES-A45 %s +// MTUNE-ANDES-A45: "-tune-cpu" "andes-a45" + +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=andes-ax45 | FileCheck -check-prefix=MCPU-ANDES-AX45 %s +// MCPU-ANDES-AX45: "-target-cpu" "andes-ax45" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+m" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+a" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+f" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+d" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+c" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+zicsr" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+zifencei" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+zba" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+zbb" +// MCPU-ANDES-AX45-SAME: "-target-feature" "+zbs" +// MCPU-ANDES-AX45-SAME: "-target-abi" "lp64d" + +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=andes-ax45 | FileCheck -check-prefix=MTUNE-ANDES-AX45 %s +// MTUNE-ANDES-AX45: "-tune-cpu" "andes-ax45" diff --git a/clang/test/Misc/target-invalid-cpu-note/riscv.c b/clang/test/Misc/target-invalid-cpu-note/riscv.c index cd8a8bf..f0c4173 100644 --- a/clang/test/Misc/target-invalid-cpu-note/riscv.c +++ b/clang/test/Misc/target-invalid-cpu-note/riscv.c @@ -5,7 +5,8 @@ // RUN: not %clang_cc1 -triple riscv32 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV32 // RISCV32: error: unknown target CPU 'not-a-cpu' // RISCV32-NEXT: note: valid target CPU values are: -// RISCV32-SAME: {{^}} andes-n45 +// RISCV32-SAME: {{^}} andes-a45 +// RISCV32-SAME: {{^}}, andes-n45 // RISCV32-SAME: {{^}}, generic-rv32 // RISCV32-SAME: {{^}}, rocket-rv32 // RISCV32-SAME: {{^}}, rp2350-hazard3 @@ -25,7 +26,8 @@ // RUN: not %clang_cc1 -triple riscv64 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix RISCV64 // RISCV64: error: unknown target CPU 'not-a-cpu' // RISCV64-NEXT: note: valid target CPU values are: -// RISCV64-SAME: {{^}} andes-nx45 +// RISCV64-SAME: {{^}} andes-ax45 +// RISCV64-SAME: {{^}}, andes-nx45 // RISCV64-SAME: {{^}}, generic-rv64 // RISCV64-SAME: {{^}}, mips-p8700 // RISCV64-SAME: {{^}}, rocket-rv64 @@ -54,7 +56,8 @@ // RUN: not %clang_cc1 -triple riscv32 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV32 // TUNE-RISCV32: error: unknown target CPU 'not-a-cpu' // TUNE-RISCV32-NEXT: note: valid target CPU values are: -// TUNE-RISCV32-SAME: {{^}} andes-n45 +// TUNE-RISCV32-SAME: {{^}} andes-a45 +// TUNE-RISCV32-SAME: {{^}}, andes-n45 // TUNE-RISCV32-SAME: {{^}}, generic-rv32 // TUNE-RISCV32-SAME: {{^}}, rocket-rv32 // TUNE-RISCV32-SAME: {{^}}, rp2350-hazard3 @@ -78,7 +81,8 @@ // RUN: not %clang_cc1 -triple riscv64 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV64 // TUNE-RISCV64: error: unknown target CPU 'not-a-cpu' // TUNE-RISCV64-NEXT: note: valid target CPU values are: -// TUNE-RISCV64-SAME: {{^}} andes-nx45 +// TUNE-RISCV64-SAME: {{^}} andes-ax45 +// TUNE-RISCV64-SAME: {{^}}, andes-nx45 // TUNE-RISCV64-SAME: {{^}}, generic-rv64 // TUNE-RISCV64-SAME: {{^}}, mips-p8700 // TUNE-RISCV64-SAME: {{^}}, rocket-rv64 diff --git a/clang/test/Modules/Inputs/PR137102/module.modulemap b/clang/test/Modules/Inputs/PR137102/module.modulemap new file mode 100644 index 0000000..337aff5 --- /dev/null +++ b/clang/test/Modules/Inputs/PR137102/module.modulemap @@ -0,0 +1 @@ +module type_aware_destroying_new_delete { header "type_aware_destroying_new_delete.h" export * } diff --git a/clang/test/Modules/Inputs/PR137102/type_aware_destroying_new_delete.h b/clang/test/Modules/Inputs/PR137102/type_aware_destroying_new_delete.h new file mode 100644 index 0000000..f96a9ea --- /dev/null +++ b/clang/test/Modules/Inputs/PR137102/type_aware_destroying_new_delete.h @@ -0,0 +1,52 @@ + +namespace std { + struct destroying_delete_t { }; + template <class T> struct type_identity { + using type = T; + }; + typedef __SIZE_TYPE__ size_t; + enum class align_val_t : size_t; +}; + +struct A { + A(); + void *operator new(std::size_t); + void operator delete(A*, std::destroying_delete_t); +}; + +struct B { + B(); + void *operator new(std::type_identity<B>, std::size_t, std::align_val_t); + void operator delete(std::type_identity<B>, void*, std::size_t, std::align_val_t); +}; + +struct C { + C(); + template <class T> void *operator new(std::type_identity<T>, std::size_t, std::align_val_t); + template <class T> void operator delete(std::type_identity<T>, void*, std::size_t, std::align_val_t); +}; + +struct D { + D(); +}; +void *operator new(std::type_identity<D>, std::size_t, std::align_val_t); +void operator delete(std::type_identity<D>, void*, std::size_t, std::align_val_t); + +struct E { + E(); +}; +template <class T> void *operator new(std::type_identity<T>, std::size_t, std::align_val_t); +template <class T> void operator delete(std::type_identity<T>, void*, std::size_t, std::align_val_t); + +void in_module_tests() { + A* a = new A; + delete a; + B *b = new B; + delete b; + C *c = new C; + delete c; + D *d = new D; + delete d; + E *e = new E; + delete e; +} diff --git a/clang/test/Modules/type-aware-destroying-new-and-delete-modules.cpp b/clang/test/Modules/type-aware-destroying-new-and-delete-modules.cpp new file mode 100644 index 0000000..e88f8a8 --- /dev/null +++ b/clang/test/Modules/type-aware-destroying-new-and-delete-modules.cpp @@ -0,0 +1,23 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -std=c++26 -fmodules-cache-path=%t -I %S/Inputs/PR137102 -emit-llvm-only %s +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -std=c++26 -fmodules-cache-path=%t -I %S/Inputs/PR137102 -emit-llvm-only %s -triple i686-windows + +#include "type_aware_destroying_new_delete.h" + + +static void call_in_module_function(void) { + in_module_tests(); +} + +void out_of_module_tests() { + A* a = new A; + delete a; + B *b = new B; + delete b; + C *c = new C; + delete c; + D *d = new D; + delete d; + E *e = new E; + delete e; +} diff --git a/clang/test/PCH/Inputs/type_aware_destroying_new_delete.h b/clang/test/PCH/Inputs/type_aware_destroying_new_delete.h new file mode 100644 index 0000000..42d609c0 --- /dev/null +++ b/clang/test/PCH/Inputs/type_aware_destroying_new_delete.h @@ -0,0 +1,52 @@ + +namespace std { + struct destroying_delete_t { }; + template <class T> struct type_identity { + using type = T; + }; + typedef __SIZE_TYPE__ size_t; + enum class align_val_t : size_t; +}; + +struct A { + A(); + void *operator new(std::size_t); + void operator delete(A*, std::destroying_delete_t); +}; + +struct B { + B(); + void *operator new(std::type_identity<B>, std::size_t, std::align_val_t); + void operator delete(std::type_identity<B>, void*, std::size_t, std::align_val_t); +}; + +struct C { + C(); + template <class T> void *operator new(std::type_identity<T>, std::size_t, std::align_val_t); + template <class T> void operator delete(std::type_identity<T>, void*, std::size_t, std::align_val_t); +}; + +struct D { + D(); +}; +void *operator new(std::type_identity<D>, std::size_t, std::align_val_t); +void operator delete(std::type_identity<D>, void*, std::size_t, std::align_val_t); + +struct E { + E(); +}; +template <class T> void *operator new(std::type_identity<T>, std::size_t, std::align_val_t); +template <class T> void operator delete(std::type_identity<T>, void*, std::size_t, std::align_val_t); + +void in_pch_tests() { + A* a = new A; + delete a; + B *b = new B; + delete b; + C *c = new C; + delete c; + D *d = new D; + delete d; + E *e = new E; + delete e; +} diff --git a/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp b/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp new file mode 100644 index 0000000..d8f7f5d --- /dev/null +++ b/clang/test/PCH/type-aware-destroying-new-and-delete-pch.cpp @@ -0,0 +1,27 @@ +// Test this without pch. +// RUN: %clang_cc1 -x c++ -std=c++26 -include %S/Inputs/type_aware_destroying_new_delete.h -emit-llvm -o - %s + +// Test with pch. +// RUN: %clang_cc1 -x c++ -std=c++26 -emit-pch -o %t %S/Inputs/type_aware_destroying_new_delete.h +// RUN: %clang_cc1 -x c++ -std=c++26 -include-pch %t -emit-llvm -o - %s + +// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -fpch-instantiate-templates -o %t %S/Inputs/type_aware_destroying_new_delete.h +// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -emit-llvm -o - %s + + +static void call_in_pch_function(void) { + in_pch_tests(); +} + +void out_of_pch_tests() { + A* a = new A; + delete a; + B *b = new B; + delete b; + C *c = new C; + delete c; + D *d = new D; + delete d; + E *e = new E; + delete e; +} diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 28016da..dc8f4bf1 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -2203,6 +2203,8 @@ namespace BuiltinStrlen { static_assert(__builtin_strlen("foo") == 3, ""); static_assert(__builtin_strlen("foo\0quux") == 3, ""); static_assert(__builtin_strlen("foo\0quux" + 4) == 4, ""); + static_assert(__builtin_strlen("foo") + 1 + "foo" == "foo", ""); // expected-error {{static assertion expression is not an integral constant expression}} + // expected-note@-1 {{comparison against pointer '&"foo"[4]' that points past the end of a complete object has unspecified value}} constexpr bool check(const char *p) { return __builtin_strlen(p) == 3 && diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 6f6ecc89..298b716 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -169,6 +169,7 @@ Changes to the RISC-V Backend which is also the default. * `-mcpu=xiangshan-kunminghu` was added. * `-mcpu=andes-n45` and `-mcpu=andes-nx45` were added. +* `-mcpu=andes-a45` and `-mcpu=andes-ax45` were added. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/ProfileData/IndexedMemProfData.cpp b/llvm/lib/ProfileData/IndexedMemProfData.cpp index fb4a891..5e78ffd 100644 --- a/llvm/lib/ProfileData/IndexedMemProfData.cpp +++ b/llvm/lib/ProfileData/IndexedMemProfData.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ProfileData/InstrProf.h" +#include "llvm/ProfileData/InstrProfReader.h" #include "llvm/ProfileData/MemProf.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/OnDiskHashTable.h" @@ -297,4 +298,127 @@ Error writeMemProf(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, memprof::MaximumSupportedVersion)); } +Error IndexedMemProfReader::deserializeV2(const unsigned char *Start, + const unsigned char *Ptr) { + // The value returned from RecordTableGenerator.Emit. + const uint64_t RecordTableOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + // The offset in the stream right before invoking + // FrameTableGenerator.Emit. + const uint64_t FramePayloadOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + // The value returned from FrameTableGenerator.Emit. + const uint64_t FrameTableOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + + // The offset in the stream right before invoking + // CallStackTableGenerator.Emit. + uint64_t CallStackPayloadOffset = 0; + // The value returned from CallStackTableGenerator.Emit. + uint64_t CallStackTableOffset = 0; + if (Version >= memprof::Version2) { + CallStackPayloadOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + CallStackTableOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + } + + // Read the schema. + auto SchemaOr = memprof::readMemProfSchema(Ptr); + if (!SchemaOr) + return SchemaOr.takeError(); + Schema = SchemaOr.get(); + + // Now initialize the table reader with a pointer into data buffer. + MemProfRecordTable.reset(MemProfRecordHashTable::Create( + /*Buckets=*/Start + RecordTableOffset, + /*Payload=*/Ptr, + /*Base=*/Start, memprof::RecordLookupTrait(Version, Schema))); + + // Initialize the frame table reader with the payload and bucket offsets. + MemProfFrameTable.reset(MemProfFrameHashTable::Create( + /*Buckets=*/Start + FrameTableOffset, + /*Payload=*/Start + FramePayloadOffset, + /*Base=*/Start)); + + if (Version >= memprof::Version2) + MemProfCallStackTable.reset(MemProfCallStackHashTable::Create( + /*Buckets=*/Start + CallStackTableOffset, + /*Payload=*/Start + CallStackPayloadOffset, + /*Base=*/Start)); + + return Error::success(); +} + +Error IndexedMemProfReader::deserializeV3(const unsigned char *Start, + const unsigned char *Ptr) { + // The offset in the stream right before invoking + // CallStackTableGenerator.Emit. + const uint64_t CallStackPayloadOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + // The offset in the stream right before invoking RecordTableGenerator.Emit. + const uint64_t RecordPayloadOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + // The value returned from RecordTableGenerator.Emit. + const uint64_t RecordTableOffset = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + + // Read the schema. + auto SchemaOr = memprof::readMemProfSchema(Ptr); + if (!SchemaOr) + return SchemaOr.takeError(); + Schema = SchemaOr.get(); + + FrameBase = Ptr; + CallStackBase = Start + CallStackPayloadOffset; + + // Compute the number of elements in the radix tree array. Since we use this + // to reserve enough bits in a BitVector, it's totally OK if we overestimate + // this number a little bit because of padding just before the next section. + RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) / + sizeof(memprof::LinearFrameId); + + // Now initialize the table reader with a pointer into data buffer. + MemProfRecordTable.reset(MemProfRecordHashTable::Create( + /*Buckets=*/Start + RecordTableOffset, + /*Payload=*/Start + RecordPayloadOffset, + /*Base=*/Start, memprof::RecordLookupTrait(memprof::Version3, Schema))); + + return Error::success(); +} + +Error IndexedMemProfReader::deserialize(const unsigned char *Start, + uint64_t MemProfOffset) { + const unsigned char *Ptr = Start + MemProfOffset; + + // Read the MemProf version number. + const uint64_t FirstWord = + support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); + + if (FirstWord == memprof::Version2 || FirstWord == memprof::Version3) { + // Everything is good. We can proceed to deserialize the rest. + Version = static_cast<memprof::IndexedVersion>(FirstWord); + } else { + return make_error<InstrProfError>( + instrprof_error::unsupported_version, + formatv("MemProf version {} not supported; " + "requires version between {} and {}, inclusive", + FirstWord, memprof::MinimumSupportedVersion, + memprof::MaximumSupportedVersion)); + } + + switch (Version) { + case memprof::Version2: + if (Error E = deserializeV2(Start, Ptr)) + return E; + break; + case memprof::Version3: + if (Error E = deserializeV3(Start, Ptr)) + return E; + break; + } + + return Error::success(); +} + } // namespace llvm diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index 4075b51..295f2a6 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -1230,129 +1230,6 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version, } } -Error IndexedMemProfReader::deserializeV2(const unsigned char *Start, - const unsigned char *Ptr) { - // The value returned from RecordTableGenerator.Emit. - const uint64_t RecordTableOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - // The offset in the stream right before invoking - // FrameTableGenerator.Emit. - const uint64_t FramePayloadOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - // The value returned from FrameTableGenerator.Emit. - const uint64_t FrameTableOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - - // The offset in the stream right before invoking - // CallStackTableGenerator.Emit. - uint64_t CallStackPayloadOffset = 0; - // The value returned from CallStackTableGenerator.Emit. - uint64_t CallStackTableOffset = 0; - if (Version >= memprof::Version2) { - CallStackPayloadOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - CallStackTableOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - } - - // Read the schema. - auto SchemaOr = memprof::readMemProfSchema(Ptr); - if (!SchemaOr) - return SchemaOr.takeError(); - Schema = SchemaOr.get(); - - // Now initialize the table reader with a pointer into data buffer. - MemProfRecordTable.reset(MemProfRecordHashTable::Create( - /*Buckets=*/Start + RecordTableOffset, - /*Payload=*/Ptr, - /*Base=*/Start, memprof::RecordLookupTrait(Version, Schema))); - - // Initialize the frame table reader with the payload and bucket offsets. - MemProfFrameTable.reset(MemProfFrameHashTable::Create( - /*Buckets=*/Start + FrameTableOffset, - /*Payload=*/Start + FramePayloadOffset, - /*Base=*/Start)); - - if (Version >= memprof::Version2) - MemProfCallStackTable.reset(MemProfCallStackHashTable::Create( - /*Buckets=*/Start + CallStackTableOffset, - /*Payload=*/Start + CallStackPayloadOffset, - /*Base=*/Start)); - - return Error::success(); -} - -Error IndexedMemProfReader::deserializeV3(const unsigned char *Start, - const unsigned char *Ptr) { - // The offset in the stream right before invoking - // CallStackTableGenerator.Emit. - const uint64_t CallStackPayloadOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - // The offset in the stream right before invoking RecordTableGenerator.Emit. - const uint64_t RecordPayloadOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - // The value returned from RecordTableGenerator.Emit. - const uint64_t RecordTableOffset = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - - // Read the schema. - auto SchemaOr = memprof::readMemProfSchema(Ptr); - if (!SchemaOr) - return SchemaOr.takeError(); - Schema = SchemaOr.get(); - - FrameBase = Ptr; - CallStackBase = Start + CallStackPayloadOffset; - - // Compute the number of elements in the radix tree array. Since we use this - // to reserve enough bits in a BitVector, it's totally OK if we overestimate - // this number a little bit because of padding just before the next section. - RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) / - sizeof(memprof::LinearFrameId); - - // Now initialize the table reader with a pointer into data buffer. - MemProfRecordTable.reset(MemProfRecordHashTable::Create( - /*Buckets=*/Start + RecordTableOffset, - /*Payload=*/Start + RecordPayloadOffset, - /*Base=*/Start, memprof::RecordLookupTrait(memprof::Version3, Schema))); - - return Error::success(); -} - -Error IndexedMemProfReader::deserialize(const unsigned char *Start, - uint64_t MemProfOffset) { - const unsigned char *Ptr = Start + MemProfOffset; - - // Read the MemProf version number. - const uint64_t FirstWord = - support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr); - - if (FirstWord == memprof::Version2 || FirstWord == memprof::Version3) { - // Everything is good. We can proceed to deserialize the rest. - Version = static_cast<memprof::IndexedVersion>(FirstWord); - } else { - return make_error<InstrProfError>( - instrprof_error::unsupported_version, - formatv("MemProf version {} not supported; " - "requires version between {} and {}, inclusive", - FirstWord, memprof::MinimumSupportedVersion, - memprof::MaximumSupportedVersion)); - } - - switch (Version) { - case memprof::Version2: - if (Error E = deserializeV2(Start, Ptr)) - return E; - break; - case memprof::Version3: - if (Error E = deserializeV3(Start, Ptr)) - return E; - break; - } - - return Error::success(); -} - Error IndexedInstrProfReader::readHeader() { using namespace support; diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td index 5e52ba8..1ad9422 100644 --- a/llvm/lib/Target/RISCV/RISCVProcessors.td +++ b/llvm/lib/Target/RISCV/RISCVProcessors.td @@ -651,3 +651,29 @@ def ANDES_NX45 : RISCVProcessorModel<"andes-nx45", FeatureStdExtD, FeatureStdExtC, FeatureStdExtB]>; + +def ANDES_A45 : RISCVProcessorModel<"andes-a45", + NoSchedModel, + [Feature32Bit, + FeatureStdExtI, + FeatureStdExtZicsr, + FeatureStdExtZifencei, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC, + FeatureStdExtB]>; + +def ANDES_AX45 : RISCVProcessorModel<"andes-ax45", + NoSchedModel, + [Feature64Bit, + FeatureStdExtI, + FeatureStdExtZicsr, + FeatureStdExtZifencei, + FeatureStdExtM, + FeatureStdExtA, + FeatureStdExtF, + FeatureStdExtD, + FeatureStdExtC, + FeatureStdExtB]>; diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td index 0f195ff..f53f95e 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td @@ -1332,18 +1332,21 @@ def ModuleFlagAttr Represents a single entry of llvm.module.flags metadata (llvm::Module::ModuleFlagEntry in LLVM). The first element is a behavior flag described by `ModFlagBehaviorAttr`, the second is a string ID - and third is the value of the flag (currently only integer constants - are supported). + and third is the value of the flag. Current supported types of values: + - Integer constants + - Strings Example: ```mlir #llvm.mlir.module_flag<error, "wchar_size", 4> + #llvm.mlir.module_flag<error, "probe-stack", "inline-asm"> ``` }]; let parameters = (ins "ModFlagBehavior":$behavior, "StringAttr":$key, - "uint32_t":$value); + "Attribute":$value); let assemblyFormat = "`<` $behavior `,` $key `,` $value `>`"; + let genVerifyDecl = 1; } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/GPU/CMakeLists.txt b/mlir/lib/Dialect/GPU/CMakeLists.txt index 013311e..be6492a 100644 --- a/mlir/lib/Dialect/GPU/CMakeLists.txt +++ b/mlir/lib/Dialect/GPU/CMakeLists.txt @@ -53,6 +53,7 @@ add_mlir_dialect_library(MLIRGPUTransforms LINK_LIBS PUBLIC MLIRAffineUtils + MLIRAMDGPUDialect MLIRArithDialect MLIRAsyncDialect MLIRBufferizationDialect @@ -70,6 +71,7 @@ add_mlir_dialect_library(MLIRGPUTransforms MLIRSideEffectInterfaces MLIRSPIRVTarget MLIRSupport + MLIRROCDLDialect MLIRROCDLTarget MLIRTransformUtils MLIRVectorDialect diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp index e4f9d6f..f3ebb8a 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp @@ -375,3 +375,13 @@ TargetFeaturesAttr TargetFeaturesAttr::featuresAt(Operation *op) { return parentFunction.getOperation()->getAttrOfType<TargetFeaturesAttr>( getAttributeName()); } + +LogicalResult +ModuleFlagAttr::verify(function_ref<InFlightDiagnostic()> emitError, + LLVM::ModFlagBehavior flagBehavior, StringAttr key, + Attribute value) { + if (!isa<IntegerAttr, StringAttr>(value)) + return emitError() + << "only integer and string values are currently supported"; + return success(); +} diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp index 368259b..3fee1e9 100644 --- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp +++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp @@ -151,13 +151,39 @@ static bool isSupportedCombiningKind(CombiningKind combiningKind, return false; } -AffineMap mlir::vector::getTransferMinorIdentityMap(ShapedType shapedType, - VectorType vectorType) { - int64_t elementVectorRank = 0; +/// Returns the number of dimensions of the `shapedType` that participate in the +/// vector transfer, effectively the rank of the vector dimensions within the +/// `shapedType`. This is calculated by taking the rank of the `vectorType` +/// being transferred and subtracting the rank of the `shapedType`'s element +/// type if it's also a vector. +/// +/// This is used to determine the number of minor dimensions for identity maps +/// in vector transfers. +/// +/// For example, given a transfer operation involving `shapedType` and +/// `vectorType`: +/// +/// - shapedType = tensor<10x20xf32>, vectorType = vector<2x4xf32> +/// - shapedType.getElementType() = f32 (rank 0) +/// - vectorType.getRank() = 2 +/// - Result = 2 - 0 = 2 +/// +/// - shapedType = tensor<10xvector<20xf32>>, vectorType = vector<20xf32> +/// - shapedType.getElementType() = vector<20xf32> (rank 1) +/// - vectorType.getRank() = 1 +/// - Result = 1 - 1 = 0 +static unsigned getRealVectorRank(ShapedType shapedType, + VectorType vectorType) { + unsigned elementVectorRank = 0; VectorType elementVectorType = llvm::dyn_cast<VectorType>(shapedType.getElementType()); if (elementVectorType) elementVectorRank += elementVectorType.getRank(); + return vectorType.getRank() - elementVectorRank; +} + +AffineMap mlir::vector::getTransferMinorIdentityMap(ShapedType shapedType, + VectorType vectorType) { // 0-d transfers are to/from tensor<t>/memref<t> and vector<1xt>. // TODO: replace once we have 0-d vectors. if (shapedType.getRank() == 0 && @@ -166,7 +192,7 @@ AffineMap mlir::vector::getTransferMinorIdentityMap(ShapedType shapedType, /*numDims=*/0, /*numSymbols=*/0, getAffineConstantExpr(0, shapedType.getContext())); return AffineMap::getMinorIdentityMap( - shapedType.getRank(), vectorType.getRank() - elementVectorRank, + shapedType.getRank(), getRealVectorRank(shapedType, vectorType), shapedType.getContext()); } @@ -4234,6 +4260,10 @@ ParseResult TransferReadOp::parse(OpAsmParser &parser, OperationState &result) { Attribute permMapAttr = result.attributes.get(permMapAttrName); AffineMap permMap; if (!permMapAttr) { + if (shapedType.getRank() < getRealVectorRank(shapedType, vectorType)) + return parser.emitError(typesLoc, + "expected a custom permutation_map when " + "rank(source) != rank(destination)"); permMap = getTransferMinorIdentityMap(shapedType, vectorType); result.attributes.set(permMapAttrName, AffineMapAttr::get(permMap)); } else { @@ -4649,6 +4679,10 @@ ParseResult TransferWriteOp::parse(OpAsmParser &parser, auto permMapAttr = result.attributes.get(permMapAttrName); AffineMap permMap; if (!permMapAttr) { + if (shapedType.getRank() < getRealVectorRank(shapedType, vectorType)) + return parser.emitError(typesLoc, + "expected a custom permutation_map when " + "rank(source) != rank(destination)"); permMap = getTransferMinorIdentityMap(shapedType, vectorType); result.attributes.set(permMapAttrName, AffineMapAttr::get(permMap)); } else { diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp index 7038b5d..e816a3e 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp @@ -16,6 +16,7 @@ #include "mlir/Support/LLVM.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" +#include "llvm/ADT/TypeSwitch.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/MDBuilder.h" @@ -273,10 +274,25 @@ static void convertLinkerOptionsOp(ArrayAttr options, static void convertModuleFlagsOp(ArrayAttr flags, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { llvm::Module *llvmModule = moduleTranslation.getLLVMModule(); - for (auto flagAttr : flags.getAsRange<ModuleFlagAttr>()) + for (auto flagAttr : flags.getAsRange<ModuleFlagAttr>()) { + llvm::Metadata *valueMetadata = + llvm::TypeSwitch<Attribute, llvm::Metadata *>(flagAttr.getValue()) + .Case<StringAttr>([&](auto strAttr) { + return llvm::MDString::get(builder.getContext(), + strAttr.getValue()); + }) + .Case<IntegerAttr>([&](auto intAttr) { + return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + llvm::Type::getInt32Ty(builder.getContext()), + intAttr.getInt())); + }) + .Default([](auto) { return nullptr; }); + + assert(valueMetadata && "expected valid metadata"); llvmModule->addModuleFlag( convertModFlagBehaviorToLLVM(flagAttr.getBehavior()), - flagAttr.getKey().getValue(), flagAttr.getValue()); + flagAttr.getKey().getValue(), valueMetadata); + } } static LogicalResult diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index df7c8d6..3f80002 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -525,18 +525,20 @@ LogicalResult ModuleImport::convertModuleFlagsMetadata() { SmallVector<Attribute> moduleFlags; for (const auto [behavior, key, val] : llvmModuleFlags) { - // Currently only supports most common: int constant values. - auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val); - if (!constInt) { + Attribute valAttr = nullptr; + if (auto *constInt = llvm::mdconst::dyn_extract<llvm::ConstantInt>(val)) { + valAttr = builder.getI32IntegerAttr(constInt->getZExtValue()); + } else if (auto *mdString = dyn_cast<llvm::MDString>(val)) { + valAttr = builder.getStringAttr(mdString->getString()); + } else { emitWarning(mlirModule.getLoc()) - << "unsupported module flag value: " << diagMD(val, llvmModule.get()) - << ", only constant integer currently supported"; + << "unsupported module flag value: " << diagMD(val, llvmModule.get()); continue; } moduleFlags.push_back(builder.getAttr<ModuleFlagAttr>( convertModFlagBehaviorFromLLVM(behavior), - builder.getStringAttr(key->getString()), constInt->getZExtValue())); + builder.getStringAttr(key->getString()), valAttr)); } if (!moduleFlags.empty()) diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir index 0cd6b1f..a3cd957 100644 --- a/mlir/test/Dialect/LLVMIR/invalid.mlir +++ b/mlir/test/Dialect/LLVMIR/invalid.mlir @@ -1776,9 +1776,10 @@ llvm.mlir.alias external @y5 : i32 { // ----- module { - // expected-error@+2 {{expected integer value}} - // expected-error@+1 {{failed to parse ModuleFlagAttr parameter 'value' which is to be a `uint32_t`}} - llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", "yolo">] + llvm.func @foo() + + // expected-error@below {{only integer and string values are currently supported}} + llvm.module_flags [#llvm.mlir.module_flag<error, "yolo", @foo>] } // ----- diff --git a/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir b/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir index d99a93c..a94514d 100644 --- a/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir +++ b/mlir/test/Dialect/LLVMIR/module-roundtrip.mlir @@ -1,16 +1,18 @@ // RUN: mlir-opt %s | mlir-opt | FileCheck %s module { - llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4>, - #llvm.mlir.module_flag<min, "PIC Level", 2>, - #llvm.mlir.module_flag<max, "PIE Level", 2>, - #llvm.mlir.module_flag<max, "uwtable", 2>, - #llvm.mlir.module_flag<max, "frame-pointer", 1>] + llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4 : i32>, + #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>, + #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>, + #llvm.mlir.module_flag<max, "uwtable", 2 : i32>, + #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>, + #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">] } // CHECK: llvm.module_flags [ -// CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4>, -// CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2>, -// CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2>, -// CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2>, -// CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1>] +// CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4 : i32>, +// CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>, +// CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>, +// CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2 : i32>, +// CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>, +// CHECK-SAME: #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">] diff --git a/mlir/test/Dialect/Vector/invalid.mlir b/mlir/test/Dialect/Vector/invalid.mlir index 3a83209..19096f0 100644 --- a/mlir/test/Dialect/Vector/invalid.mlir +++ b/mlir/test/Dialect/Vector/invalid.mlir @@ -525,6 +525,15 @@ func.func @test_vector.transfer_read(%arg0: memref<?x?xvector<2x3xf32>>) { // ----- +func.func @test_vector.transfer_read(%arg1: memref<?xindex>) -> vector<3x4xindex> { + %c3 = arith.constant 3 : index + // expected-error@+1 {{expected a custom permutation_map when rank(source) != rank(destination)}} + %0 = vector.transfer_read %arg1[%c3, %c3], %c3 : memref<?xindex>, vector<3x4xindex> + return %0 : vector<3x4xindex> +} + +// ----- + func.func @test_vector.transfer_write(%arg0: memref<?x?xf32>) { %c3 = arith.constant 3 : index %cst = arith.constant 3.0 : f32 @@ -646,6 +655,14 @@ func.func @test_vector.transfer_write(%arg0: memref<?xf32>, %arg1: vector<7xf32> // ----- +func.func @test_vector.transfer_write(%vec_to_write: vector<3x4xindex>, %output_memref: memref<?xindex>) { + %c3 = arith.constant 3 : index + // expected-error@+1 {{expected a custom permutation_map when rank(source) != rank(destination)}} + vector.transfer_write %vec_to_write, %output_memref[%c3, %c3] : vector<3x4xindex>, memref<?xindex> +} + +// ----- + func.func @insert_strided_slice(%a: vector<4x4xf32>, %b: vector<4x8x16xf32>) { // expected-error@+1 {{expected offsets of same size as destination vector rank}} %1 = vector.insert_strided_slice %a, %b {offsets = [100], strides = [1, 1]} : vector<4x4xf32> into vector<4x8x16xf32> diff --git a/mlir/test/Target/LLVMIR/Import/module-flags.ll b/mlir/test/Target/LLVMIR/Import/module-flags.ll index b7b686f..e6bb2c0 100644 --- a/mlir/test/Target/LLVMIR/Import/module-flags.ll +++ b/mlir/test/Target/LLVMIR/Import/module-flags.ll @@ -1,25 +1,27 @@ ; RUN: mlir-translate -import-llvm -split-input-file -verify-diagnostics %s | FileCheck %s -!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.module.flags = !{!0, !1, !2, !3, !4, !5} !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 8, !"PIC Level", i32 2} !2 = !{i32 7, !"PIE Level", i32 2} !3 = !{i32 7, !"uwtable", i32 2} !4 = !{i32 7, !"frame-pointer", i32 1} +!5 = !{i32 4, !"probe-stack", !"inline-asm"} ; CHECK-LABEL: module attributes {{.*}} { ; CHECK: llvm.module_flags [ -; CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4>, -; CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2>, -; CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2>, -; CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2>, -; CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1>] -; CHECK: } +; CHECK-SAME: #llvm.mlir.module_flag<error, "wchar_size", 4 : i32>, +; CHECK-SAME: #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>, +; CHECK-SAME: #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>, +; CHECK-SAME: #llvm.mlir.module_flag<max, "uwtable", 2 : i32>, +; CHECK-SAME: #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>, +; CHECK-SAME: #llvm.mlir.module_flag<override, "probe-stack", "inline-asm">] ; // ----- - -!llvm.module.flags = !{!0} - -; expected-warning@-5{{unsupported module flag value: !"yolo_more", only constant integer currently supported}} -!0 = !{i32 1, !"yolo", !"yolo_more"} +; expected-warning@-2 {{unsupported module flag value: !4 = !{!"foo", i32 1}}} +!10 = !{ i32 1, !"foo", i32 1 } +!11 = !{ i32 4, !"bar", i32 37 } +!12 = !{ i32 2, !"qux", i32 42 } +!13 = !{ i32 3, !"qux", !{ !"foo", i32 1 }} +!llvm.module.flags = !{ !10, !11, !12, !13 } diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index 3cf08db..74fa327 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -2809,11 +2809,11 @@ llvm.func @call_intrin_with_opbundle(%arg0 : !llvm.ptr) { // ----- module { - llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4>, - #llvm.mlir.module_flag<min, "PIC Level", 2>, - #llvm.mlir.module_flag<max, "PIE Level", 2>, - #llvm.mlir.module_flag<max, "uwtable", 2>, - #llvm.mlir.module_flag<max, "frame-pointer", 1>] + llvm.module_flags [#llvm.mlir.module_flag<error, "wchar_size", 4 : i32>, + #llvm.mlir.module_flag<min, "PIC Level", 2 : i32>, + #llvm.mlir.module_flag<max, "PIE Level", 2 : i32>, + #llvm.mlir.module_flag<max, "uwtable", 2 : i32>, + #llvm.mlir.module_flag<max, "frame-pointer", 1 : i32>] } // CHECK: !llvm.module.flags = !{![[#WCHAR:]], ![[#PIC:]], ![[#PIE:]], ![[#UWTABLE:]], ![[#FrameP:]], ![[#DBG:]]} @@ -2830,7 +2830,7 @@ module { // Verifies that the debug info version is not added twice, if it's already present initially. module { - llvm.module_flags [#llvm.mlir.module_flag<warning, "Debug Info Version", 3>] + llvm.module_flags [#llvm.mlir.module_flag<warning, "Debug Info Version", 3 : i32>] } // CHECK: !llvm.module.flags = !{![[#DBG:]]} diff --git a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel index b07c6f9..95fb5fb 100644 --- a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel @@ -698,6 +698,8 @@ cc_library( deps = [ "//llvm:NVPTXCodeGen", "//llvm:Support", + "//mlir:AMDGPUDialect", + "//mlir:AMDGPUUtils", "//mlir:AffineDialect", "//mlir:AffineToStandard", "//mlir:ArithDialect", @@ -721,6 +723,7 @@ cc_library( "//mlir:NVVMToLLVM", "//mlir:NVVMToLLVMIRTranslation", "//mlir:Pass", + "//mlir:ROCDLDialect", "//mlir:ROCDLToLLVMIRTranslation", "//mlir:ReconcileUnrealizedCasts", "//mlir:SCFDialect", |