[llvm] Fix https://github.com/llvm/llvm-project/issues/75998 (PR #82661)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 22 09:44:22 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: Eleanor Bonnici (eleanor-arm)

<details>
<summary>Changes</summary>


When compiling for thumbv8.1m with +pacbti and making an indirect tail
call, the compiler was free to put the function pointer into R12.

This is incorrect because R12 is restored to contain authentication code
for the caller's return address.

This patch excludes R12 from the set of registers the compiler can put
the function pointer in.


---
Full diff: https://github.com/llvm/llvm-project/pull/82661.diff


2 Files Affected:

- (modified) llvm/lib/Target/ARM/ARMRegisterInfo.td (+2-1) 
- (added) llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call-no-r12.ll (+78) 


``````````diff
diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.td b/llvm/lib/Target/ARM/ARMRegisterInfo.td
index 194d65cad8d170..025ca62d54376b 100644
--- a/llvm/lib/Target/ARM/ARMRegisterInfo.td
+++ b/llvm/lib/Target/ARM/ARMRegisterInfo.td
@@ -369,7 +369,8 @@ def hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)> {
 def tcGPR : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3, R12)> {
   let AltOrders = [(and tcGPR, tGPR)];
   let AltOrderSelect = [{
-      return MF.getSubtarget<ARMSubtarget>().isThumb1Only();
+      return MF.getSubtarget<ARMSubtarget>().isThumb1Only() ||
+        MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true);
   }];
 }
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call-no-r12.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call-no-r12.ll
new file mode 100644
index 00000000000000..844baa15500a3d
--- /dev/null
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call-no-r12.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc %s -mtriple=thumbv8.1m.main -mattr=+pacbti -o - | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv8.1m.main-m.main-unknown"
+
+; Function Attrs: minsize nounwind optsize sspstrong
+define dso_local arm_aapcscc i32 @i3c_dev_do_priv_xfers_locked(ptr noundef %dev, ptr noundef %xfers, i32 noundef %nxfers) local_unnamed_addr #0 {
+; CHECK-LABEL: i3c_dev_do_priv_xfers_locked:
+; CHECK:       @ %bb.0: @ %entry
+; CHECK-NEXT:    pacbti r12, lr, sp
+; CHECK-NEXT:    push {r4, lr}
+; CHECK-NEXT:    str r12, [sp, #-4]!
+; CHECK-NEXT:    mov r3, r0
+; CHECK-NEXT:    mvn r0, #21
+; CHECK-NEXT:    cbz r1, .LBB0_5
+; CHECK-NEXT:  @ %bb.1: @ %entry
+; CHECK-NEXT:    ldr r4, [r3]
+; CHECK-NEXT:    cbz r4, .LBB0_5
+; CHECK-NEXT:  @ %bb.2: @ %if.end
+; CHECK-NEXT:    ldr r0, [r4]
+; CHECK-NEXT:    ldr r
+; CHECK-SAME-NOT      12
+; CHECK-SAME             , [r0]
+; CHECK-NEXT:    cbz r0, .LBB0_4
+; CHECK-NEXT:  @ %bb.3: @ %if.end5
+; CHECK-NEXT:    mov r4, r0
+; CHECK-NEXT:    mov r0, r3
+; CHECK-NEXT:    mov r3, r4
+; CHECK-NEXT:    ldr r12, [sp], #4
+; CHECK-NEXT:    pop.w {r4, lr}
+; CHECK-NEXT:    aut r12, lr, sp
+; CHECK-NEXT:    bx r
+; CHECK-SAME-NOT     12
+entry:
+  %0 = load ptr, ptr %dev, align 4, !tbaa !6
+  %tobool = icmp ne ptr %0, null
+  %tobool2 = icmp ne ptr %xfers, null
+  %or.cond = and i1 %tobool2, %tobool
+  br i1 %or.cond, label %if.end, label %cleanup
+
+if.end:                                           ; preds = %entry
+
+  %1 = load ptr, ptr %0, align 4, !tbaa !12
+  %2 = load ptr, ptr %1, align 4, !tbaa !14
+  %tobool3.not = icmp eq ptr %2, null
+  br i1 %tobool3.not, label %cleanup, label %if.end5
+
+if.end5:                                          ; preds = %if.end
+  %call = tail call arm_aapcscc i32 %2(ptr noundef nonnull %dev, ptr noundef nonnull %xfers, i32 noundef %nxfers) #1
+  br label %cleanup
+
+cleanup:                                          ; preds = %if.end, %entry, %if.end5
+  %retval.0 = phi i32 [ %call, %if.end5 ], [ -22, %entry ], [ -138, %if.end ]
+  ret i32 %retval.0
+}
+
+attributes #0 = { minsize sspstrong "target-features"="+armv8.1-m.main" }
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4}
+!llvm.ident = !{!5}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"min_enum_size", i32 1}
+!2 = !{i32 8, !"branch-target-enforcement", i32 1}
+!3 = !{i32 8, !"guarded-control-stack", i32 1}
+!4 = !{i32 8, !"sign-return-address", i32 1}
+!5 = !{!"clang version 18.0.0git (git at github.com:llvm/llvm-project.git 2db9244b6f66a4fd4c937de7b33a5b6dda4a06a8)"}
+!6 = !{!7, !9, i64 0}
+!7 = !{!"i3c_dev_desc", !8, i64 0}
+!8 = !{!"i3c_i2c_dev_desc", !9, i64 0}
+!9 = !{!"any pointer", !10, i64 0}
+!10 = !{!"omnipotent char", !11, i64 0}
+!11 = !{!"Simple C/C++ TBAA"}
+!12 = !{!13, !9, i64 0}
+!13 = !{!"i3c_master_controller", !9, i64 0}
+!14 = !{!15, !9, i64 0}
+!15 = !{!"i3c_master_controller_ops", !9, i64 0}

``````````

</details>


https://github.com/llvm/llvm-project/pull/82661


More information about the llvm-commits mailing list