diff options
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp | 3 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/setjmp-bti.ll | 15 |
3 files changed, 15 insertions, 5 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index ba7b54a..7f34970 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7173,7 +7173,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, bool IsSibCall = false; bool GuardWithBTI = false; - if (CLI.CB && CLI.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) && + if (CLI.CB && CLI.CB->hasFnAttr(Attribute::ReturnsTwice) && !Subtarget->noBTIAtReturnTwice()) { GuardWithBTI = FuncInfo->branchTargetEnforcement(); } diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index 3b06fbe..e603414 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -1266,8 +1266,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, Opc = AArch64::BLR_RVMARKER; // A call to a returns twice function like setjmp must be followed by a bti // instruction. - else if (Info.CB && - Info.CB->getAttributes().hasFnAttr(Attribute::ReturnsTwice) && + else if (Info.CB && Info.CB->hasFnAttr(Attribute::ReturnsTwice) && !Subtarget.noBTIAtReturnTwice() && MF.getInfo<AArch64FunctionInfo>()->branchTargetEnforcement()) Opc = AArch64::BLR_BTI; diff --git a/llvm/test/CodeGen/AArch64/setjmp-bti.ll b/llvm/test/CodeGen/AArch64/setjmp-bti.ll index 0f19409..79a6baf 100644 --- a/llvm/test/CodeGen/AArch64/setjmp-bti.ll +++ b/llvm/test/CodeGen/AArch64/setjmp-bti.ll @@ -18,8 +18,9 @@ ; ; void bbb(void) { ; setjmp(0); +; setjmp(0); // With the attributes removed. ; int (*fnptr)(ptr) = setjmp; -; fnptr(0); +; fnptr(0); // With attributes added. ; notsetjmp(); ; } @@ -27,6 +28,8 @@ define void @bbb() { ; BTI-LABEL: bbb: ; BTI: bl setjmp ; BTI-NEXT: hint #36 +; BTI: bl setjmp +; BTI-NEXT: hint #36 ; BTI: blr x{{[0-9]+}} ; BTI-NEXT: hint #36 ; BTI: bl notsetjmp @@ -35,6 +38,8 @@ define void @bbb() { ; BTISLS-LABEL: bbb: ; BTISLS: bl setjmp ; BTISLS-NEXT: hint #36 +; BTISLS: bl setjmp +; BTISLS-NEXT: hint #36 ; BTISLS: bl __llvm_slsblr_thunk_x{{[0-9]+}} ; BTISLS-NEXT: hint #36 ; BTISLS: bl notsetjmp @@ -43,16 +48,22 @@ define void @bbb() { ; NOBTI-LABEL: bbb: ; NOBTI: bl setjmp ; NOBTI-NOT: hint #36 +; NOBTI: bl setjmp +; NOBTI-NOT: hint #36 ; NOBTI: blr x{{[0-9]+}} ; NOBTI-NOT: hint #36 ; NOBTI: bl notsetjmp ; NOBTI-NOT: hint #36 entry: %fnptr = alloca ptr, align 8 + ; The frontend may apply attributes to the call, but it doesn't have to. We + ; should be looking at the call base, which looks past that to the called function. %call = call i32 @setjmp(ptr noundef null) #0 + %call1 = call i32 @setjmp(ptr noundef null) store ptr @setjmp, ptr %fnptr, align 8 %0 = load ptr, ptr %fnptr, align 8 - %call1 = call i32 %0(ptr noundef null) #0 + ; Clang does not attach the attribute here but if it did, it should work. + %call2 = call i32 %0(ptr noundef null) #0 call void @notsetjmp() ret void } |
