https://github.com/jroelofs updated https://github.com/llvm/llvm-project/pull/84704
>From b352a41e1788819afbb15a5b6d79cbf2968dc5dc Mon Sep 17 00:00:00 2001 From: Jon Roelofs <jonathan_roel...@apple.com> Date: Sun, 10 Mar 2024 16:46:50 -0700 Subject: [PATCH 1/3] [CodeGen][AArch64][FMV] PAC the stub_helper's frame on arm64e --- clang/lib/CodeGen/CodeGenModule.cpp | 18 ++++-- .../test/CodeGen/attr-target-version-arm64e.c | 58 +++++++++++++++++++ llvm/include/llvm/CodeGen/AsmPrinter.h | 13 +++-- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 3 +- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 45 ++++++++++++++ llvm/test/CodeGen/AArch64/ifunc-asm.ll | 21 +++++-- 6 files changed, 142 insertions(+), 16 deletions(-) create mode 100644 clang/test/CodeGen/attr-target-version-arm64e.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 967319bdfc457..dadc76d04c5f6 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4365,13 +4365,16 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // For cpu_specific, don't create an ifunc yet because we don't know if the // cpu_dispatch will be emitted in this translation unit. if (getTarget().supportsIFunc() && !FD->isCPUSpecificMultiVersion()) { - llvm::Type *ResolverType = llvm::FunctionType::get( + llvm::FunctionType *ResolverType = llvm::FunctionType::get( llvm::PointerType::get(DeclTy, getTypes().getTargetAddressSpace(FD->getType())), false); - llvm::Constant *Resolver = GetOrCreateLLVMFunction( - MangledName + ".resolver", ResolverType, GlobalDecl{}, - /*ForVTable=*/false); + llvm::Function *Resolver = cast<llvm::Function>( + CreateRuntimeFunction(ResolverType, MangledName + ".resolver") + .getCallee()); + llvm::AttrBuilder Attrs(getLLVMContext()); + addDefaultFunctionDefinitionAttributes(Attrs); + Resolver->addFnAttrs(Attrs); llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create(DeclTy, 0, getMultiversionLinkage(*this, GD), "", Resolver, &getModule()); @@ -4381,8 +4384,11 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { return GIF; } - llvm::Constant *Resolver = GetOrCreateLLVMFunction( - ResolverName, DeclTy, GlobalDecl{}, /*ForVTable=*/false); + llvm::Function *Resolver = cast<llvm::Function>( + CreateRuntimeFunction(DeclTy, ResolverName).getCallee()); + llvm::AttrBuilder Attrs(getLLVMContext()); + addDefaultFunctionDefinitionAttributes(Attrs); + Resolver->addFnAttrs(Attrs); assert(isa<llvm::GlobalValue>(Resolver) && "Resolver should be created for the first time"); SetCommonAttributes(FD, cast<llvm::GlobalValue>(Resolver)); diff --git a/clang/test/CodeGen/attr-target-version-arm64e.c b/clang/test/CodeGen/attr-target-version-arm64e.c new file mode 100644 index 0000000000000..2deff9a688daa --- /dev/null +++ b/clang/test/CodeGen/attr-target-version-arm64e.c @@ -0,0 +1,58 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs +// RUN: %clang_cc1 -triple arm64e-apple-ios -target-feature +ls64 -target-feature +fullfp16 -S -emit-llvm -o - %s | FileCheck %s + +int __attribute__((target_version("sha1"))) fmv(void) { return 1; } +int __attribute__((target_version("default"))) fmv(void) { return 0; } +int foo() { + return fmv(); +} + +//. +// CHECK: @__aarch64_cpu_features = external dso_local global { i64 } +// CHECK: @fmv.ifunc = weak_odr alias i32 (), ptr @fmv +// CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver +//. +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Msha1 +// CHECK-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 1 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@foo +// CHECK-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv() +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK-LABEL: define {{[^@]+}}@fmv.resolver +// CHECK-SAME: () #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2048 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2048 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @fmv._Msha1 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv.default +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv.default +// CHECK-SAME: () #[[ATTR1]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +//. +// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" } +// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR2]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } +//. +// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} +//. diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index a7fbf4aeb7449..3b7e9c282120f 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -603,16 +603,21 @@ class AsmPrinter : public MachineFunctionPass { return nullptr; } + virtual const MCExpr * + emitMachOIfuncLazyPointerInit(const MCSymbolRefExpr *Init) { + return Init; + } + virtual void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) { - llvm_unreachable( - "Mach-O IFunc lowering is not yet supported on this target"); + assert(false && + "Mach-O IFunc lowering is not yet supported on this target"); } virtual void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) { - llvm_unreachable( - "Mach-O IFunc lowering is not yet supported on this target"); + assert(false && + "Mach-O IFunc lowering is not yet supported on this target"); } /// Emit N NOP instructions. diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 0efe7a0e73367..b70221cdec296 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2259,7 +2259,8 @@ void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) { emitAlignment(Align(DL.getPointerSize())); OutStreamer->emitLabel(LazyPointer); emitVisibility(LazyPointer, GI.getVisibility()); - OutStreamer->emitValue(MCSymbolRefExpr::create(StubHelper, OutContext), 8); + const MCSymbolRefExpr *Init = MCSymbolRefExpr::create(StubHelper, OutContext); + OutStreamer->emitValue(emitMachOIfuncLazyPointerInit(Init), 8); OutStreamer->switchSection(OutContext.getObjectFileInfo()->getTextSection()); diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 4fa719ad67cf3..f191fe3259d27 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -208,6 +208,8 @@ class AArch64AsmPrinter : public AsmPrinter { assert(STI); return STI; } + const MCExpr * + emitMachOIfuncLazyPointerInit(const MCSymbolRefExpr *Init) override; void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) override; void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI, @@ -1897,6 +1899,15 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); } +const MCExpr * +AArch64AsmPrinter::emitMachOIfuncLazyPointerInit(const MCSymbolRefExpr *Init) { + if (TM.getTargetTriple().isArm64e()) + return AArch64AuthMCExpr::create(Init, /*Disc=*/0, AArch64PACKey::IA, + /*HasAddressDiversity=*/false, OutContext); + + return Init; +} + void AArch64AsmPrinter::emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) { // _ifunc: @@ -1980,6 +1991,9 @@ void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(Module &M, // ldp fp, lr, [sp], #16 // br x16 + if (TM.getTargetTriple().isArm64e()) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::PACIBSP), *STI); + OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXpre) .addReg(AArch64::SP) .addReg(AArch64::FP) @@ -2085,6 +2099,37 @@ void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(Module &M, .addImm(2), *STI); + if (TM.getTargetTriple().isArm64e()) { + // autibsp + // eor x17, lr, lr, lsl #1 + // tbz x17, #62, Lgoodsig + // brk #0xc741 + // Lgoodsig: + + OutStreamer->emitInstruction(MCInstBuilder(AArch64::AUTIBSP), *STI); + + OutStreamer->emitInstruction(MCInstBuilder(AArch64::EORXrs) + .addReg(AArch64::X17) + .addReg(AArch64::LR) + .addReg(AArch64::LR) + .addImm(1), + *STI); + + MCContext &Ctx = OutStreamer->getContext(); + MCSymbol *GoodSigSym = Ctx.createTempSymbol(); + const MCExpr *GoodSig = MCSymbolRefExpr::create(GoodSigSym, Ctx); + OutStreamer->emitInstruction(MCInstBuilder(AArch64::TBZX) + .addReg(AArch64::X17) + .addImm(62) + .addExpr(GoodSig), + *STI); + + OutStreamer->emitInstruction(MCInstBuilder(AArch64::BRK).addImm(0xc471), + *STI); + + OutStreamer->emitLabel(GoodSigSym); + } + OutStreamer->emitInstruction(MCInstBuilder(TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ : AArch64::BR) diff --git a/llvm/test/CodeGen/AArch64/ifunc-asm.ll b/llvm/test/CodeGen/AArch64/ifunc-asm.ll index 57fc2f0c9d7f5..6f0d6f633fd51 100644 --- a/llvm/test/CodeGen/AArch64/ifunc-asm.ll +++ b/llvm/test/CodeGen/AArch64/ifunc-asm.ll @@ -1,6 +1,8 @@ ; RUN: llc -mtriple=arm64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=ELF -; RUN: llc -mtriple=arm64-apple-darwin %s -o - | FileCheck %s --check-prefix=MACHO -; RUN: llc -mtriple=arm64-apple-darwin %s -global-isel -o - | FileCheck %s --check-prefix=MACHO +; RUN: llc -mtriple=arm64-apple-darwin %s -o - | FileCheck %s --check-prefixes=MACHO,ARM64 +; RUN: llc -mtriple=arm64-apple-darwin %s -global-isel -o - | FileCheck %s --check-prefixes=MACHO,ARM64 +; RUN: llc -mtriple=arm64e-apple-darwin %s -o - | FileCheck %s --check-prefixes=MACHO,PAUTH +; RUN: llc -mtriple=arm64e-apple-darwin %s -global-isel -o - | FileCheck %s --check-prefixes=MACHO,PAUTH define internal ptr @the_resolver() { entry: @@ -21,7 +23,8 @@ entry: ; MACHO: .section __DATA,__data ; MACHO-NEXT: .p2align 3, 0x0 ; MACHO-NEXT: _global_ifunc.lazy_pointer: -; MACHO-NEXT: .quad _global_ifunc.stub_helper +; ARM64-NEXT: .quad _global_ifunc.stub_helper{{$}} +; PAUTH-NEXT: .quad _global_ifunc.stub_helper@AUTH(ia,0) ; MACHO: .section __TEXT,__text,regular,pure_instructions ; MACHO-NEXT: .globl _global_ifunc @@ -30,9 +33,11 @@ entry: ; MACHO-NEXT: adrp x16, _global_ifunc.lazy_pointer@GOTPAGE ; MACHO-NEXT: ldr x16, [x16, _global_ifunc.lazy_pointer@GOTPAGEOFF] ; MACHO-NEXT: ldr x16, [x16] -; MACHO-NEXT: br x16 +; ARM64-NEXT: br x16 +; PAUTH-NEXT: braaz x16 ; MACHO-NEXT: .p2align 2 ; MACHO-NEXT: _global_ifunc.stub_helper: +; PAUTH-NEXT: pacibsp ; MACHO-NEXT: stp x29, x30, [sp, #-16]! ; MACHO-NEXT: mov x29, sp ; MACHO-NEXT: stp x1, x0, [sp, #-16]! @@ -57,7 +62,13 @@ entry: ; MACHO-NEXT: ldp x3, x2, [sp], #16 ; MACHO-NEXT: ldp x1, x0, [sp], #16 ; MACHO-NEXT: ldp x29, x30, [sp], #16 -; MACHO-NEXT: br x16 +; PAUTH-NEXT: autibsp +; PAUTH-NEXT: eor x17, x30, x30, lsl #1 +; PAUTH-NEXT: tbz x17, #62, [[GOOD_SIG:Ltmp[0-9]+]] +; PAUTH-NEXT: brk #0xc471 +; PAUTH-NEXT: [[GOOD_SIG]]: +; ARM64-NEXT: br x16 +; PAUTH-NEXT: braaz x16 @weak_ifunc = weak ifunc i32 (i32), ptr @the_resolver >From 73aa83448691d3e6af07025572eaf5abef4b4469 Mon Sep 17 00:00:00 2001 From: Jon Roelofs <jonathan_roel...@apple.com> Date: Sun, 10 Mar 2024 16:46:50 -0700 Subject: [PATCH 2/3] fixup tests --- clang/test/CodeGen/attr-cpuspecific.c | 24 +++++----- clang/test/CodeGen/attr-target-clones.c | 46 +++++++++---------- clang/test/CodeGen/attr-target-mv-va-args.c | 6 +-- clang/test/CodeGen/attr-target-mv.c | 18 ++++---- clang/test/CodeGen/attr-target-version.c | 23 ++++++---- clang/test/CodeGenCXX/attr-cpuspecific.cpp | 2 +- clang/test/CodeGenCXX/attr-target-clones.cpp | 4 +- .../CodeGenCXX/attr-target-mv-diff-ns.cpp | 4 +- .../attr-target-mv-member-funcs.cpp | 2 +- .../attr-target-mv-out-of-line-defs.cpp | 2 +- .../CodeGenCXX/attr-target-mv-overloads.cpp | 4 +- 11 files changed, 71 insertions(+), 64 deletions(-) diff --git a/clang/test/CodeGen/attr-cpuspecific.c b/clang/test/CodeGen/attr-cpuspecific.c index 2c3e6931800cd..7fe14bec68d9d 100644 --- a/clang/test/CodeGen/attr-cpuspecific.c +++ b/clang/test/CodeGen/attr-cpuspecific.c @@ -51,7 +51,7 @@ void SingleVersion(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @SingleVersion() comdat +// WINDOWS: define weak_odr dso_local void @SingleVersion() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: %[[FEAT_INIT:.+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4 // WINDOWS: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 525311 @@ -82,7 +82,7 @@ void TwoVersions(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @TwoVersions() comdat +// WINDOWS: define weak_odr dso_local void @TwoVersions() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: %[[FEAT_INIT:.+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4 // WINDOWS: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 59754495 @@ -125,7 +125,7 @@ void OrderDispatchUsageSpecific(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @OrderDispatchUsageSpecific() comdat +// WINDOWS: define weak_odr dso_local void @OrderDispatchUsageSpecific() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call void @OrderDispatchUsageSpecific.Z() // WINDOWS-NEXT: ret void @@ -174,7 +174,7 @@ void TwoVersionsSameAttr(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @TwoVersionsSameAttr() comdat +// WINDOWS: define weak_odr dso_local void @TwoVersionsSameAttr() {{.*}} comdat // WINDOWS: call void @TwoVersionsSameAttr.Z // WINDOWS-NEXT: ret void // WINDOWS: call void @TwoVersionsSameAttr.S @@ -194,7 +194,7 @@ void ThreeVersionsSameAttr(void){} // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @ThreeVersionsSameAttr() comdat +// WINDOWS: define weak_odr dso_local void @ThreeVersionsSameAttr() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @ThreeVersionsSameAttr.Z // WINDOWS-NEXT: ret void @@ -210,7 +210,7 @@ void OrderSpecificUsageDispatch(void); // LINUX: define weak_odr ptr @OrderSpecificUsageDispatch.resolver() // LINUX: ret ptr @OrderSpecificUsageDispatch.Z -// WINDOWS: define weak_odr dso_local void @OrderSpecificUsageDispatch() comdat +// WINDOWS: define weak_odr dso_local void @OrderSpecificUsageDispatch() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @OrderSpecificUsageDispatch.Z // WINDOWS-NEXT: ret void @@ -226,7 +226,7 @@ void NoSpecifics(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @NoSpecifics() comdat +// WINDOWS: define weak_odr dso_local void @NoSpecifics() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @NoSpecifics.Z // WINDOWS-NEXT: ret void @@ -247,7 +247,7 @@ void HasGeneric(void); // LINUX: ret ptr @HasGeneric.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local void @HasGeneric() comdat +// WINDOWS: define weak_odr dso_local void @HasGeneric() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @HasGeneric.Z // WINDOWS-NEXT: ret void @@ -269,7 +269,7 @@ void HasParams(int i, double d); // LINUX: ret ptr @HasParams.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local void @HasParams(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local void @HasParams(i32 %0, double %1) {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @HasParams.Z(i32 %0, double %1) // WINDOWS-NEXT: ret void @@ -291,7 +291,7 @@ int HasParamsAndReturn(int i, double d); // LINUX: ret ptr @HasParamsAndReturn.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local i32 @HasParamsAndReturn(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local i32 @HasParamsAndReturn(i32 %0, double %1) {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: %[[RET:.+]] = musttail call i32 @HasParamsAndReturn.Z(i32 %0, double %1) // WINDOWS-NEXT: ret i32 %[[RET]] @@ -312,7 +312,7 @@ int GenericAndPentium(int i, double d); // LINUX-NOT: ret ptr @GenericAndPentium.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local i32 @GenericAndPentium(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local i32 @GenericAndPentium(i32 %0, double %1) {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: %[[RET:.+]] = musttail call i32 @GenericAndPentium.O(i32 %0, double %1) // WINDOWS-NEXT: ret i32 %[[RET]] @@ -327,7 +327,7 @@ int DispatchFirst(void); // LINUX: ret ptr @DispatchFirst.O // LINUX: ret ptr @DispatchFirst.B -// WINDOWS: define weak_odr dso_local i32 @DispatchFirst() comdat +// WINDOWS: define weak_odr dso_local i32 @DispatchFirst() {{.*}} comdat // WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.O() // WINDOWS-NEXT: ret i32 %[[RET]] // WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.B() diff --git a/clang/test/CodeGen/attr-target-clones.c b/clang/test/CodeGen/attr-target-clones.c index 3256db061f9a2..730321e185fba 100644 --- a/clang/test/CodeGen/attr-target-clones.c +++ b/clang/test/CodeGen/attr-target-clones.c @@ -44,45 +44,45 @@ static int __attribute__((target_clones("sse4.2, default"))) internal(void) { return 0; } int use(void) { return internal(); } /// Internal linkage resolvers do not use comdat. -// LINUX: define internal ptr @internal.resolver() { -// DARWIN: define internal ptr @internal.resolver() { -// WINDOWS: define internal i32 @internal() { +// LINUX: define internal ptr @internal.resolver() +// DARWIN: define internal ptr @internal.resolver() +// WINDOWS: define internal i32 @internal() int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; } // LINUX: define {{.*}}i32 @foo.sse4.2.0() // LINUX: define {{.*}}i32 @foo.default.1() -// LINUX: define weak_odr ptr @foo.resolver() comdat +// LINUX: define weak_odr ptr @foo.resolver() {{.*}} comdat // LINUX: ret ptr @foo.sse4.2.0 // LINUX: ret ptr @foo.default.1 // DARWIN: define {{.*}}i32 @foo.sse4.2.0() // DARWIN: define {{.*}}i32 @foo.default.1() -// DARWIN: define weak_odr ptr @foo.resolver() { +// DARWIN: define weak_odr ptr @foo.resolver() // DARWIN: ret ptr @foo.sse4.2.0 // DARWIN: ret ptr @foo.default.1 // WINDOWS: define dso_local i32 @foo.sse4.2.0() // WINDOWS: define dso_local i32 @foo.default.1() -// WINDOWS: define weak_odr dso_local i32 @foo() comdat +// WINDOWS: define weak_odr dso_local i32 @foo() {{.*}} comdat // WINDOWS: musttail call i32 @foo.sse4.2.0 // WINDOWS: musttail call i32 @foo.default.1 __attribute__((target_clones("default,default ,sse4.2"))) void foo_dupes(void) {} // LINUX: define {{.*}}void @foo_dupes.default.1() // LINUX: define {{.*}}void @foo_dupes.sse4.2.0() -// LINUX: define weak_odr ptr @foo_dupes.resolver() comdat +// LINUX: define weak_odr ptr @foo_dupes.resolver() {{.*}} comdat // LINUX: ret ptr @foo_dupes.sse4.2.0 // LINUX: ret ptr @foo_dupes.default.1 // DARWIN: define {{.*}}void @foo_dupes.default.1() // DARWIN: define {{.*}}void @foo_dupes.sse4.2.0() -// DARWIN: define weak_odr ptr @foo_dupes.resolver() { +// DARWIN: define weak_odr ptr @foo_dupes.resolver() // DARWIN: ret ptr @foo_dupes.sse4.2.0 // DARWIN: ret ptr @foo_dupes.default.1 // WINDOWS: define dso_local void @foo_dupes.default.1() // WINDOWS: define dso_local void @foo_dupes.sse4.2.0() -// WINDOWS: define weak_odr dso_local void @foo_dupes() comdat +// WINDOWS: define weak_odr dso_local void @foo_dupes() {{.*}} comdat // WINDOWS: musttail call void @foo_dupes.sse4.2.0 // WINDOWS: musttail call void @foo_dupes.default.1 @@ -109,19 +109,19 @@ int bar(void) { void __attribute__((target_clones("default, arch=ivybridge"))) unused(void) {} // LINUX: define {{.*}}void @unused.default.1() // LINUX: define {{.*}}void @unused.arch_ivybridge.0() -// LINUX: define weak_odr ptr @unused.resolver() comdat +// LINUX: define weak_odr ptr @unused.resolver() {{.*}} comdat // LINUX: ret ptr @unused.arch_ivybridge.0 // LINUX: ret ptr @unused.default.1 // DARWIN: define {{.*}}void @unused.default.1() // DARWIN: define {{.*}}void @unused.arch_ivybridge.0() -// DARWIN: define weak_odr ptr @unused.resolver() { +// DARWIN: define weak_odr ptr @unused.resolver() // DARWIN: ret ptr @unused.arch_ivybridge.0 // DARWIN: ret ptr @unused.default.1 // WINDOWS: define dso_local void @unused.default.1() // WINDOWS: define dso_local void @unused.arch_ivybridge.0() -// WINDOWS: define weak_odr dso_local void @unused() comdat +// WINDOWS: define weak_odr dso_local void @unused() {{.*}} comdat // WINDOWS: musttail call void @unused.arch_ivybridge.0 // WINDOWS: musttail call void @unused.default.1 @@ -144,34 +144,34 @@ int bar3(void) { // WINDOWS: call i32 @foo_inline2() } -// LINUX: define weak_odr ptr @foo_inline.resolver() comdat +// LINUX: define weak_odr ptr @foo_inline.resolver() {{.*}} comdat // LINUX: ret ptr @foo_inline.arch_sandybridge.0 // LINUX: ret ptr @foo_inline.sse4.2.1 // LINUX: ret ptr @foo_inline.default.2 -// DARWIN: define weak_odr ptr @foo_inline.resolver() { +// DARWIN: define weak_odr ptr @foo_inline.resolver() // DARWIN: ret ptr @foo_inline.arch_sandybridge.0 // DARWIN: ret ptr @foo_inline.sse4.2.1 // DARWIN: ret ptr @foo_inline.default.2 -// WINDOWS: define weak_odr dso_local i32 @foo_inline() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_inline() {{.*}} comdat // WINDOWS: musttail call i32 @foo_inline.arch_sandybridge.0 // WINDOWS: musttail call i32 @foo_inline.sse4.2.1 // WINDOWS: musttail call i32 @foo_inline.default.2 inline int __attribute__((target_clones("arch=sandybridge,default,sse4.2"))) foo_inline2(void){ return 0; } -// LINUX: define weak_odr ptr @foo_inline2.resolver() comdat +// LINUX: define weak_odr ptr @foo_inline2.resolver() {{.*}} comdat // LINUX: ret ptr @foo_inline2.arch_sandybridge.0 // LINUX: ret ptr @foo_inline2.sse4.2.1 // LINUX: ret ptr @foo_inline2.default.2 -// DARWIN: define weak_odr ptr @foo_inline2.resolver() { +// DARWIN: define weak_odr ptr @foo_inline2.resolver() // DARWIN: ret ptr @foo_inline2.arch_sandybridge.0 // DARWIN: ret ptr @foo_inline2.sse4.2.1 // DARWIN: ret ptr @foo_inline2.default.2 -// WINDOWS: define weak_odr dso_local i32 @foo_inline2() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_inline2() {{.*}} comdat // WINDOWS: musttail call i32 @foo_inline2.arch_sandybridge.0 // WINDOWS: musttail call i32 @foo_inline2.sse4.2.1 // WINDOWS: musttail call i32 @foo_inline2.default.2 @@ -194,15 +194,15 @@ int test_foo_used_no_defn(void) { } -// LINUX: define weak_odr ptr @foo_used_no_defn.resolver() comdat +// LINUX: define weak_odr ptr @foo_used_no_defn.resolver() {{.*}} comdat // LINUX: ret ptr @foo_used_no_defn.sse4.2.0 // LINUX: ret ptr @foo_used_no_defn.default.1 -// DARWIN: define weak_odr ptr @foo_used_no_defn.resolver() { +// DARWIN: define weak_odr ptr @foo_used_no_defn.resolver() // DARWIN: ret ptr @foo_used_no_defn.sse4.2.0 // DARWIN: ret ptr @foo_used_no_defn.default.1 -// WINDOWS: define weak_odr dso_local i32 @foo_used_no_defn() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_used_no_defn() {{.*}} comdat // WINDOWS: musttail call i32 @foo_used_no_defn.sse4.2.0 // WINDOWS: musttail call i32 @foo_used_no_defn.default.1 @@ -213,7 +213,7 @@ int isa_level(int) { return 0; } // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v2.1( // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v3.2( // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v4.3( -// LINUX: define weak_odr ptr @isa_level.resolver() comdat +// LINUX: define weak_odr ptr @isa_level.resolver() {{.*}} comdat // LINUX: call void @__cpu_indicator_init() // LINUX-NEXT: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2) // LINUX-NEXT: and i32 %[[#]], 4 @@ -234,7 +234,7 @@ int isa_level(int) { return 0; } // DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v2.1( // DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v3.2( // DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v4.3( -// DARWIN: define weak_odr ptr @isa_level.resolver() { +// DARWIN: define weak_odr ptr @isa_level.resolver() // DARWIN: call void @__cpu_indicator_init() // DARWIN-NEXT: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2) // DARWIN-NEXT: and i32 %[[#]], 4 diff --git a/clang/test/CodeGen/attr-target-mv-va-args.c b/clang/test/CodeGen/attr-target-mv-va-args.c index dbf5a74205c4c..5147f87bc52f7 100644 --- a/clang/test/CodeGen/attr-target-mv-va-args.c +++ b/clang/test/CodeGen/attr-target-mv-va-args.c @@ -24,7 +24,7 @@ int bar(void) { // IFUNC-ELF: call i32 (i32, ...) @foo.ifunc(i32 noundef 1, i32 noundef 97, double // IFUNC-ELF: call i32 (i32, ...) @foo.ifunc(i32 noundef 2, double noundef 2.2{{[0-9Ee+]+}}, ptr noundef -// IFUNC-ELF: define weak_odr ptr @foo.resolver() comdat +// IFUNC-ELF: define weak_odr ptr @foo.resolver() {{.*}} comdat // IFUNC-ELF: ret ptr @foo.arch_sandybridge // IFUNC-ELF: ret ptr @foo.arch_ivybridge // IFUNC-ELF: ret ptr @foo.sse4.2 @@ -59,8 +59,8 @@ int bar(void) { // NO-IFUNC: call i32 (i32, ...) @foo.resolver(i32 noundef 1, i32 noundef 97, double // NO-IFUNC: call i32 (i32, ...) @foo.resolver(i32 noundef 2, double noundef 2.2{{[0-9Ee+]+}}, ptr noundef -// WINDOWS: define weak_odr dso_local i32 @foo.resolver(i32 %0, ...) comdat -// NO-IFUNC-ELF: define weak_odr i32 @foo.resolver(i32 %0, ...) comdat +// WINDOWS: define weak_odr dso_local i32 @foo.resolver(i32 %0, ...) {{.*}} comdat +// NO-IFUNC-ELF: define weak_odr i32 @foo.resolver(i32 %0, ...) {{.*}} comdat // NO-IFUNC: musttail call i32 (i32, ...) @foo.arch_sandybridge // NO-IFUNC: musttail call i32 (i32, ...) @foo.arch_ivybridge // NO-IFUNC: musttail call i32 (i32, ...) @foo.sse4.2 diff --git a/clang/test/CodeGen/attr-target-mv.c b/clang/test/CodeGen/attr-target-mv.c index 2c4b95ca04370..f31ca5a8d1401 100644 --- a/clang/test/CodeGen/attr-target-mv.c +++ b/clang/test/CodeGen/attr-target-mv.c @@ -270,7 +270,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo.sse4.2 // ITANIUM: ret ptr @foo -// WINDOWS: define weak_odr dso_local i32 @foo.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @foo.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @foo.arch_sandybridge // WINDOWS: call i32 @foo.arch_ivybridge @@ -278,9 +278,9 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: call i32 @foo /// Internal linkage resolvers do not use comdat. -// ITANIUM: define internal ptr @foo_internal.resolver() { +// ITANIUM: define internal ptr @foo_internal.resolver() #[[ATTR:[0-9]+]] { -// WINDOWS: define internal i32 @foo_internal.resolver() { +// WINDOWS: define internal i32 @foo_internal.resolver() {{.*}} { // ITANIUM: define{{.*}} i32 @bar2() // ITANIUM: call i32 @foo_inline.ifunc() @@ -296,7 +296,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo_inline.sse4.2 // ITANIUM: ret ptr @foo_inline -// WINDOWS: define weak_odr dso_local i32 @foo_inline.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_inline.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @foo_inline.arch_sandybridge // WINDOWS: call i32 @foo_inline.arch_ivybridge @@ -314,7 +314,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo_decls.sse4.2 // ITANIUM: ret ptr @foo_decls -// WINDOWS: define weak_odr dso_local void @foo_decls.resolver() comdat +// WINDOWS: define weak_odr dso_local void @foo_decls.resolver() {{.*}} comdat // WINDOWS: call void @foo_decls.sse4.2 // WINDOWS: call void @foo_decls @@ -338,7 +338,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo_multi.avx_sse4.2 // ITANIUM: ret ptr @foo_multi -// WINDOWS: define weak_odr dso_local void @foo_multi.resolver(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local void @foo_multi.resolver(i32 %0, double %1) {{.*}} comdat // WINDOWS: and i32 %{{.*}}, 4352 // WINDOWS: icmp eq i32 %{{.*}}, 4352 // WINDOWS: call void @foo_multi.fma4_sse4.2(i32 %0, double %1) @@ -387,10 +387,10 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @fwd_decl_avx.avx // ITANIUM: ret ptr @fwd_decl_avx -// WINDOWS: define weak_odr dso_local i32 @fwd_decl_default.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @fwd_decl_default.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @fwd_decl_default -// WINDOWS: define weak_odr dso_local i32 @fwd_decl_avx.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @fwd_decl_avx.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @fwd_decl_avx.avx // WINDOWS: call i32 @fwd_decl_avx @@ -468,7 +468,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @pr50025b // ITANIUM: define linkonce void @pr50025b() // ITANIUM: call void @must_be_emitted() -// WINDOWS: define weak_odr dso_local void @pr50025b.resolver() comdat +// WINDOWS: define weak_odr dso_local void @pr50025b.resolver() {{.*}} comdat // WINDOWS: musttail call void @pr50025b() // WINDOWS: define linkonce_odr dso_local void @pr50025b() #{{[0-9]*}} comdat // WINDOWS: call void @must_be_emitted() diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index b7112c783da91..1e0568e884643 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -138,7 +138,8 @@ int hoo(void) { // CHECK-NEXT: ret i32 [[ADD3]] // // -// CHECK-LABEL: define {{[^@]+}}@fmv.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv.resolver +// CHECK-SAME: () #[[ATTR3:[0-9]+]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -216,17 +217,20 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_one.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_one.resolver +// CHECK-SAME: () #[[ATTR3]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: ret ptr @fmv_one._Mls64Msimd // // -// CHECK-LABEL: define {{[^@]+}}@fmv_two.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_two.resolver +// CHECK-SAME: () #[[ATTR3]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: ret ptr @fmv_two._Mfp16Msimd // // -// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver +// CHECK-SAME: () #[[ATTR3]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: ret ptr @fmv_e._Mls64 // @@ -238,7 +242,8 @@ int hoo(void) { // CHECK-NEXT: ret i32 111 // // -// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver +// CHECK-SAME: () #[[ATTR3]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -264,7 +269,8 @@ int hoo(void) { // CHECK-NEXT: ret i32 [[CALL3]] // // -// CHECK-LABEL: define {{[^@]+}}@fmv_inline.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_inline.resolver +// CHECK-SAME: () #[[ATTR3]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -398,7 +404,8 @@ int hoo(void) { // CHECK-NEXT: ret ptr @fmv_inline.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver() { +// CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver +// CHECK-SAME: () #[[ATTR3]] { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -819,7 +826,7 @@ int hoo(void) { // CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon,+rand" } // CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" } // CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } -// CHECK: attributes #[[ATTR3:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR3]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } // CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+fullfp16,+ls64,+sme,+sme-i16i64" } // CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+sha2" } // CHECK: attributes #[[ATTR6]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+fullfp16,+ls64,+neon" } diff --git a/clang/test/CodeGenCXX/attr-cpuspecific.cpp b/clang/test/CodeGenCXX/attr-cpuspecific.cpp index 225c6a5c742a5..688650595b67c 100644 --- a/clang/test/CodeGenCXX/attr-cpuspecific.cpp +++ b/clang/test/CodeGenCXX/attr-cpuspecific.cpp @@ -22,7 +22,7 @@ void foo() { // LINUX: declare void @_ZN1S4FuncEv.S // LINUX: define linkonce_odr void @_ZN1S4FuncEv.O -// WINDOWS: define weak_odr dso_local void @"?Func@S@@QEAAXXZ"(ptr %0) comdat +// WINDOWS: define weak_odr dso_local void @"?Func@S@@QEAAXXZ"(ptr %0) {{.*}} comdat // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(ptr %0) // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(ptr %0) // WINDOWS: declare dso_local void @"?Func@S@@QEAAXXZ.S" diff --git a/clang/test/CodeGenCXX/attr-target-clones.cpp b/clang/test/CodeGenCXX/attr-target-clones.cpp index 0814df312f4d8..7bf5eb630d86a 100644 --- a/clang/test/CodeGenCXX/attr-target-clones.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones.cpp @@ -29,7 +29,7 @@ int __attribute__((target_clones("sse4.2", "default"))) overloaded(int) { return // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.sse4.2.0"(i32{{.+}}) // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.default.1"(i32{{.+}}) -// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHH@Z"(i32{{.+}}) comdat +// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHH@Z"(i32{{.+}}) {{.*}} comdat // WINDOWS: call i32 @"?overloaded@@YAHH@Z.sse4.2.0" // WINDOWS: call i32 @"?overloaded@@YAHH@Z.default.1" @@ -43,7 +43,7 @@ int __attribute__((target_clones("arch=ivybridge", "default"))) overloaded(const // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.arch_ivybridge.0"(ptr{{.+}}) // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.default.1"(ptr{{.+}}) -// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHPEBD@Z"(ptr{{.+}}) comdat +// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHPEBD@Z"(ptr{{.+}}) {{.*}} comdat // WINDOWS: call i32 @"?overloaded@@YAHPEBD@Z.arch_ivybridge.0" // WINDOWS: call i32 @"?overloaded@@YAHPEBD@Z.default.1" diff --git a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp index 8f2fb5ef0df7e..7dae27d3d2a72 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp @@ -67,7 +67,7 @@ int bar() { // ITANIUM: ret ptr @_Z3fooi.sse4.2 // ITANIUM: ret ptr @_Z3fooi -// WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) {{.*}} comdat // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_ivybridge"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z.sse4.2"(i32 %0) @@ -80,7 +80,7 @@ int bar() { // ITANIUM: ret ptr @_ZN2ns3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN2ns3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) {{.*}} comdat // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32 %0) // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_ivybridge"(i32 %0) // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 %0) diff --git a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp index f956890cf706e..1181f5b5d743d 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp @@ -180,7 +180,7 @@ int templ_use() { // ITANIUM: ret ptr @_ZN5templIdE3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN5templIdE3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) {{.*}} comdat // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge" // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge" // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2" diff --git a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp index 3c56cad3af914..32274ece69e60 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp @@ -54,7 +54,7 @@ int bar() { // ITANIUM: ret ptr @_ZN1S3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN1S3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) {{.*}} comdat // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"(ptr %0, i32 %1) diff --git a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp index e30fbf4ef5027..9e54919b3227c 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp @@ -61,7 +61,7 @@ int bar2() { // ITANIUM: ret ptr @_Z12foo_overloadv.sse4.2 // ITANIUM: ret ptr @_Z12foo_overloadv -// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() {{.*}} comdat // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_sandybridge" // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_ivybridge" // WINDOWS: call i32 @"?foo_overload@@YAHXZ.sse4.2" @@ -74,7 +74,7 @@ int bar2() { // ITANIUM: ret ptr @_Z12foo_overloadi.sse4.2 // ITANIUM: ret ptr @_Z12foo_overloadi -// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) {{.*}} comdat // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_sandybridge" // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_ivybridge" // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.sse4.2" >From 499382fcb792e15ed6942f388952309b88933cf0 Mon Sep 17 00:00:00 2001 From: Jon Roelofs <jonathan_roel...@apple.com> Date: Sun, 10 Mar 2024 16:46:50 -0700 Subject: [PATCH 3/3] [CodeGen][AArch64][FMV] PAC the stub_helper's frame on arm64e --- clang/lib/CodeGen/CodeGenFunction.cpp | 6 +- clang/lib/CodeGen/CodeGenModule.cpp | 18 ++++-- .../CodeGen/aarch64-mixed-target-attributes.c | 19 ++++--- clang/test/CodeGen/attr-cpuspecific.c | 24 ++++---- clang/test/CodeGen/attr-target-clones.c | 46 +++++++-------- clang/test/CodeGen/attr-target-mv-va-args.c | 6 +- clang/test/CodeGen/attr-target-mv.c | 18 +++--- .../test/CodeGen/attr-target-version-arm64e.c | 57 +++++++++++++++++++ clang/test/CodeGen/attr-target-version.c | 35 ++++++++---- clang/test/CodeGenCXX/attr-cpuspecific.cpp | 2 +- .../CodeGenCXX/attr-target-clones-aarch64.cpp | 47 ++++++++------- clang/test/CodeGenCXX/attr-target-clones.cpp | 4 +- .../CodeGenCXX/attr-target-mv-diff-ns.cpp | 4 +- .../attr-target-mv-member-funcs.cpp | 2 +- .../attr-target-mv-out-of-line-defs.cpp | 2 +- .../CodeGenCXX/attr-target-mv-overloads.cpp | 4 +- clang/test/CodeGenCXX/attr-target-version.cpp | 20 ++++--- clang/test/CodeGenCXX/fmv-namespace.cpp | 7 ++- llvm/include/llvm/CodeGen/AsmPrinter.h | 13 +++-- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 3 +- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 45 +++++++++++++++ llvm/test/CodeGen/AArch64/ifunc-asm.ll | 21 +++++-- 22 files changed, 280 insertions(+), 123 deletions(-) create mode 100644 clang/test/CodeGen/attr-target-version-arm64e.c diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1e98bea8c8ce3..76b6bc39b8b15 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2833,7 +2833,11 @@ static void CreateMultiVersionResolverReturn(CodeGenModule &CGM, llvm::Function *FuncToReturn, bool SupportsIFunc) { if (SupportsIFunc) { - Builder.CreateRet(FuncToReturn); + llvm::Constant *Fn = FuncToReturn; + const ASTContext &Ctx = CGM.getContext(); + QualType FTy = Ctx.getFunctionType(Ctx.VoidTy, {}, FunctionProtoType::ExtProtoInfo()); + Fn = CGM.getFunctionPointer(Fn, FTy); + Builder.CreateRet(Fn); return; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 71192cb0e8c4a..c3f4ee6911814 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4510,13 +4510,16 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // For cpu_specific, don't create an ifunc yet because we don't know if the // cpu_dispatch will be emitted in this translation unit. if (getTarget().supportsIFunc() && !FD->isCPUSpecificMultiVersion()) { - llvm::Type *ResolverType = llvm::FunctionType::get( + llvm::FunctionType *ResolverType = llvm::FunctionType::get( llvm::PointerType::get(DeclTy, getTypes().getTargetAddressSpace(FD->getType())), false); - llvm::Constant *Resolver = GetOrCreateLLVMFunction( - MangledName + ".resolver", ResolverType, GlobalDecl{}, - /*ForVTable=*/false); + llvm::Function *Resolver = cast<llvm::Function>( + CreateRuntimeFunction(ResolverType, MangledName + ".resolver") + .getCallee()); + llvm::AttrBuilder Attrs(getLLVMContext()); + addDefaultFunctionDefinitionAttributes(Attrs); + Resolver->addFnAttrs(Attrs); llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create(DeclTy, 0, getMultiversionLinkage(*this, GD), "", Resolver, &getModule()); @@ -4527,8 +4530,11 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { return GIF; } - llvm::Constant *Resolver = GetOrCreateLLVMFunction( - ResolverName, DeclTy, GlobalDecl{}, /*ForVTable=*/false); + llvm::Function *Resolver = cast<llvm::Function>( + CreateRuntimeFunction(DeclTy, ResolverName).getCallee()); + llvm::AttrBuilder Attrs(getLLVMContext()); + addDefaultFunctionDefinitionAttributes(Attrs); + Resolver->addFnAttrs(Attrs); assert(isa<llvm::GlobalValue>(Resolver) && "Resolver should be created for the first time"); SetCommonAttributes(FD, cast<llvm::GlobalValue>(Resolver)); diff --git a/clang/test/CodeGen/aarch64-mixed-target-attributes.c b/clang/test/CodeGen/aarch64-mixed-target-attributes.c index d779abd395b5f..87a4fc7ecd78f 100644 --- a/clang/test/CodeGen/aarch64-mixed-target-attributes.c +++ b/clang/test/CodeGen/aarch64-mixed-target-attributes.c @@ -62,7 +62,8 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define {{[^@]+}}@explicit_default.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@explicit_default.resolver +// CHECK-SAME: () #[[ATTR4:[0-9]+]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -102,7 +103,7 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@explicit_default._Mrdm -// CHECK-SAME: () #[[ATTR4:[0-9]+]] { +// CHECK-SAME: () #[[ATTR5:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // @@ -136,7 +137,8 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define {{[^@]+}}@implicit_default.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@implicit_default.resolver +// CHECK-SAME: () #[[ATTR4]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -176,7 +178,7 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define {{[^@]+}}@implicit_default._Mrdm -// CHECK-SAME: () #[[ATTR4]] { +// CHECK-SAME: () #[[ATTR5]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 3 // @@ -203,7 +205,8 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define {{[^@]+}}@default_def_with_version_decls.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@default_def_with_version_decls.resolver +// CHECK-SAME: () #[[ATTR4]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -259,9 +262,9 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } // CHECK: attributes #[[ATTR2]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } // CHECK: attributes #[[ATTR3]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } -// CHECK: attributes #[[ATTR4]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } -// CHECK: attributes #[[ATTR5:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } -// CHECK: attributes #[[ATTR6:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } +// CHECK: attributes #[[ATTR4]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-v9.5a" } +// CHECK: attributes #[[ATTR5]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm,-v9.5a" } +// CHECK: attributes #[[ATTR6:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon,-v9.5a" } // CHECK: attributes #[[ATTR7:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse,-v9.5a" } // CHECK: attributes #[[ATTR8:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+jsconv,+neon,-v9.5a" } //. diff --git a/clang/test/CodeGen/attr-cpuspecific.c b/clang/test/CodeGen/attr-cpuspecific.c index 628892d5809b4..8b6ed65ee8713 100644 --- a/clang/test/CodeGen/attr-cpuspecific.c +++ b/clang/test/CodeGen/attr-cpuspecific.c @@ -51,7 +51,7 @@ void SingleVersion(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @SingleVersion() comdat +// WINDOWS: define weak_odr dso_local void @SingleVersion() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: %[[FEAT_INIT:.+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4 // WINDOWS: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 525311 @@ -82,7 +82,7 @@ void TwoVersions(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @TwoVersions() comdat +// WINDOWS: define weak_odr dso_local void @TwoVersions() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: %[[FEAT_INIT:.+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4 // WINDOWS: %[[FEAT_JOIN:.+]] = and i32 %[[FEAT_INIT]], 9422847 @@ -125,7 +125,7 @@ void OrderDispatchUsageSpecific(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @OrderDispatchUsageSpecific() comdat +// WINDOWS: define weak_odr dso_local void @OrderDispatchUsageSpecific() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call void @OrderDispatchUsageSpecific.Z() // WINDOWS-NEXT: ret void @@ -174,7 +174,7 @@ void TwoVersionsSameAttr(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @TwoVersionsSameAttr() comdat +// WINDOWS: define weak_odr dso_local void @TwoVersionsSameAttr() {{.*}} comdat // WINDOWS: call void @TwoVersionsSameAttr.Z // WINDOWS-NEXT: ret void // WINDOWS: call void @TwoVersionsSameAttr.S @@ -194,7 +194,7 @@ void ThreeVersionsSameAttr(void){} // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @ThreeVersionsSameAttr() comdat +// WINDOWS: define weak_odr dso_local void @ThreeVersionsSameAttr() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @ThreeVersionsSameAttr.Z // WINDOWS-NEXT: ret void @@ -210,7 +210,7 @@ void OrderSpecificUsageDispatch(void); // LINUX: define weak_odr ptr @OrderSpecificUsageDispatch.resolver() // LINUX: ret ptr @OrderSpecificUsageDispatch.Z -// WINDOWS: define weak_odr dso_local void @OrderSpecificUsageDispatch() comdat +// WINDOWS: define weak_odr dso_local void @OrderSpecificUsageDispatch() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @OrderSpecificUsageDispatch.Z // WINDOWS-NEXT: ret void @@ -226,7 +226,7 @@ void NoSpecifics(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define weak_odr dso_local void @NoSpecifics() comdat +// WINDOWS: define weak_odr dso_local void @NoSpecifics() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @NoSpecifics.Z // WINDOWS-NEXT: ret void @@ -247,7 +247,7 @@ void HasGeneric(void); // LINUX: ret ptr @HasGeneric.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local void @HasGeneric() comdat +// WINDOWS: define weak_odr dso_local void @HasGeneric() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @HasGeneric.Z // WINDOWS-NEXT: ret void @@ -269,7 +269,7 @@ void HasParams(int i, double d); // LINUX: ret ptr @HasParams.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local void @HasParams(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local void @HasParams(i32 %0, double %1) {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @HasParams.Z(i32 %0, double %1) // WINDOWS-NEXT: ret void @@ -291,7 +291,7 @@ int HasParamsAndReturn(int i, double d); // LINUX: ret ptr @HasParamsAndReturn.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local i32 @HasParamsAndReturn(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local i32 @HasParamsAndReturn(i32 %0, double %1) {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: %[[RET:.+]] = musttail call i32 @HasParamsAndReturn.Z(i32 %0, double %1) // WINDOWS-NEXT: ret i32 %[[RET]] @@ -312,7 +312,7 @@ int GenericAndPentium(int i, double d); // LINUX-NOT: ret ptr @GenericAndPentium.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define weak_odr dso_local i32 @GenericAndPentium(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local i32 @GenericAndPentium(i32 %0, double %1) {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: %[[RET:.+]] = musttail call i32 @GenericAndPentium.O(i32 %0, double %1) // WINDOWS-NEXT: ret i32 %[[RET]] @@ -327,7 +327,7 @@ int DispatchFirst(void); // LINUX: ret ptr @DispatchFirst.O // LINUX: ret ptr @DispatchFirst.B -// WINDOWS: define weak_odr dso_local i32 @DispatchFirst() comdat +// WINDOWS: define weak_odr dso_local i32 @DispatchFirst() {{.*}} comdat // WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.O() // WINDOWS-NEXT: ret i32 %[[RET]] // WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.B() diff --git a/clang/test/CodeGen/attr-target-clones.c b/clang/test/CodeGen/attr-target-clones.c index 3256db061f9a2..730321e185fba 100644 --- a/clang/test/CodeGen/attr-target-clones.c +++ b/clang/test/CodeGen/attr-target-clones.c @@ -44,45 +44,45 @@ static int __attribute__((target_clones("sse4.2, default"))) internal(void) { return 0; } int use(void) { return internal(); } /// Internal linkage resolvers do not use comdat. -// LINUX: define internal ptr @internal.resolver() { -// DARWIN: define internal ptr @internal.resolver() { -// WINDOWS: define internal i32 @internal() { +// LINUX: define internal ptr @internal.resolver() +// DARWIN: define internal ptr @internal.resolver() +// WINDOWS: define internal i32 @internal() int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; } // LINUX: define {{.*}}i32 @foo.sse4.2.0() // LINUX: define {{.*}}i32 @foo.default.1() -// LINUX: define weak_odr ptr @foo.resolver() comdat +// LINUX: define weak_odr ptr @foo.resolver() {{.*}} comdat // LINUX: ret ptr @foo.sse4.2.0 // LINUX: ret ptr @foo.default.1 // DARWIN: define {{.*}}i32 @foo.sse4.2.0() // DARWIN: define {{.*}}i32 @foo.default.1() -// DARWIN: define weak_odr ptr @foo.resolver() { +// DARWIN: define weak_odr ptr @foo.resolver() // DARWIN: ret ptr @foo.sse4.2.0 // DARWIN: ret ptr @foo.default.1 // WINDOWS: define dso_local i32 @foo.sse4.2.0() // WINDOWS: define dso_local i32 @foo.default.1() -// WINDOWS: define weak_odr dso_local i32 @foo() comdat +// WINDOWS: define weak_odr dso_local i32 @foo() {{.*}} comdat // WINDOWS: musttail call i32 @foo.sse4.2.0 // WINDOWS: musttail call i32 @foo.default.1 __attribute__((target_clones("default,default ,sse4.2"))) void foo_dupes(void) {} // LINUX: define {{.*}}void @foo_dupes.default.1() // LINUX: define {{.*}}void @foo_dupes.sse4.2.0() -// LINUX: define weak_odr ptr @foo_dupes.resolver() comdat +// LINUX: define weak_odr ptr @foo_dupes.resolver() {{.*}} comdat // LINUX: ret ptr @foo_dupes.sse4.2.0 // LINUX: ret ptr @foo_dupes.default.1 // DARWIN: define {{.*}}void @foo_dupes.default.1() // DARWIN: define {{.*}}void @foo_dupes.sse4.2.0() -// DARWIN: define weak_odr ptr @foo_dupes.resolver() { +// DARWIN: define weak_odr ptr @foo_dupes.resolver() // DARWIN: ret ptr @foo_dupes.sse4.2.0 // DARWIN: ret ptr @foo_dupes.default.1 // WINDOWS: define dso_local void @foo_dupes.default.1() // WINDOWS: define dso_local void @foo_dupes.sse4.2.0() -// WINDOWS: define weak_odr dso_local void @foo_dupes() comdat +// WINDOWS: define weak_odr dso_local void @foo_dupes() {{.*}} comdat // WINDOWS: musttail call void @foo_dupes.sse4.2.0 // WINDOWS: musttail call void @foo_dupes.default.1 @@ -109,19 +109,19 @@ int bar(void) { void __attribute__((target_clones("default, arch=ivybridge"))) unused(void) {} // LINUX: define {{.*}}void @unused.default.1() // LINUX: define {{.*}}void @unused.arch_ivybridge.0() -// LINUX: define weak_odr ptr @unused.resolver() comdat +// LINUX: define weak_odr ptr @unused.resolver() {{.*}} comdat // LINUX: ret ptr @unused.arch_ivybridge.0 // LINUX: ret ptr @unused.default.1 // DARWIN: define {{.*}}void @unused.default.1() // DARWIN: define {{.*}}void @unused.arch_ivybridge.0() -// DARWIN: define weak_odr ptr @unused.resolver() { +// DARWIN: define weak_odr ptr @unused.resolver() // DARWIN: ret ptr @unused.arch_ivybridge.0 // DARWIN: ret ptr @unused.default.1 // WINDOWS: define dso_local void @unused.default.1() // WINDOWS: define dso_local void @unused.arch_ivybridge.0() -// WINDOWS: define weak_odr dso_local void @unused() comdat +// WINDOWS: define weak_odr dso_local void @unused() {{.*}} comdat // WINDOWS: musttail call void @unused.arch_ivybridge.0 // WINDOWS: musttail call void @unused.default.1 @@ -144,34 +144,34 @@ int bar3(void) { // WINDOWS: call i32 @foo_inline2() } -// LINUX: define weak_odr ptr @foo_inline.resolver() comdat +// LINUX: define weak_odr ptr @foo_inline.resolver() {{.*}} comdat // LINUX: ret ptr @foo_inline.arch_sandybridge.0 // LINUX: ret ptr @foo_inline.sse4.2.1 // LINUX: ret ptr @foo_inline.default.2 -// DARWIN: define weak_odr ptr @foo_inline.resolver() { +// DARWIN: define weak_odr ptr @foo_inline.resolver() // DARWIN: ret ptr @foo_inline.arch_sandybridge.0 // DARWIN: ret ptr @foo_inline.sse4.2.1 // DARWIN: ret ptr @foo_inline.default.2 -// WINDOWS: define weak_odr dso_local i32 @foo_inline() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_inline() {{.*}} comdat // WINDOWS: musttail call i32 @foo_inline.arch_sandybridge.0 // WINDOWS: musttail call i32 @foo_inline.sse4.2.1 // WINDOWS: musttail call i32 @foo_inline.default.2 inline int __attribute__((target_clones("arch=sandybridge,default,sse4.2"))) foo_inline2(void){ return 0; } -// LINUX: define weak_odr ptr @foo_inline2.resolver() comdat +// LINUX: define weak_odr ptr @foo_inline2.resolver() {{.*}} comdat // LINUX: ret ptr @foo_inline2.arch_sandybridge.0 // LINUX: ret ptr @foo_inline2.sse4.2.1 // LINUX: ret ptr @foo_inline2.default.2 -// DARWIN: define weak_odr ptr @foo_inline2.resolver() { +// DARWIN: define weak_odr ptr @foo_inline2.resolver() // DARWIN: ret ptr @foo_inline2.arch_sandybridge.0 // DARWIN: ret ptr @foo_inline2.sse4.2.1 // DARWIN: ret ptr @foo_inline2.default.2 -// WINDOWS: define weak_odr dso_local i32 @foo_inline2() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_inline2() {{.*}} comdat // WINDOWS: musttail call i32 @foo_inline2.arch_sandybridge.0 // WINDOWS: musttail call i32 @foo_inline2.sse4.2.1 // WINDOWS: musttail call i32 @foo_inline2.default.2 @@ -194,15 +194,15 @@ int test_foo_used_no_defn(void) { } -// LINUX: define weak_odr ptr @foo_used_no_defn.resolver() comdat +// LINUX: define weak_odr ptr @foo_used_no_defn.resolver() {{.*}} comdat // LINUX: ret ptr @foo_used_no_defn.sse4.2.0 // LINUX: ret ptr @foo_used_no_defn.default.1 -// DARWIN: define weak_odr ptr @foo_used_no_defn.resolver() { +// DARWIN: define weak_odr ptr @foo_used_no_defn.resolver() // DARWIN: ret ptr @foo_used_no_defn.sse4.2.0 // DARWIN: ret ptr @foo_used_no_defn.default.1 -// WINDOWS: define weak_odr dso_local i32 @foo_used_no_defn() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_used_no_defn() {{.*}} comdat // WINDOWS: musttail call i32 @foo_used_no_defn.sse4.2.0 // WINDOWS: musttail call i32 @foo_used_no_defn.default.1 @@ -213,7 +213,7 @@ int isa_level(int) { return 0; } // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v2.1( // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v3.2( // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v4.3( -// LINUX: define weak_odr ptr @isa_level.resolver() comdat +// LINUX: define weak_odr ptr @isa_level.resolver() {{.*}} comdat // LINUX: call void @__cpu_indicator_init() // LINUX-NEXT: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2) // LINUX-NEXT: and i32 %[[#]], 4 @@ -234,7 +234,7 @@ int isa_level(int) { return 0; } // DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v2.1( // DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v3.2( // DARWIN: define{{.*}} i32 @isa_level.arch_x86-64-v4.3( -// DARWIN: define weak_odr ptr @isa_level.resolver() { +// DARWIN: define weak_odr ptr @isa_level.resolver() // DARWIN: call void @__cpu_indicator_init() // DARWIN-NEXT: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2) // DARWIN-NEXT: and i32 %[[#]], 4 diff --git a/clang/test/CodeGen/attr-target-mv-va-args.c b/clang/test/CodeGen/attr-target-mv-va-args.c index dbf5a74205c4c..5147f87bc52f7 100644 --- a/clang/test/CodeGen/attr-target-mv-va-args.c +++ b/clang/test/CodeGen/attr-target-mv-va-args.c @@ -24,7 +24,7 @@ int bar(void) { // IFUNC-ELF: call i32 (i32, ...) @foo.ifunc(i32 noundef 1, i32 noundef 97, double // IFUNC-ELF: call i32 (i32, ...) @foo.ifunc(i32 noundef 2, double noundef 2.2{{[0-9Ee+]+}}, ptr noundef -// IFUNC-ELF: define weak_odr ptr @foo.resolver() comdat +// IFUNC-ELF: define weak_odr ptr @foo.resolver() {{.*}} comdat // IFUNC-ELF: ret ptr @foo.arch_sandybridge // IFUNC-ELF: ret ptr @foo.arch_ivybridge // IFUNC-ELF: ret ptr @foo.sse4.2 @@ -59,8 +59,8 @@ int bar(void) { // NO-IFUNC: call i32 (i32, ...) @foo.resolver(i32 noundef 1, i32 noundef 97, double // NO-IFUNC: call i32 (i32, ...) @foo.resolver(i32 noundef 2, double noundef 2.2{{[0-9Ee+]+}}, ptr noundef -// WINDOWS: define weak_odr dso_local i32 @foo.resolver(i32 %0, ...) comdat -// NO-IFUNC-ELF: define weak_odr i32 @foo.resolver(i32 %0, ...) comdat +// WINDOWS: define weak_odr dso_local i32 @foo.resolver(i32 %0, ...) {{.*}} comdat +// NO-IFUNC-ELF: define weak_odr i32 @foo.resolver(i32 %0, ...) {{.*}} comdat // NO-IFUNC: musttail call i32 (i32, ...) @foo.arch_sandybridge // NO-IFUNC: musttail call i32 (i32, ...) @foo.arch_ivybridge // NO-IFUNC: musttail call i32 (i32, ...) @foo.sse4.2 diff --git a/clang/test/CodeGen/attr-target-mv.c b/clang/test/CodeGen/attr-target-mv.c index 2c4b95ca04370..f31ca5a8d1401 100644 --- a/clang/test/CodeGen/attr-target-mv.c +++ b/clang/test/CodeGen/attr-target-mv.c @@ -270,7 +270,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo.sse4.2 // ITANIUM: ret ptr @foo -// WINDOWS: define weak_odr dso_local i32 @foo.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @foo.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @foo.arch_sandybridge // WINDOWS: call i32 @foo.arch_ivybridge @@ -278,9 +278,9 @@ void calls_pr50025c(void) { pr50025c(); } // WINDOWS: call i32 @foo /// Internal linkage resolvers do not use comdat. -// ITANIUM: define internal ptr @foo_internal.resolver() { +// ITANIUM: define internal ptr @foo_internal.resolver() #[[ATTR:[0-9]+]] { -// WINDOWS: define internal i32 @foo_internal.resolver() { +// WINDOWS: define internal i32 @foo_internal.resolver() {{.*}} { // ITANIUM: define{{.*}} i32 @bar2() // ITANIUM: call i32 @foo_inline.ifunc() @@ -296,7 +296,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo_inline.sse4.2 // ITANIUM: ret ptr @foo_inline -// WINDOWS: define weak_odr dso_local i32 @foo_inline.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @foo_inline.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @foo_inline.arch_sandybridge // WINDOWS: call i32 @foo_inline.arch_ivybridge @@ -314,7 +314,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo_decls.sse4.2 // ITANIUM: ret ptr @foo_decls -// WINDOWS: define weak_odr dso_local void @foo_decls.resolver() comdat +// WINDOWS: define weak_odr dso_local void @foo_decls.resolver() {{.*}} comdat // WINDOWS: call void @foo_decls.sse4.2 // WINDOWS: call void @foo_decls @@ -338,7 +338,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @foo_multi.avx_sse4.2 // ITANIUM: ret ptr @foo_multi -// WINDOWS: define weak_odr dso_local void @foo_multi.resolver(i32 %0, double %1) comdat +// WINDOWS: define weak_odr dso_local void @foo_multi.resolver(i32 %0, double %1) {{.*}} comdat // WINDOWS: and i32 %{{.*}}, 4352 // WINDOWS: icmp eq i32 %{{.*}}, 4352 // WINDOWS: call void @foo_multi.fma4_sse4.2(i32 %0, double %1) @@ -387,10 +387,10 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @fwd_decl_avx.avx // ITANIUM: ret ptr @fwd_decl_avx -// WINDOWS: define weak_odr dso_local i32 @fwd_decl_default.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @fwd_decl_default.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @fwd_decl_default -// WINDOWS: define weak_odr dso_local i32 @fwd_decl_avx.resolver() comdat +// WINDOWS: define weak_odr dso_local i32 @fwd_decl_avx.resolver() {{.*}} comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call i32 @fwd_decl_avx.avx // WINDOWS: call i32 @fwd_decl_avx @@ -468,7 +468,7 @@ void calls_pr50025c(void) { pr50025c(); } // ITANIUM: ret ptr @pr50025b // ITANIUM: define linkonce void @pr50025b() // ITANIUM: call void @must_be_emitted() -// WINDOWS: define weak_odr dso_local void @pr50025b.resolver() comdat +// WINDOWS: define weak_odr dso_local void @pr50025b.resolver() {{.*}} comdat // WINDOWS: musttail call void @pr50025b() // WINDOWS: define linkonce_odr dso_local void @pr50025b() #{{[0-9]*}} comdat // WINDOWS: call void @must_be_emitted() diff --git a/clang/test/CodeGen/attr-target-version-arm64e.c b/clang/test/CodeGen/attr-target-version-arm64e.c new file mode 100644 index 0000000000000..24fd526bcedd6 --- /dev/null +++ b/clang/test/CodeGen/attr-target-version-arm64e.c @@ -0,0 +1,57 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs +// RUN: %clang_cc1 -triple arm64e-apple-ios -target-feature +ls64 -target-feature +fullfp16 -emit-llvm -o - %s | FileCheck %s + +int __attribute__((target_version("sha1"))) fmv(void) { return 1; } +int __attribute__((target_version("default"))) fmv(void) { return 0; } +int foo() { + return fmv(); +} + +//. +// CHECK: @__aarch64_cpu_features = external dso_local global { i64 } +// CHECK: @fmv = weak_odr ifunc i32 (), ptr @fmv.resolver +//. +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv._Msha1 +// CHECK-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 1 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@fmv.default +// CHECK-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define {{[^@]+}}@foo +// CHECK-SAME: () #[[ATTR1]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv() +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK-LABEL: define {{[^@]+}}@fmv.resolver +// CHECK-SAME: () #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: resolver_entry: +// CHECK-NEXT: call void @__init_cpu_features_resolver() +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 2048 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 2048 +// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] +// CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] +// CHECK: resolver_return: +// CHECK-NEXT: ret ptr @fmv._Msha1 +// CHECK: resolver_else: +// CHECK-NEXT: ret ptr @fmv.default +// +//. +// CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" } +// CHECK: attributes #[[ATTR1]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } +// CHECK: attributes #[[ATTR2]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } +//. +// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} +//. diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index b058f84f78baa..9a970c5134534 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -464,7 +464,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret i32 [[CALL]] // // -// CHECK-LABEL: define {{[^@]+}}@fmv.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv.resolver +// CHECK-SAME: () #[[ATTR12:[0-9]+]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -542,7 +543,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_one.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_one.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -564,7 +566,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv_one.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_two.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_two.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -602,7 +605,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv_two.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_e.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -630,7 +634,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver() { +// CHECK-LABEL: define {{[^@]+}}@fmv_d.resolver +// CHECK-SAME: () #[[ATTR12]] { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -644,7 +649,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv_d.default // // -// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_c.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -777,7 +783,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret i32 3 // // -// CHECK-LABEL: define {{[^@]+}}@fmv_inline.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@fmv_inline.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -911,7 +918,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv_inline.default // // -// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@unused_with_default_def.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -925,7 +933,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @unused_with_default_def.default // // -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_default_def.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -939,7 +948,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @unused_with_implicit_default_def.default // // -// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@unused_with_implicit_forward_default_def.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -953,7 +963,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @unused_with_implicit_forward_default_def.default // // -// CHECK-LABEL: define {{[^@]+}}@default_def_with_version_decls.resolver() comdat { +// CHECK-LABEL: define {{[^@]+}}@default_def_with_version_decls.resolver +// CHECK-SAME: () #[[ATTR12]] comdat { // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -1124,7 +1135,7 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK: attributes #[[ATTR9]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } // CHECK: attributes #[[ATTR10]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp" } // CHECK: attributes #[[ATTR11]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } -// CHECK: attributes #[[ATTR12:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR12]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } // CHECK: attributes #[[ATTR13]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } // CHECK: attributes #[[ATTR14]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+neon" } // CHECK: attributes #[[ATTR15]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } diff --git a/clang/test/CodeGenCXX/attr-cpuspecific.cpp b/clang/test/CodeGenCXX/attr-cpuspecific.cpp index 225c6a5c742a5..688650595b67c 100644 --- a/clang/test/CodeGenCXX/attr-cpuspecific.cpp +++ b/clang/test/CodeGenCXX/attr-cpuspecific.cpp @@ -22,7 +22,7 @@ void foo() { // LINUX: declare void @_ZN1S4FuncEv.S // LINUX: define linkonce_odr void @_ZN1S4FuncEv.O -// WINDOWS: define weak_odr dso_local void @"?Func@S@@QEAAXXZ"(ptr %0) comdat +// WINDOWS: define weak_odr dso_local void @"?Func@S@@QEAAXXZ"(ptr %0) {{.*}} comdat // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(ptr %0) // WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(ptr %0) // WINDOWS: declare dso_local void @"?Func@S@@QEAAXXZ.S" diff --git a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp index 6405621a9d647..443431894dcf6 100644 --- a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp @@ -53,7 +53,8 @@ void run_foo_tml() { // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovli.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovli.resolver( +// CHECK-SAME: ) #[[ATTR1:[0-9]+]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -68,12 +69,13 @@ void run_foo_tml() { // // // CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovlv._Mls64Mls64_accdata( -// CHECK-SAME: ) #[[ATTR1:[0-9]+]] { +// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovlv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z7foo_ovlv.resolver( +// CHECK-SAME: ) #[[ATTR1]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -88,7 +90,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define dso_local noundef i32 @_Z3barv( -// CHECK-SAME: ) #[[ATTR2:[0-9]+]] { +// CHECK-SAME: ) #[[ATTR3:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_Z7foo_ovli(i32 noundef 1) // CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z7foo_ovlv() @@ -97,7 +99,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define dso_local void @_Z11run_foo_tmlv( -// CHECK-SAME: ) #[[ATTR2]] { +// CHECK-SAME: ) #[[ATTR3]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[MC1:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 // CHECK-NEXT: [[MC2:%.*]] = alloca [[STRUCT_MYCLASS_0:%.*]], align 1 @@ -111,7 +113,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIfsE7foo_tmlEv( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -120,7 +122,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIdfE7foo_tmlEv( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -129,7 +131,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovli.default( -// CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR2]] { +// CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR3]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 @@ -137,13 +139,13 @@ void run_foo_tml() { // // // CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovlv.default( -// CHECK-SAME: ) #[[ATTR2]] { +// CHECK-SAME: ) #[[ATTR3]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret i32 2 // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv._Mfrintts( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3:[0-9]+]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4:[0-9]+]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -152,7 +154,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv._Msme-f64f64Mssbs( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4:[0-9]+]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR5:[0-9]+]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -161,7 +163,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv.default( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -169,7 +171,8 @@ void run_foo_tml() { // CHECK-NEXT: ret i32 1 // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIssE7foo_tmlEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIssE7foo_tmlEv.resolver( +// CHECK-SAME: ) #[[ATTR1]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -192,7 +195,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv._Mfrintts( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -201,7 +204,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv._Msme-f64f64Mssbs( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR5]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -210,7 +213,7 @@ void run_foo_tml() { // // // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv.default( -// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3]] comdat { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 @@ -218,7 +221,8 @@ void run_foo_tml() { // CHECK-NEXT: ret i32 2 // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIisE7foo_tmlEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIisE7foo_tmlEv.resolver( +// CHECK-SAME: ) #[[ATTR1]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -241,10 +245,11 @@ void run_foo_tml() { // //. // CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } -// CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ls64" } -// CHECK: attributes #[[ATTR2]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -// CHECK: attributes #[[ATTR3]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint" } -// CHECK: attributes #[[ATTR4]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } +// CHECK: attributes #[[ATTR1]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR2]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ls64" } +// CHECK: attributes #[[ATTR3]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR4]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint" } +// CHECK: attributes #[[ATTR5]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme,+sme-f64f64" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/clang/test/CodeGenCXX/attr-target-clones.cpp b/clang/test/CodeGenCXX/attr-target-clones.cpp index 0814df312f4d8..7bf5eb630d86a 100644 --- a/clang/test/CodeGenCXX/attr-target-clones.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones.cpp @@ -29,7 +29,7 @@ int __attribute__((target_clones("sse4.2", "default"))) overloaded(int) { return // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.sse4.2.0"(i32{{.+}}) // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHH@Z.default.1"(i32{{.+}}) -// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHH@Z"(i32{{.+}}) comdat +// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHH@Z"(i32{{.+}}) {{.*}} comdat // WINDOWS: call i32 @"?overloaded@@YAHH@Z.sse4.2.0" // WINDOWS: call i32 @"?overloaded@@YAHH@Z.default.1" @@ -43,7 +43,7 @@ int __attribute__((target_clones("arch=ivybridge", "default"))) overloaded(const // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.arch_ivybridge.0"(ptr{{.+}}) // WINDOWS: define dso_local noundef i32 @"?overloaded@@YAHPEBD@Z.default.1"(ptr{{.+}}) -// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHPEBD@Z"(ptr{{.+}}) comdat +// WINDOWS: define weak_odr dso_local i32 @"?overloaded@@YAHPEBD@Z"(ptr{{.+}}) {{.*}} comdat // WINDOWS: call i32 @"?overloaded@@YAHPEBD@Z.arch_ivybridge.0" // WINDOWS: call i32 @"?overloaded@@YAHPEBD@Z.default.1" diff --git a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp index 8f2fb5ef0df7e..7dae27d3d2a72 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-diff-ns.cpp @@ -67,7 +67,7 @@ int bar() { // ITANIUM: ret ptr @_Z3fooi.sse4.2 // ITANIUM: ret ptr @_Z3fooi -// WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) {{.*}} comdat // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_ivybridge"(i32 %0) // WINDOWS: call i32 @"?foo@@YAHH@Z.sse4.2"(i32 %0) @@ -80,7 +80,7 @@ int bar() { // ITANIUM: ret ptr @_ZN2ns3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN2ns3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) {{.*}} comdat // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32 %0) // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_ivybridge"(i32 %0) // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 %0) diff --git a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp index f956890cf706e..1181f5b5d743d 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp @@ -180,7 +180,7 @@ int templ_use() { // ITANIUM: ret ptr @_ZN5templIdE3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN5templIdE3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) {{.*}} comdat // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge" // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge" // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2" diff --git a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp index 3c56cad3af914..32274ece69e60 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-out-of-line-defs.cpp @@ -54,7 +54,7 @@ int bar() { // ITANIUM: ret ptr @_ZN1S3fooEi.sse4.2 // ITANIUM: ret ptr @_ZN1S3fooEi -// WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1) {{.*}} comdat // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(ptr %0, i32 %1) // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"(ptr %0, i32 %1) diff --git a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp index e30fbf4ef5027..9e54919b3227c 100644 --- a/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp +++ b/clang/test/CodeGenCXX/attr-target-mv-overloads.cpp @@ -61,7 +61,7 @@ int bar2() { // ITANIUM: ret ptr @_Z12foo_overloadv.sse4.2 // ITANIUM: ret ptr @_Z12foo_overloadv -// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHXZ.resolver"() {{.*}} comdat // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_sandybridge" // WINDOWS: call i32 @"?foo_overload@@YAHXZ.arch_ivybridge" // WINDOWS: call i32 @"?foo_overload@@YAHXZ.sse4.2" @@ -74,7 +74,7 @@ int bar2() { // ITANIUM: ret ptr @_Z12foo_overloadi.sse4.2 // ITANIUM: ret ptr @_Z12foo_overloadi -// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) comdat +// WINDOWS: define weak_odr dso_local i32 @"?foo_overload@@YAHH@Z.resolver"(i32 %0) {{.*}} comdat // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_sandybridge" // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.arch_ivybridge" // WINDOWS: call i32 @"?foo_overload@@YAHH@Z.sse4.2" diff --git a/clang/test/CodeGenCXX/attr-target-version.cpp b/clang/test/CodeGenCXX/attr-target-version.cpp index 6661abead20c6..0d3eaedc20d13 100644 --- a/clang/test/CodeGenCXX/attr-target-version.cpp +++ b/clang/test/CodeGenCXX/attr-target-version.cpp @@ -231,7 +231,8 @@ int bar() { // CHECK-NEXT: ret i32 [[ADD3]] // // -// CHECK-LABEL: define weak_odr ptr @_Z3fooi.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z3fooi.resolver( +// CHECK-SAME: ) #[[ATTR11:[0-9]+]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -245,7 +246,8 @@ int bar() { // CHECK-NEXT: ret ptr @_Z3fooi.default // // -// CHECK-LABEL: define weak_odr ptr @_Z3foov.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_Z3foov.resolver( +// CHECK-SAME: ) #[[ATTR11]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -259,7 +261,8 @@ int bar() { // CHECK-NEXT: ret ptr @_Z3foov.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass3gooEi.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass3gooEi.resolver( +// CHECK-SAME: ) #[[ATTR11]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -281,7 +284,8 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass23unused_with_default_defEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass23unused_with_default_defEv.resolver( +// CHECK-SAME: ) #[[ATTR11]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -295,7 +299,8 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass23unused_with_default_defEv.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass32unused_with_implicit_default_defEv.resolver( +// CHECK-SAME: ) #[[ATTR11]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -309,7 +314,8 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass32unused_with_implicit_default_defEv.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN7MyClass40unused_with_implicit_forward_default_defEv.resolver( +// CHECK-SAME: ) #[[ATTR11]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -334,7 +340,7 @@ int bar() { // CHECK: attributes #[[ATTR8]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" } // CHECK: attributes #[[ATTR9]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+lse" } // CHECK: attributes #[[ATTR10]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rdm" } -// CHECK: attributes #[[ATTR11:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// CHECK: attributes #[[ATTR11]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/clang/test/CodeGenCXX/fmv-namespace.cpp b/clang/test/CodeGenCXX/fmv-namespace.cpp index 1ac88e68a3a12..35eda4fd756cc 100644 --- a/clang/test/CodeGenCXX/fmv-namespace.cpp +++ b/clang/test/CodeGenCXX/fmv-namespace.cpp @@ -72,7 +72,8 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: ret i32 0 // // -// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver( +// CHECK-SAME: ) #[[ATTR4:[0-9]+]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -86,7 +87,8 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: ret ptr @_ZN4Name3fooEv.default // // -// CHECK-LABEL: define weak_odr ptr @_ZN3Foo3barEv.resolver() comdat { +// CHECK-LABEL: define weak_odr ptr @_ZN3Foo3barEv.resolver( +// CHECK-SAME: ) #[[ATTR4]] comdat { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 @@ -104,6 +106,7 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" } // CHECK: attributes #[[ATTR2:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" } // CHECK: attributes #[[ATTR3]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+mops" } +// CHECK: attributes #[[ATTR4]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" } //. // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index 1c4e9e9111441..a482545610c2b 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -595,16 +595,21 @@ class AsmPrinter : public MachineFunctionPass { return nullptr; } + virtual const MCExpr * + emitMachOIfuncLazyPointerInit(const MCSymbolRefExpr *Init) { + return Init; + } + virtual void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) { - llvm_unreachable( - "Mach-O IFunc lowering is not yet supported on this target"); + assert(false && + "Mach-O IFunc lowering is not yet supported on this target"); } virtual void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) { - llvm_unreachable( - "Mach-O IFunc lowering is not yet supported on this target"); + assert(false && + "Mach-O IFunc lowering is not yet supported on this target"); } /// Emit N NOP instructions. diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 91b5703944f3d..86ba76262659d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2231,7 +2231,8 @@ void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) { emitAlignment(Align(DL.getPointerSize())); OutStreamer->emitLabel(LazyPointer); emitVisibility(LazyPointer, GI.getVisibility()); - OutStreamer->emitValue(MCSymbolRefExpr::create(StubHelper, OutContext), 8); + const MCSymbolRefExpr *Init = MCSymbolRefExpr::create(StubHelper, OutContext); + OutStreamer->emitValue(emitMachOIfuncLazyPointerInit(Init), 8); OutStreamer->switchSection(OutContext.getObjectFileInfo()->getTextSection()); diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 1e60ce9c40df8..4d7232f44c007 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -226,6 +226,8 @@ class AArch64AsmPrinter : public AsmPrinter { assert(STI); return STI; } + const MCExpr * + emitMachOIfuncLazyPointerInit(const MCSymbolRefExpr *Init) override; void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) override; void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI, @@ -2419,6 +2421,15 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); } +const MCExpr * +AArch64AsmPrinter::emitMachOIfuncLazyPointerInit(const MCSymbolRefExpr *Init) { + if (TM.getTargetTriple().isArm64e()) + return AArch64AuthMCExpr::create(Init, /*Disc=*/0, AArch64PACKey::IA, + /*HasAddressDiversity=*/false, OutContext); + + return Init; +} + void AArch64AsmPrinter::emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer) { // _ifunc: @@ -2502,6 +2513,9 @@ void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(Module &M, // ldp fp, lr, [sp], #16 // br x16 + if (TM.getTargetTriple().isArm64e()) + OutStreamer->emitInstruction(MCInstBuilder(AArch64::PACIBSP), *STI); + OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXpre) .addReg(AArch64::SP) .addReg(AArch64::FP) @@ -2607,6 +2621,37 @@ void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(Module &M, .addImm(2), *STI); + if (TM.getTargetTriple().isArm64e()) { + // autibsp + // eor x17, lr, lr, lsl #1 + // tbz x17, #62, Lgoodsig + // brk #0xc741 + // Lgoodsig: + + OutStreamer->emitInstruction(MCInstBuilder(AArch64::AUTIBSP), *STI); + + OutStreamer->emitInstruction(MCInstBuilder(AArch64::EORXrs) + .addReg(AArch64::X17) + .addReg(AArch64::LR) + .addReg(AArch64::LR) + .addImm(1), + *STI); + + MCContext &Ctx = OutStreamer->getContext(); + MCSymbol *GoodSigSym = Ctx.createTempSymbol(); + const MCExpr *GoodSig = MCSymbolRefExpr::create(GoodSigSym, Ctx); + OutStreamer->emitInstruction(MCInstBuilder(AArch64::TBZX) + .addReg(AArch64::X17) + .addImm(62) + .addExpr(GoodSig), + *STI); + + OutStreamer->emitInstruction(MCInstBuilder(AArch64::BRK).addImm(0xc471), + *STI); + + OutStreamer->emitLabel(GoodSigSym); + } + OutStreamer->emitInstruction(MCInstBuilder(TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ : AArch64::BR) diff --git a/llvm/test/CodeGen/AArch64/ifunc-asm.ll b/llvm/test/CodeGen/AArch64/ifunc-asm.ll index 57fc2f0c9d7f5..6f0d6f633fd51 100644 --- a/llvm/test/CodeGen/AArch64/ifunc-asm.ll +++ b/llvm/test/CodeGen/AArch64/ifunc-asm.ll @@ -1,6 +1,8 @@ ; RUN: llc -mtriple=arm64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=ELF -; RUN: llc -mtriple=arm64-apple-darwin %s -o - | FileCheck %s --check-prefix=MACHO -; RUN: llc -mtriple=arm64-apple-darwin %s -global-isel -o - | FileCheck %s --check-prefix=MACHO +; RUN: llc -mtriple=arm64-apple-darwin %s -o - | FileCheck %s --check-prefixes=MACHO,ARM64 +; RUN: llc -mtriple=arm64-apple-darwin %s -global-isel -o - | FileCheck %s --check-prefixes=MACHO,ARM64 +; RUN: llc -mtriple=arm64e-apple-darwin %s -o - | FileCheck %s --check-prefixes=MACHO,PAUTH +; RUN: llc -mtriple=arm64e-apple-darwin %s -global-isel -o - | FileCheck %s --check-prefixes=MACHO,PAUTH define internal ptr @the_resolver() { entry: @@ -21,7 +23,8 @@ entry: ; MACHO: .section __DATA,__data ; MACHO-NEXT: .p2align 3, 0x0 ; MACHO-NEXT: _global_ifunc.lazy_pointer: -; MACHO-NEXT: .quad _global_ifunc.stub_helper +; ARM64-NEXT: .quad _global_ifunc.stub_helper{{$}} +; PAUTH-NEXT: .quad _global_ifunc.stub_helper@AUTH(ia,0) ; MACHO: .section __TEXT,__text,regular,pure_instructions ; MACHO-NEXT: .globl _global_ifunc @@ -30,9 +33,11 @@ entry: ; MACHO-NEXT: adrp x16, _global_ifunc.lazy_pointer@GOTPAGE ; MACHO-NEXT: ldr x16, [x16, _global_ifunc.lazy_pointer@GOTPAGEOFF] ; MACHO-NEXT: ldr x16, [x16] -; MACHO-NEXT: br x16 +; ARM64-NEXT: br x16 +; PAUTH-NEXT: braaz x16 ; MACHO-NEXT: .p2align 2 ; MACHO-NEXT: _global_ifunc.stub_helper: +; PAUTH-NEXT: pacibsp ; MACHO-NEXT: stp x29, x30, [sp, #-16]! ; MACHO-NEXT: mov x29, sp ; MACHO-NEXT: stp x1, x0, [sp, #-16]! @@ -57,7 +62,13 @@ entry: ; MACHO-NEXT: ldp x3, x2, [sp], #16 ; MACHO-NEXT: ldp x1, x0, [sp], #16 ; MACHO-NEXT: ldp x29, x30, [sp], #16 -; MACHO-NEXT: br x16 +; PAUTH-NEXT: autibsp +; PAUTH-NEXT: eor x17, x30, x30, lsl #1 +; PAUTH-NEXT: tbz x17, #62, [[GOOD_SIG:Ltmp[0-9]+]] +; PAUTH-NEXT: brk #0xc471 +; PAUTH-NEXT: [[GOOD_SIG]]: +; ARM64-NEXT: br x16 +; PAUTH-NEXT: braaz x16 @weak_ifunc = weak ifunc i32 (i32), ptr @the_resolver _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits