From e82cace1244f131ddffe12c09910c756043dfcc3 Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Fri, 28 Oct 2022 07:08:08 +0000 Subject: [PATCH] [AArch64][SME] Set fn attributes correctly on __arm_tpidr2_save call. Changing the way the attribute is created changes the way the attribute is added. Now it seems to be correctly added as a function attribute, whereas before it was not. This led ISel ignoring attributes and setting up a lazy-save buffer for the call to __arm_tpidr2_save. This patch also marks the intrinsic call as 'preserves_za' which together with the above prevents the code-generator from setting up a lazy-save buffer. Reviewed By: kmclaughlin Differential Revision: https://reviews.llvm.org/D136342 --- llvm/lib/Target/AArch64/SMEABIPass.cpp | 9 ++++++--- llvm/test/CodeGen/AArch64/sme-new-za-function.ll | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/AArch64/SMEABIPass.cpp b/llvm/lib/Target/AArch64/SMEABIPass.cpp index f209e8f6f6f93..822ade2b2f5ab 100644 --- a/llvm/lib/Target/AArch64/SMEABIPass.cpp +++ b/llvm/lib/Target/AArch64/SMEABIPass.cpp @@ -63,12 +63,15 @@ FunctionPass *llvm::createSMEABIPass() { return new SMEABI(); } void emitTPIDR2Save(Module *M, IRBuilder<> &Builder) { auto *TPIDR2SaveTy = FunctionType::get(Builder.getVoidTy(), {}, /*IsVarArgs=*/false); - auto Attrs = - AttributeList::get(M->getContext(), 0, {"aarch64_pstate_sm_compatible"}); + AttributeList() + .addFnAttribute(M->getContext(), "aarch64_pstate_sm_compatible") + .addFnAttribute(M->getContext(), "aarch64_pstate_za_preserved"); FunctionCallee Callee = M->getOrInsertFunction("__arm_tpidr2_save", TPIDR2SaveTy, Attrs); - Builder.CreateCall(Callee); + CallInst *Call = Builder.CreateCall(Callee); + Call->setCallingConv( + CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0); // A save to TPIDR2 should be followed by clearing TPIDR2_EL0. Function *WriteIntr = diff --git a/llvm/test/CodeGen/AArch64/sme-new-za-function.ll b/llvm/test/CodeGen/AArch64/sme-new-za-function.ll index 392f590bb2408..54ef5fd432755 100644 --- a/llvm/test/CodeGen/AArch64/sme-new-za-function.ll +++ b/llvm/test/CodeGen/AArch64/sme-new-za-function.ll @@ -10,7 +10,7 @@ define void @private_za() "aarch64_pstate_za_new" { ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[TPIDR2]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[SAVE_ZA:%.*]], label [[TMP0:%.*]] ; CHECK: save.za: -; CHECK-NEXT: call void @__arm_tpidr2_save() +; CHECK-NEXT: call aarch64_sme_preservemost_from_x0 void @__arm_tpidr2_save() ; CHECK-NEXT: call void @llvm.aarch64.sme.set.tpidr2(i64 0) ; CHECK-NEXT: br label [[TMP0]] ; CHECK: 0: @@ -30,7 +30,7 @@ define i32 @private_za_multiple_exit(i32 %a, i32 %b, i64 %cond) "aarch64_pstate_ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[TPIDR2]], 0 ; CHECK-NEXT: br i1 [[CMP]], label [[SAVE_ZA:%.*]], label [[ENTRY:%.*]] ; CHECK: save.za: -; CHECK-NEXT: call void @__arm_tpidr2_save() +; CHECK-NEXT: call aarch64_sme_preservemost_from_x0 void @__arm_tpidr2_save() ; CHECK-NEXT: call void @llvm.aarch64.sme.set.tpidr2(i64 0) ; CHECK-NEXT: br label [[ENTRY]] ; CHECK: entry: @@ -59,4 +59,5 @@ if.end: ret i32 %sub } -; CHECK: declare "aarch64_pstate_sm_compatible" void @__arm_tpidr2_save() +; CHECK: declare void @__arm_tpidr2_save() #[[ATTR:[0-9]+]] +; CHECK: attributes #[[ATTR]] = { "aarch64_pstate_sm_compatible" "aarch64_pstate_za_preserved" }