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_not...@linaro.org wrote: > > After llvm commit 6398903ac8c141820a84f3063b7956abe1742500 > Author: Momchil Velikov <momchil.veli...@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-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/build-6398903ac8c141820a84f3063b7956abe1742500/save-temps/ > - Last_good save-temps: > https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/build-48f188433335846bba4cf3e5e9fa2150d4c0253b/save-temps/ > - Baseline save-temps: > https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/build-baseline/save-temps/ > > 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-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/build-6398903ac8c141820a84f3063b7956abe1742500/ > Last_good build: > https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/build-48f188433335846bba4cf3e5e9fa2150d4c0253b/ > Baseline build: > https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/build-baseline/ > Even more details: > https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/ > > 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-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/manifests/build-baseline.sh > --fail > curl -o artifacts/manifests/build-parameters.sh > https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/manifests/build-parameters.sh > --fail > curl -o artifacts/test.sh > https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-aarch64-spec2k6-Oz_LTO/13/artifact/artifacts/test.sh > --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.veli...@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", > - "uwtable", > "zeroext", > "cold", > "nocf_check", > 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> _______________________________________________ linaro-toolchain mailing list -- linaro-toolchain@lists.linaro.org To unsubscribe send an email to linaro-toolchain-le...@lists.linaro.org