-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AArch64] Fix case of 0 dynamic alloc when stack probing #74877
Conversation
@llvm/pr-subscribers-backend-aarch64 Author: Oskar Wirga (oskarwirga) ChangesI have ZERO clue what happened but I accidentally closed #74806 If the dynamic allocation size is 0, then we will still probe the current sp value despite not decrementing sp! This results in overwriting stack data, in my case the stack canary. The fix here is just to load the value of [sp] into xzr which is essentially a no-op but still performs a read/probe of the new page. Full diff: https://github.com/llvm/llvm-project/pull/74877.diff 5 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 93b8295f4f3efc..50cbd3672fbd0d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -9532,9 +9532,9 @@ AArch64InstrInfo::probedStackAlloc(MachineBasicBlock::iterator MBBI,
.addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0))
.setMIFlags(Flags);
- // STR XZR, [SP]
- BuildMI(*ExitMBB, ExitMBB->end(), DL, TII->get(AArch64::STRXui))
- .addReg(AArch64::XZR)
+ // LDR XZR, [SP]
+ BuildMI(*ExitMBB, ExitMBB->end(), DL, TII->get(AArch64::LDRXui))
+ .addReg(AArch64::XZR, RegState::Define)
.addReg(AArch64::SP)
.addImm(0)
.setMIFlags(Flags);
diff --git a/llvm/test/CodeGen/AArch64/stack-probing-64k.ll b/llvm/test/CodeGen/AArch64/stack-probing-64k.ll
index 945c271d375001..2f15e317a7f58b 100644
--- a/llvm/test/CodeGen/AArch64/stack-probing-64k.ll
+++ b/llvm/test/CodeGen/AArch64/stack-probing-64k.ll
@@ -313,7 +313,7 @@ define void @static_16_align_131072(ptr %out) #0 {
; CHECK-NEXT: b .LBB9_1
; CHECK-NEXT: .LBB9_3: // %entry
; CHECK-NEXT: mov sp, x9
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: mov x8, sp
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: mov sp, x29
diff --git a/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll b/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll
index d247ed1b599775..a3b8df487ed488 100644
--- a/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll
+++ b/llvm/test/CodeGen/AArch64/stack-probing-dynamic.ll
@@ -28,7 +28,7 @@ define void @dynamic(i64 %size, ptr %out) #0 {
; CHECK-NEXT: b .LBB0_1
; CHECK-NEXT: .LBB0_3:
; CHECK-NEXT: mov sp, x8
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: mov sp, x29
; CHECK-NEXT: .cfi_def_cfa wsp, 16
@@ -72,7 +72,7 @@ define void @dynamic_fixed(i64 %size, ptr %out1, ptr %out2) #0 {
; CHECK-NEXT: b .LBB1_1
; CHECK-NEXT: .LBB1_3:
; CHECK-NEXT: mov sp, x8
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: str x8, [x2]
; CHECK-NEXT: mov sp, x29
; CHECK-NEXT: .cfi_def_cfa wsp, 16
@@ -122,7 +122,7 @@ define void @dynamic_align_64(i64 %size, ptr %out) #0 {
; CHECK-NEXT: b .LBB2_1
; CHECK-NEXT: .LBB2_3:
; CHECK-NEXT: mov sp, x8
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: mov sp, x29
; CHECK-NEXT: .cfi_def_cfa wsp, 32
@@ -167,7 +167,7 @@ define void @dynamic_align_8192(i64 %size, ptr %out) #0 {
; CHECK-NEXT: mov sp, x9
; CHECK-NEXT: add x9, x0, #15
; CHECK-NEXT: mov x8, sp
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: and x9, x9, #0xfffffffffffffff0
; CHECK-NEXT: mov x19, sp
; CHECK-NEXT: sub x8, x8, x9
@@ -181,7 +181,7 @@ define void @dynamic_align_8192(i64 %size, ptr %out) #0 {
; CHECK-NEXT: b .LBB3_4
; CHECK-NEXT: .LBB3_6:
; CHECK-NEXT: mov sp, x8
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: mov sp, x29
; CHECK-NEXT: .cfi_def_cfa wsp, 32
@@ -221,7 +221,7 @@ define void @dynamic_64k_guard(i64 %size, ptr %out) #0 "stack-probe-size"="65536
; CHECK-NEXT: b .LBB4_1
; CHECK-NEXT: .LBB4_3:
; CHECK-NEXT: mov sp, x8
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: mov sp, x29
; CHECK-NEXT: .cfi_def_cfa wsp, 16
@@ -265,7 +265,7 @@ define void @no_reserved_call_frame(i64 %n) #0 {
; CHECK-NEXT: b .LBB5_1
; CHECK-NEXT: .LBB5_3: // %entry
; CHECK-NEXT: mov sp, x0
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: sub sp, sp, #1104
; CHECK-NEXT: str xzr, [sp]
; CHECK-NEXT: bl callee_stack_args
@@ -344,7 +344,7 @@ define void @dynamic_sve(i64 %size, ptr %out) #0 "target-features"="+sve" {
; CHECK-NEXT: b .LBB7_1
; CHECK-NEXT: .LBB7_3:
; CHECK-NEXT: mov sp, x8
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: str x8, [x1]
; CHECK-NEXT: mov sp, x29
; CHECK-NEXT: .cfi_def_cfa wsp, 32
diff --git a/llvm/test/CodeGen/AArch64/stack-probing-sve.ll b/llvm/test/CodeGen/AArch64/stack-probing-sve.ll
index 4dad104e66f20d..03a9220ebfddc6 100644
--- a/llvm/test/CodeGen/AArch64/stack-probing-sve.ll
+++ b/llvm/test/CodeGen/AArch64/stack-probing-sve.ll
@@ -115,7 +115,7 @@ define void @sve_17_vector(ptr %out) #0 {
; CHECK-NEXT: b .LBB3_1
; CHECK-NEXT: .LBB3_3: // %entry
; CHECK-NEXT: mov sp, x9
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: .cfi_def_cfa_register wsp
; CHECK-NEXT: addvl sp, sp, #17
; CHECK-NEXT: .cfi_def_cfa wsp, 16
@@ -351,7 +351,7 @@ define void @sve_16v_1p_csr(<vscale x 4 x float> %a) #0 {
; CHECK-NEXT: b .LBB9_1
; CHECK-NEXT: .LBB9_3: // %entry
; CHECK-NEXT: mov sp, x9
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: .cfi_def_cfa_register wsp
; CHECK-NEXT: str p8, [sp, #7, mul vl] // 2-byte Folded Spill
; CHECK-NEXT: str z23, [sp, #1, mul vl] // 16-byte Folded Spill
@@ -467,7 +467,7 @@ define void @sve_1_vector_4096_arr(ptr %out) #0 {
; CHECK-NEXT: b .LBB11_1
; CHECK-NEXT: .LBB11_3: // %entry
; CHECK-NEXT: mov sp, x9
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: .cfi_def_cfa_register wsp
; CHECK-NEXT: addvl sp, sp, #31
; CHECK-NEXT: .cfi_escape 0x0f, 0x0f, 0x8f, 0x00, 0x11, 0x90, 0xe0, 0x00, 0x22, 0x11, 0x88, 0x02, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 12304 + 264 * VG
@@ -516,7 +516,7 @@ define void @sve_1_vector_16_arr_align_8192(ptr %out) #0 {
; CHECK-NEXT: b .LBB12_1
; CHECK-NEXT: .LBB12_3: // %entry
; CHECK-NEXT: mov sp, x9
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: mov sp, x29
; CHECK-NEXT: .cfi_def_cfa wsp, 16
; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload
@@ -616,7 +616,7 @@ define void @sve_1028_64k_guard(ptr %out) #0 "stack-probe-size"="65536" {
; CHECK-NEXT: b .LBB14_1
; CHECK-NEXT: .LBB14_3: // %entry
; CHECK-NEXT: mov sp, x9
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: .cfi_def_cfa_register wsp
; CHECK-NEXT: addvl sp, sp, #31
; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x90, 0x0e, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 16 + 1808 * VG
diff --git a/llvm/test/CodeGen/AArch64/stack-probing.ll b/llvm/test/CodeGen/AArch64/stack-probing.ll
index 5c5d9321a56e58..df5408de5bab0a 100644
--- a/llvm/test/CodeGen/AArch64/stack-probing.ll
+++ b/llvm/test/CodeGen/AArch64/stack-probing.ll
@@ -400,7 +400,7 @@ define void @static_16_align_8192(ptr %out) #0 {
; CHECK-NEXT: b .LBB13_1
; CHECK-NEXT: .LBB13_3: // %entry
; CHECK-NEXT: mov sp, x9
-; CHECK-NEXT: str xzr, [sp]
+; CHECK-NEXT: ldr xzr, [sp]
; CHECK-NEXT: mov x8, sp
; CHECK-NEXT: str x8, [x0]
; CHECK-NEXT: mov sp, x29
|
I have ZERO clue what happened but I accidentally closed #74806
If the dynamic allocation size is 0, then we will still probe the current sp value despite not decrementing sp! This results in overwriting stack data, in my case the stack canary.
The fix here is just to load the value of [sp] into xzr which is essentially a no-op but still performs a read/probe of the new page.