Skip to content

Commit c81e7db

Browse files
committed
Use the stack_protector metadata to skip alloca's which don't need protection.
This is the LLVM piece of this work. The clang work permitted the no_stack_protector attribute on local variables. That generated new metadata which is used here to skip any alloca's which would otherwise require a stack protector.
1 parent fd8bf3c commit c81e7db

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

llvm/lib/CodeGen/StackProtector.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,11 @@ bool SSPLayoutAnalysis::requiresStackProtector(Function *F,
431431
for (const BasicBlock &BB : *F) {
432432
for (const Instruction &I : BB) {
433433
if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
434+
if (MDNode* MD = AI->getMetadata("stack-protector")) {
435+
auto* CI = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0));
436+
if (CI->isZero())
437+
continue;
438+
}
434439
if (AI->isArrayAllocation()) {
435440
auto RemarkBuilder = [&]() {
436441
return OptimizationRemark(DEBUG_TYPE, "StackProtectorAllocaOrArray",
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
; RUN: llc -mtriple=aarch64-apple-darwin < %s -o - | FileCheck %s
2+
3+
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
4+
target triple = "arm64-apple-darwin25.1.0"
5+
6+
@.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
7+
8+
; CHECK-LABEL: test1:
9+
; CHECK-NOT: ___stack_chk_guard
10+
11+
; Function Attrs: noinline nounwind optnone
12+
define void @test1(ptr noundef %msg) #0 {
13+
entry:
14+
%msg.addr = alloca ptr, align 8
15+
%a = alloca [1000 x i8], align 1, !stack-protector !2
16+
store ptr %msg, ptr %msg.addr, align 8
17+
%arraydecay = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
18+
%0 = load ptr, ptr %msg.addr, align 8
19+
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
20+
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
21+
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
22+
ret void
23+
}
24+
25+
26+
; CHECK-LABEL: test2:
27+
; CHECK: ___stack_chk_guard
28+
29+
; Function Attrs: noinline nounwind optnone
30+
define void @test2(ptr noundef %msg) #0 {
31+
entry:
32+
%msg.addr = alloca ptr, align 8
33+
%b = alloca [1000 x i8], align 1
34+
store ptr %msg, ptr %msg.addr, align 8
35+
%arraydecay = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
36+
%0 = load ptr, ptr %msg.addr, align 8
37+
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
38+
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
39+
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
40+
ret void
41+
}
42+
43+
; Function Attrs: nounwind
44+
declare ptr @strcpy(ptr noundef, ptr noundef) #1
45+
46+
declare i32 @printf(ptr noundef, ...) #2
47+
48+
attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" ssp }
49+
attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
50+
attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
51+
attributes #3 = { nounwind }
52+
53+
!llvm.module.flags = !{!0}
54+
!llvm.ident = !{!1}
55+
56+
!0 = !{i32 1, !"wchar_size", i32 4}
57+
!1 = !{!"clang version 22.0.0"}
58+
!2 = !{i32 0}

0 commit comments

Comments
 (0)