Hi Momchil,
Your patch seems to significantly increase code-size of several benchmarks — by up to 9%. Would you please investigate whether this can be avoided?
Please let us know if you need assistance with reproducing the regressions.
Thank you,
-- Maxim Kuvyrkov https://www.linaro.org
On 25 Mar 2022, at 14:45, ci_notify@linaro.org wrote:
After llvm commit 6398903ac8c141820a84f3063b7956abe1742500 Author: Momchil Velikov momchil.velikov@arm.com
Extend the `uwtable` attribute with unwind table kind
the following benchmarks grew in size by more than 1%:
- 456.hmmer grew in size by 9% from 104960 to 113912 bytes
- 403.gcc grew in size by 9% from 2191632 to 2394404 bytes
- 400.perlbench grew in size by 9% from 803690 to 879478 bytes
- 458.sjeng grew in size by 5% from 102355 to 107719 bytes
- 401.bzip2 grew in size by 3% from 43428 to 44772 bytes
Below reproducer instructions can be used to re-build both "first_bad" and "last_good" cross-toolchains used in this bisection. Naturally, the scripts will fail when triggerring benchmarking jobs if you don't have access to Linaro TCWG CI.
For your convenience, we have uploaded tarballs with pre-processed source and assembly files at:
- First_bad save-temps: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a...
- Last_good save-temps: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a...
- Baseline save-temps: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a...
Configuration:
- Benchmark: SPEC CPU2006
- Toolchain: Clang + Glibc + LLVM Linker
- Version: all components were built from their tip of trunk
- Target: aarch64-linux-gnu
- Compiler flags: -Oz -flto
- Hardware: APM Mustang 8x X-Gene1
This benchmarking CI is work-in-progress, and we welcome feedback and suggestions at linaro-toolchain@lists.linaro.org . In our improvement plans is to add support for SPEC CPU2017 benchmarks and provide "perf report/annotate" data behind these reports.
THIS IS THE END OF INTERESTING STUFF. BELOW ARE LINKS TO BUILDS, REPRODUCTION INSTRUCTIONS, AND THE RAW COMMIT.
This commit has regressed these CI configurations:
- tcwg_bmk_llvm_apm/llvm-master-aarch64-spec2k6-Oz_LTO
First_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a... Last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a... Baseline build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a... Even more details: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a...
Reproduce builds:
<cut> mkdir investigate-llvm-6398903ac8c141820a84f3063b7956abe1742500 cd investigate-llvm-6398903ac8c141820a84f3063b7956abe1742500
# Fetch scripts git clone https://git.linaro.org/toolchain/jenkins-scripts
# Fetch manifests and test.sh script mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a... --fail curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a... --fail curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-a... --fail chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh) mkdir -p ./bisect rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /llvm/ ./ ./bisect/baseline/
cd llvm
# Reproduce first_bad build git checkout --detach 6398903ac8c141820a84f3063b7956abe1742500 ../artifacts/test.sh
# Reproduce last_good build git checkout --detach 48f188433335846bba4cf3e5e9fa2150d4c0253b ../artifacts/test.sh
cd ..
</cut>
Full commit (up to 1000 lines):
<cut> commit 6398903ac8c141820a84f3063b7956abe1742500 Author: Momchil Velikov <momchil.velikov@arm.com> Date: Mon Feb 14 13:41:34 2022 +0000
Extend the `uwtable` attribute with unwind table kind
We have the `clang -cc1` command-line option `-funwind-tables=1|2` and the codegen option `VALUE_CODEGENOPT(UnwindTables, 2, 0) ///< Unwind tables (1) or asynchronous unwind tables (2)`. However, this is encoded in LLVM IR by the presence or the absence of the `uwtable` attribute, i.e. we lose the information whether to generate want just some unwind tables or asynchronous unwind tables.
Asynchronous unwind tables take more space in the runtime image, I'd estimate something like 80-90% more, as the difference is adding roughly the same number of CFI directives as for prologues, only a bit simpler (e.g. `.cfi_offset reg, off` vs. `.cfi_restore reg`). Or even more, if you consider tail duplication of epilogue blocks. Asynchronous unwind tables could also restrict code generation to having only a finite number of frame pointer adjustments (an example of *not* having a finite number of `SP` adjustments is on AArch64 when untagging the stack (MTE) in some cases the compiler can modify `SP` in a loop). Having the CFI precise up to an instruction generally also means one cannot bundle together CFI instructions once the prologue is done, they need to be interspersed with ordinary instructions, which means extra `DW_CFA_advance_loc` commands, further increasing the unwind tables size.
That is to say, async unwind tables impose a non-negligible overhead, yet for the most common use cases (like C++ exceptions), they are not even needed.
This patch extends the `uwtable` attribute with an optional value: - `uwtable` (default to `async`) - `uwtable(sync)`, synchronous unwind tables - `uwtable(async)`, asynchronous (instruction precise) unwind tables
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D114543
clang/lib/CodeGen/CGExpr.cpp | 2 +- clang/lib/CodeGen/CodeGenModule.cpp | 4 +- clang/test/CodeGen/asan-globals.cpp | 2 +- clang/test/CodeGen/uwtable-attr.c | 30 +++++ llvm/bindings/go/llvm/ir_test.go | 1 - llvm/docs/LangRef.rst | 12 +- llvm/include/llvm/AsmParser/LLParser.h | 1 + llvm/include/llvm/AsmParser/LLToken.h | 2 + llvm/include/llvm/IR/Attributes.h | 13 +++ llvm/include/llvm/IR/Attributes.td | 2 +- llvm/include/llvm/IR/Function.h | 12 +- llvm/include/llvm/IR/Module.h | 4 +- llvm/include/llvm/Support/CodeGen.h | 8 +- llvm/lib/AsmParser/LLLexer.cpp | 2 + llvm/lib/AsmParser/LLParser.cpp | 23 ++++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 4 + llvm/lib/CodeGen/MachineOutliner.cpp | 9 ++ llvm/lib/IR/AttributeImpl.h | 1 + llvm/lib/IR/Attributes.cpp | 50 ++++++++ llvm/lib/IR/Function.cpp | 5 +- llvm/lib/IR/Module.cpp | 11 +- llvm/test/Assembler/uwtable-1.ll | 7 ++ llvm/test/Assembler/uwtable-2.ll | 4 + llvm/test/Bitcode/attributes.ll | 11 ++ llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll | 4 +- llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll | 5 +- .../AddressSanitizer/module-flags.ll | 2 +- .../Attributor/ArgumentPromotion/X86/attributes.ll | 34 +++--- .../X86/min-legal-vector-width.ll | 128 ++++++++++----------- llvm/test/Transforms/Attributor/align.ll | 48 ++++---- llvm/test/Transforms/Attributor/allow_list.ll | 4 +- .../Transforms/Attributor/cb_liveness_disabled.ll | 4 +- .../Transforms/Attributor/cb_liveness_enabled.ll | 4 +- .../test/Transforms/Attributor/internal-noalias.ll | 28 ++--- llvm/test/Transforms/Attributor/liveness.ll | 12 +- llvm/test/Transforms/Attributor/nocapture-2.ll | 48 ++++---- llvm/test/Transforms/Attributor/nofree.ll | 38 +++--- llvm/test/Transforms/Attributor/noreturn.ll | 12 +- llvm/test/Transforms/Attributor/nosync.ll | 28 ++--- llvm/test/Transforms/Attributor/returned.ll | 48 ++++---- .../Attributor/value-simplify-pointer-info.ll | 14 +-- llvm/test/Transforms/Attributor/willreturn.ll | 56 ++++----- llvm/test/Transforms/FunctionAttrs/atomic.ll | 4 +- .../Transforms/FunctionAttrs/nofree-attributor.ll | 2 +- llvm/test/Transforms/FunctionAttrs/nofree.ll | 2 +- llvm/test/Transforms/FunctionAttrs/nosync.ll | 16 +-- llvm/test/Transforms/GCOVProfiling/module-flags.ll | 2 +- .../Inputs/check_attrs.ll.funcattrs.expected | 2 +- llvm/unittests/IR/VerifierTest.cpp | 3 +- 49 files changed, 473 insertions(+), 295 deletions(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index fa45554bb54f..e0e1dd5df586 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3188,7 +3188,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF, B.addAttribute(llvm::Attribute::NoReturn) .addAttribute(llvm::Attribute::NoUnwind); }
- B.addAttribute(llvm::Attribute::UWTable);
B.addUWTableAttr(llvm::UWTableKind::Default);
llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction( FnType, FnName,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 772059a436d1..c99fd899ac93 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -828,7 +828,7 @@ void CodeGenModule::Release() { if (CodeGenOpts.NoPLT) getModule().setRtLibUseGOT(); if (CodeGenOpts.UnwindTables)
- getModule().setUwtable();
getModule().setUwtable(llvm::UWTableKind(CodeGenOpts.UnwindTables));
switch (CodeGenOpts.getFramePointer()) { case CodeGenOptions::FramePointerKind::None:
@@ -1839,7 +1839,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::AttrBuilder B(F->getContext());
if (CodeGenOpts.UnwindTables)
- B.addAttribute(llvm::Attribute::UWTable);
B.addUWTableAttr(llvm::UWTableKind(CodeGenOpts.UnwindTables));
if (CodeGenOpts.StackClashProtector) B.addAttribute("probe-stack", "inline-asm");
diff --git a/clang/test/CodeGen/asan-globals.cpp b/clang/test/CodeGen/asan-globals.cpp index a77060b124e9..2cea167d0ea5 100644 --- a/clang/test/CodeGen/asan-globals.cpp +++ b/clang/test/CodeGen/asan-globals.cpp @@ -48,7 +48,7 @@ void func() { // RUN: %clang_cc1 -emit-llvm -fsanitize=address -funwind-tables=2 -o - %s | FileCheck %s --check-prefixes=UWTABLE // UWTABLE: define internal void @asan.module_dtor() #[[#ATTR:]] { // UWTABLE: attributes #[[#ATTR]] = { nounwind uwtable } -// UWTABLE: ![[#]] = !{i32 7, !"uwtable", i32 1} +// UWTABLE: ![[#]] = !{i32 7, !"uwtable", i32 2}
// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]} // CHECK: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false} diff --git a/clang/test/CodeGen/uwtable-attr.c b/clang/test/CodeGen/uwtable-attr.c new file mode 100644 index 000000000000..7436db979b6b --- /dev/null +++ b/clang/test/CodeGen/uwtable-attr.c @@ -0,0 +1,30 @@ +// Test that function and modules attributes react on the command-line options, +// it does not state the current behaviour makes sense in all cases (it does not).
+// RUN: %clang -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,DEFAULT +// RUN: %clang -S -emit-llvm -o - %s -funwind-tables -fno-asynchronous-unwind-tables | FileCheck %s -check-prefixes=CHECK,TABLES +// RUN: %clang -S -emit-llvm -o - %s -fno-unwind-tables -fno-asynchronous-unwind-tables | FileCheck %s -check-prefixes=CHECK,NO_TABLES
+// RUN: %clang -S -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefixes=CHECK,DEFAULT +// RUN: %clang -S -emit-llvm -o - -x c++ %s -funwind-tables -fno-asynchronous-unwind-tables | FileCheck %s -check-prefixes=CHECK,TABLES +// RUN: %clang -S -emit-llvm -o - -x c++ %s -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables | FileCheck %s -check-prefixes=CHECK,NO_TABLES
+#ifdef __cplusplus +extern "C" void g(void); +struct S { ~S(); }; +extern "C" int f() { S s; g(); return 0;}; +#else +void g(void); +int f() { g(); return 0; }; +#endif
+// CHECK: define {{.*}} @f() #[[#F:]] +// CHECK: declare {{.*}} @g() #[[#]]
+// DEFAULT: attributes #[[#F]] = { {{.*}} uwtable{{ }}{{.*}} } +// DEFAULT: ![[#]] = !{i32 7, !"uwtable", i32 2}
+// TABLES: attributes #[[#F]] = { {{.*}} uwtable(sync){{.*}} } +// TABLES: ![[#]] = !{i32 7, !"uwtable", i32 1}
+// NO_TABLES-NOT: uwtable diff --git a/llvm/bindings/go/llvm/ir_test.go b/llvm/bindings/go/llvm/ir_test.go index 71c47d94a0ec..61b482f2ef9a 100644 --- a/llvm/bindings/go/llvm/ir_test.go +++ b/llvm/bindings/go/llvm/ir_test.go @@ -83,7 +83,6 @@ func TestAttributes(t *testing.T) { "sspstrong", "sanitize_thread", "sanitize_memory",
"zeroext", "cold", "nocf_check","uwtable",
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 6b44b7e7355c..1a212c661597 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -2108,12 +2108,15 @@ example: function with a tail call. The prototype of a thunk should not be used for optimization purposes. The caller is expected to cast the thunk prototype to match the thunk target prototype. -``uwtable`` +``uwtable[(sync|async)]`` This attribute indicates that the ABI being targeted requires that an unwind table entry be produced for this function even if we can show that no exceptions passes by it. This is normally the case for the ELF x86-64 abi, but it can be disabled for some compilation
- units.
- units. The optional parameter describes what kind of unwind tables
- to generate: ``sync`` for normal unwind tables, ``async`` for asynchronous
- (instruction precise) unwind tables. Without the parameter, the attribute
- ``uwtable`` is equivalent to ``uwtable(async)``.
``nocf_check`` This attribute indicates that no control-flow check will be performed on the attributed entity. It disables -fcf-protection=<> for a specific @@ -7215,8 +7218,9 @@ functions is small.
- "frame-pointer": **Max**. The value can be 0, 1, or 2. A synthesized function will get the "frame-pointer" function attribute, with value being "none", "non-leaf", or "all", respectively.
-- "uwtable": **Max**. The value can be 0 or 1. If the value is 1, a synthesized
- function will get the ``uwtable`` function attribute.
+- "uwtable": **Max**. The value can be 0, 1, or 2. If the value is 1, a synthesized
- function will get the ``uwtable(sync)`` function attribute, if the value is 2,
- a synthesized function will get the ``uwtable(async)`` function attribute.
Objective-C Garbage Collection Module Flags Metadata
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h index 62af3afbc142..b2f7b9ebb721 100644 --- a/llvm/include/llvm/AsmParser/LLParser.h +++ b/llvm/include/llvm/AsmParser/LLParser.h @@ -263,6 +263,7 @@ namespace llvm { bool parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens = false); bool parseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes);
- bool parseOptionalUWTableKind(UWTableKind &Kind); bool parseScopeAndOrdering(bool IsAtomic, SyncScope::ID &SSID, AtomicOrdering &Ordering); bool parseScope(SyncScope::ID &SSID);
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index 78ebb35e0ea4..faac67ebbab9 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -252,6 +252,8 @@ enum Kind { kw_immarg, kw_byref, kw_mustprogress,
kw_sync,
kw_async,
kw_type, kw_opaque,
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index 74b60f1e3d05..61819b1a07fa 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -22,6 +22,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Alignment.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <bitset> #include <cassert> @@ -130,6 +131,7 @@ public: static Attribute getWithByRefType(LLVMContext &Context, Type *Ty); static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty); static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty);
static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind);
/// For a typed attribute, return the equivalent attribute with the type /// changed to \p ReplacementTy.
@@ -223,6 +225,9 @@ public: /// unknown. Optional<unsigned> getVScaleRangeMax() const;
- // Returns the unwind table kind.
- UWTableKind getUWTableKind() const;
- /// The Attribute is converted to a string of equivalent mnemonic. This /// is, presumably, for writing out the mnemonics for the assembly writer. std::string getAsString(bool InAttrGrp = false) const;
@@ -353,6 +358,7 @@ public: std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; unsigned getVScaleRangeMin() const; Optional<unsigned> getVScaleRangeMax() const;
UWTableKind getUWTableKind() const; std::string getAsString(bool InAttrGrp = false) const;
/// Return true if this attribute set belongs to the LLVMContext.
@@ -841,6 +847,9 @@ public: /// arg. uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const;
- /// Get the unwind table kind requested for the function.
- UWTableKind getUWTableKind() const;
- /// Return the attributes at the index as a string. std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
@@ -1190,6 +1199,10 @@ public: /// Attribute.getIntValue(). AttrBuilder &addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr);
/// This turns the unwind table kind into the form used internally in
/// Attribute.
AttrBuilder &addUWTableAttr(UWTableKind Kind);
ArrayRef<Attribute> attrs() const { return Attrs; }
bool operator==(const AttrBuilder &B) const;
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index a03e5441827c..d7a79f90e05e 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -273,7 +273,7 @@ def SwiftSelf : EnumAttr<"swiftself", [ParamAttr]>; def SwiftAsync : EnumAttr<"swiftasync", [ParamAttr]>;
/// Function must be in a unwind table. -def UWTable : EnumAttr<"uwtable", [FnAttr]>; +def UWTable : IntAttr<"uwtable", [FnAttr]>;
/// Minimum/Maximum vscale value for function. def VScaleRange : IntAttr<"vscale_range", [FnAttr]>; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index 90095cd1bc77..1b9843e08b28 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -623,15 +623,19 @@ public: bool willReturn() const { return hasFnAttribute(Attribute::WillReturn); } void setWillReturn() { addFnAttr(Attribute::WillReturn); }
- /// Get what kind of unwind table entry to generate for this function.
- UWTableKind getUWTableKind() const {
- return AttributeSets.getUWTableKind();
- }
- /// True if the ABI mandates (or the user requested) that this /// function be in a unwind table. bool hasUWTable() const {
- return hasFnAttribute(Attribute::UWTable);
- return getUWTableKind() != UWTableKind::None; }
- void setHasUWTable() {
- addFnAttr(Attribute::UWTable);
- void setUWTableKind(UWTableKind K) {
- addFnAttr(Attribute::getWithUWTableKind(getContext(), K)); }
- /// True if this function needs an unwind table. bool needsUnwindTableEntry() const { return hasUWTable() || !doesNotThrow() || hasPersonalityFn();
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 9385ecab83d2..0414adfaee4d 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -888,8 +888,8 @@ public: void setRtLibUseGOT();
/// Get/set whether synthesized functions should get the uwtable attribute.
- bool getUwtable() const;
- void setUwtable();
UWTableKind getUwtable() const;
void setUwtable(UWTableKind Kind);
/// Get/set whether synthesized functions should get the "frame-pointer" /// attribute.
diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h index ef5cc5d19fc5..71d0ddbfe05e 100644 --- a/llvm/include/llvm/Support/CodeGen.h +++ b/llvm/include/llvm/Support/CodeGen.h @@ -97,6 +97,12 @@ namespace llvm { }; } // namespace ZeroCallUsedRegs
-} // end llvm namespace
- enum class UWTableKind {
- None = 0, ///< No unwind table requested
- Sync = 1, ///< "Synchronous" unwind tables
- Async = 2, ///< "Asynchronous" unwind tables (instr precise)
- Default = 2,
- };
- } // namespace llvm
#endif diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index e3bf41c9721b..a508660edfa5 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -708,6 +708,8 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(immarg); KEYWORD(byref); KEYWORD(mustprogress);
KEYWORD(sync);
KEYWORD(async);
KEYWORD(type); KEYWORD(opaque);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 4281193caf85..769601c7e633 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1333,6 +1333,13 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B, B.addDereferenceableOrNullAttr(Bytes); return false; }
- case Attribute::UWTable: {
- UWTableKind Kind;
- if (parseOptionalUWTableKind(Kind))
return true;
- B.addUWTableAttr(Kind);
- return false;
- } default: B.addAttribute(Attr); Lex.Lex();
@@ -1996,6 +2003,22 @@ bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind, return false; }
+bool LLParser::parseOptionalUWTableKind(UWTableKind &Kind) {
- Lex.Lex();
- Kind = UWTableKind::Default;
- if (!EatIfPresent(lltok::lparen))
- return false;
- LocTy KindLoc = Lex.getLoc();
- if (Lex.getKind() == lltok::kw_sync)
- Kind = UWTableKind::Sync;
- else if (Lex.getKind() == lltok::kw_async)
- Kind = UWTableKind::Async;
- else
- return error(KindLoc, "expected unwind table kind");
- Lex.Lex();
- return parseToken(lltok::rparen, "expected ')'");
+}
/// parseOptionalCommaAlign /// ::= /// ::= ',' align 4 diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 3d4b1f64b11c..5f6d980708a5 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1628,6 +1628,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addStructRetAttr(nullptr); else if (Kind == Attribute::InAlloca) B.addInAllocaAttr(nullptr);
else if (Kind == Attribute::UWTable)
B.addUWTableAttr(UWTableKind::Default); else if (Attribute::isEnumAttrKind(Kind)) B.addAttribute(Kind); else
@@ -1650,6 +1652,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { B.addAllocSizeAttrFromRawRepr(Record[++i]); else if (Kind == Attribute::VScaleRange) B.addVScaleRangeAttrFromRawRepr(Record[++i]);
else if (Kind == Attribute::UWTable)
B.addUWTableAttr(UWTableKind(Record[++i])); } else if (Record[i] == 3 || Record[i] == 4) { // String attribute bool HasValue = (Record[i++] == 4); SmallString<64> KindStr;
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index 7783b5e0d3cc..d7d098278d2a 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -623,6 +623,15 @@ MachineFunction *MachineOutliner::createOutlinedFunction(
TII.mergeOutliningCandidateAttributes(*F, OF.Candidates);
- // Set uwtable, so we generate eh_frame.
- UWTableKind UW = std::accumulate(
OF.Candidates.cbegin(), OF.Candidates.cend(), UWTableKind::None,
[](UWTableKind K, const outliner::Candidate &C) {
return std::max(K, C.getMF()->getFunction().getUWTableKind());
});
- if (UW != UWTableKind::None)
- F->setUWTableKind(UW);
- BasicBlock *EntryBB = BasicBlock::Create(C, "entry", F); IRBuilder<> Builder(EntryBB); Builder.CreateRetVoid();
diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h index 1153fb827b56..adf8a4d34a0a 100644 --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -255,6 +255,7 @@ public: std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; unsigned getVScaleRangeMin() const; Optional<unsigned> getVScaleRangeMax() const;
- UWTableKind getUWTableKind() const; std::string getAsString(bool InAttrGrp) const; Type *getAttributeType(Attribute::AttrKind Kind) const;
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 43fde64c3734..5751b99a2807 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -205,6 +205,11 @@ Attribute Attribute::getWithInAllocaType(LLVMContext &Context, Type *Ty) { return get(Context, InAlloca, Ty); }
+Attribute Attribute::getWithUWTableKind(LLVMContext &Context,
UWTableKind Kind) {
- return get(Context, UWTable, uint64_t(Kind));
+}
Attribute Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const Optional<unsigned> &NumElemsArg) { @@ -366,6 +371,12 @@ Optional<unsigned> Attribute::getVScaleRangeMax() const { return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second; }
+UWTableKind Attribute::getUWTableKind() const {
- assert(hasAttribute(Attribute::UWTable) &&
"Trying to get unwind table kind from non-uwtable attribute");
- return UWTableKind(pImpl->getValueAsInt());
+}
std::string Attribute::getAsString(bool InAttrGrp) const { if (!pImpl) return {};
@@ -426,6 +437,25 @@ std::string Attribute::getAsString(bool InAttrGrp) const { .str(); }
- if (hasAttribute(Attribute::UWTable)) {
- UWTableKind Kind = getUWTableKind();
- if (Kind != UWTableKind::None) {
return Kind == UWTableKind::Default
? "uwtable"
: ("uwtable(" +
Twine(Kind == UWTableKind::Sync ? "sync" : "async") + ")")
.str();
- }
- if (Kind != UWTableKind::None) {
if (Kind == UWTableKind::Default)
return "uwtable";
return ("uwtable(" + Twine(Kind == UWTableKind::Sync ? "sync" : "async") +
")")
.str();
- }
- }
- // Convert target-dependent attributes to strings of the form: // // "kind"
@@ -710,6 +740,10 @@ Optional<unsigned> AttributeSet::getVScaleRangeMax() const { return SetNode ? SetNode->getVScaleRangeMax() : None; }
+UWTableKind AttributeSet::getUWTableKind() const {
- return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
+}
std::string AttributeSet::getAsString(bool InAttrGrp) const { return SetNode ? SetNode->getAsString(InAttrGrp) : ""; } @@ -876,6 +910,12 @@ Optional<unsigned> AttributeSetNode::getVScaleRangeMax() const { return None; }
+UWTableKind AttributeSetNode::getUWTableKind() const {
- if (auto A = findEnumAttribute(Attribute::UWTable))
- return A->getUWTableKind();
- return UWTableKind::None;
+}
std::string AttributeSetNode::getAsString(bool InAttrGrp) const { std::string Str; for (iterator I = begin(), E = end(); I != E; ++I) { @@ -1428,6 +1468,10 @@ AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const { return getParamAttrs(Index).getDereferenceableOrNullBytes(); }
+UWTableKind AttributeList::getUWTableKind() const {
- return getFnAttrs().getUWTableKind();
+}
std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const { return getAttributes(Index).getAsString(InAttrGrp); } @@ -1649,6 +1693,12 @@ AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) { return addRawIntAttr(Attribute::VScaleRange, RawArgs); }
+AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) {
- if (Kind == UWTableKind::None)
- return *this;
- return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
+}
Type *AttrBuilder::getTypeAttr(Attribute::AttrKind Kind) const { assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute"); Attribute A = getAttribute(Kind); diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 726ba80da41b..6ae3d0b4dcb9 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -339,8 +339,9 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty, Module *M) { auto *F = new Function(Ty, Linkage, AddrSpace, N, M); AttrBuilder B(F->getContext());
- if (M->getUwtable())
- B.addAttribute(Attribute::UWTable);
- UWTableKind UWTable = M->getUwtable();
- if (UWTable != UWTableKind::None)
- B.addUWTableAttr(UWTable); switch (M->getFramePointer()) { case FramePointerKind::None: // 0 ("none") is the default.
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 6156edd99790..b66a99ba17b0 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -671,12 +671,15 @@ void Module::setRtLibUseGOT() { addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1); }
-bool Module::getUwtable() const {
- auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable"));
- return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0);
+UWTableKind Module::getUwtable() const {
- if (auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable")))
- return UWTableKind(cast<ConstantInt>(Val->getValue())->getZExtValue());
- return UWTableKind::None;
}
-void Module::setUwtable() { addModuleFlag(ModFlagBehavior::Max, "uwtable", 1); } +void Module::setUwtable(UWTableKind Kind) {
- addModuleFlag(ModFlagBehavior::Max, "uwtable", uint32_t(Kind));
+}
FramePointerKind Module::getFramePointer() const { auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("frame-pointer")); diff --git a/llvm/test/Assembler/uwtable-1.ll b/llvm/test/Assembler/uwtable-1.ll new file mode 100644 index 000000000000..2e9e3f0cab6d --- /dev/null +++ b/llvm/test/Assembler/uwtable-1.ll @@ -0,0 +1,7 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+declare void @f0() uwtable +declare void @f1() uwtable(sync) +declare void @f2() uwtable(async) +declare void @f3() uwtable(unsync) +; CHECK: :[[#@LINE-1]]:28: error: expected unwind table kind diff --git a/llvm/test/Assembler/uwtable-2.ll b/llvm/test/Assembler/uwtable-2.ll new file mode 100644 index 000000000000..c04228dbf157 --- /dev/null +++ b/llvm/test/Assembler/uwtable-2.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+declare void @f() uwtable(sync x +; CHECK: :[[#@LINE-1]]:32: error: expected ')' diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index b2b92bb6e12d..5d3828d2762d 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -516,6 +516,16 @@ define void @f83(<4 x i8*> align 32 %0, <vscale x 1 x double*> align 64 %1) { ret void }
+; CHECK: define void @f84() #51 +define void @f84() uwtable(sync) {
ret void;
+}
+; CHECK: define void @f85() #15 +define void @f85() uwtable(async) {
ret void;
+}
; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } @@ -567,4 +577,5 @@ define void @f83(<4 x i8*> align 32 %0, <vscale x 1 x double*> align 64 %1) { ; CHECK: attributes #48 = { nosanitize_coverage } ; CHECK: attributes #49 = { noprofile } ; CHECK: attributes #50 = { disable_sanitizer_instrumentation } +; CHECK: attributes #51 = { uwtable(sync) } ; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin } diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll index af761a4c37ec..84983411e86c 100644 --- a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll +++ b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll @@ -137,7 +137,9 @@ attributes #0 = { minsize nofree norecurse nounwind optsize uwtable} ; UNWIND-NEXT: 0xB0 ; finish
; UNWIND-LABEL: FunctionAddress: 0x40 -; UNWIND: Model: CantUnwind +; UNWIND: Opcodes [ +; UNWIND-NEXT: 0xB0 ; finish
; UNWINND-LABEL: 00000041 {{.*}} OUTLINED_FUNCTION_0 ; UNWINND-LABEL: 00000001 {{.*}} x diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll index 9251e1b4ddf6..edbae593ee84 100644 --- a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll +++ b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll @@ -154,8 +154,9 @@ attributes #0 = { minsize noinline norecurse nounwind optsize readnone uwtable } ; UNWIND-NEXT: 0xAA ; pop {r4, r5, r6, lr}
; UNWIND-LABEL: FunctionAddress: 0x5C -; UNWIND: Model: CantUnwind
+; UNWIND: 0xB4 ; pop ra_auth_code +; UNWIND: 0x84 0x00 ; pop {lr}
; UNWIND-LABEL: 0000005d {{.*}} OUTLINED_FUNCTION_0 ; UNWIND-LABEL: 00000005 {{.*}} f ; UNWIND-LABEL: 00000031 {{.*}} g diff --git a/llvm/test/Instrumentation/AddressSanitizer/module-flags.ll b/llvm/test/Instrumentation/AddressSanitizer/module-flags.ll index ca3c6f3051f1..c046592890b4 100644 --- a/llvm/test/Instrumentation/AddressSanitizer/module-flags.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/module-flags.ll @@ -13,7 +13,7 @@ entry: !llvm.module.flags = !{!0, !1}
;; Due to -fasynchronous-unwind-tables. -!0 = !{i32 7, !"uwtable", i32 1} +!0 = !{i32 7, !"uwtable", i32 2}
;; Due to -fno-omit-frame-pointer. !1 = !{i32 7, !"frame-pointer", i32 2} diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll index b077dd388780..90437f5876d7 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll @@ -9,7 +9,7 @@ target triple = "x86_64-unknown-linux-gnu"
define internal fastcc void @no_promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@no_promote_avx2 ; IS________OPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] { ; IS________OPM-NEXT: bb: @@ -17,7 +17,7 @@ define internal fastcc void @no_promote_avx2(<4 x i64>* %arg, <4 x i64>* readonl ; IS________OPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 ; IS________OPM-NEXT: ret void ; -; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@no_promote_avx2 ; IS________NPM-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] { ; IS________NPM-NEXT: bb: @@ -32,7 +32,7 @@ bb: }
define void @no_promote(<4 x i64>* %arg) #1 { -; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind uwtable willreturn +; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@no_promote ; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: bb: @@ -45,7 +45,7 @@ define void @no_promote(<4 x i64>* %arg) #1 { ; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind uwtable willreturn +; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote ; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: bb: @@ -58,7 +58,7 @@ define void @no_promote(<4 x i64>* %arg) #1 { ; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind uwtable willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@no_promote ; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: bb: @@ -71,7 +71,7 @@ define void @no_promote(<4 x i64>* %arg) #1 { ; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind uwtable willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@no_promote ; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: bb: @@ -96,7 +96,7 @@ bb: }
define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly %arg1) #0 { -; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@promote_avx2 ; IS________OPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]]) #[[ATTR0]] { ; IS________OPM-NEXT: bb: @@ -104,7 +104,7 @@ define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly % ; IS________OPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 ; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote_avx2 ; IS__TUNIT_NPM-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) #[[ATTR0]] { ; IS__TUNIT_NPM-NEXT: bb: @@ -114,7 +114,7 @@ define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>* readonly % ; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@promote_avx2 ; IS__CGSCC_NPM-SAME: (<4 x i64>* noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]]) #[[ATTR0]] { ; IS__CGSCC_NPM-NEXT: bb: @@ -131,7 +131,7 @@ bb: }
define void @promote(<4 x i64>* %arg) #0 { -; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@promote ; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] { ; IS__TUNIT_OPM-NEXT: bb: @@ -144,7 +144,7 @@ define void @promote(<4 x i64>* %arg) #0 { ; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote ; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] { ; IS__TUNIT_NPM-NEXT: bb: @@ -158,7 +158,7 @@ define void @promote(<4 x i64>* %arg) #0 { ; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@promote ; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR0]] { ; IS__CGSCC_OPM-NEXT: bb: @@ -171,7 +171,7 @@ define void @promote(<4 x i64>* %arg) #0 { ; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@promote ; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(32) [[ARG:%.*]]) #[[ATTR0]] { ; IS__CGSCC_NPM-NEXT: bb: @@ -203,14 +203,14 @@ attributes #0 = { inlinehint norecurse nounwind uwtable "target-features"="+avx2 attributes #1 = { nounwind uwtable } attributes #2 = { argmemonly nounwind } ;. -; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn "target-features"="+avx2" } -; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind uwtable willreturn } +; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" } +; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn uwtable } ; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } ; IS__TUNIT____: attributes #[[ATTR3:[0-9]+]] = { willreturn writeonly } ; IS__TUNIT____: attributes #[[ATTR4:[0-9]+]] = { nofree nosync nounwind willreturn } ;. -; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn "target-features"="+avx2" } -; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind uwtable willreturn } +; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable "target-features"="+avx2" } +; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn uwtable } ; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { nosync nounwind willreturn } diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll index a7bcf1e42252..7a2b796cb321 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll @@ -11,7 +11,7 @@ target triple = "x86_64-unknown-linux-gnu" ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #0 { ; -; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] { ; IS________OPM-NEXT: bb: @@ -19,7 +19,7 @@ define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal5 ; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 ; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: bb: @@ -29,7 +29,7 @@ define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal5 ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__CGSCC_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: bb: @@ -47,7 +47,7 @@ bb:
define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* %arg) #0 { ; -; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] { ; IS__TUNIT_OPM-NEXT: bb: @@ -60,7 +60,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR0]] { ; IS__TUNIT_NPM-NEXT: bb: @@ -74,7 +74,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR0]] { ; IS__CGSCC_OPM-NEXT: bb: @@ -87,7 +87,7 @@ define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>* ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR0]] { ; IS__CGSCC_NPM-NEXT: bb: @@ -115,7 +115,7 @@ bb: ; This should promote define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 { ; -; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS________OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS________OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree noundef nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]]) #[[ATTR1:[0-9]+]] { ; IS________OPM-NEXT: bb: @@ -123,7 +123,7 @@ define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal5 ; IS________OPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 ; IS________OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: bb: @@ -133,7 +133,7 @@ define internal fastcc void @callee_avx512_legal512_prefer256_call_avx512_legal5 ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* noalias nocapture nofree noundef nonnull writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: bb: @@ -151,7 +151,7 @@ bb:
define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* %arg) #1 { ; -; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] { ; IS__TUNIT_OPM-NEXT: bb: @@ -164,7 +164,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* ; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_OPM-NEXT: ret void ; -; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__TUNIT_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree writeonly [[ARG:%.*]]) #[[ATTR1]] { ; IS__TUNIT_NPM-NEXT: bb: @@ -178,7 +178,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* ; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__TUNIT_NPM-NEXT: ret void ; -; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_OPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR1]] { ; IS__CGSCC_OPM-NEXT: bb: @@ -191,7 +191,7 @@ define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>* ; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2 ; IS__CGSCC_OPM-NEXT: ret void ; -; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind uwtable willreturn +; IS__CGSCC_NPM: Function Attrs: argmemonly inlinehint nofree norecurse nosync nounwind willreturn uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256 ; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nofree noundef nonnull writeonly align 2 dereferenceable(64) [[ARG:%.*]]) #[[ATTR1]] { ; IS__CGSCC_NPM-NEXT: bb: @@ -219,7 +219,7 @@ bb: ; This should promote define internal fastcc void @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>* %arg, <8 x i64>* readonly %arg1) #1 {
</cut>