blob: 3f07f02ba5c3ebcb7dbba1024adb2f5ea7366f04 [file]
; RUN: llc -mtriple=aarch64-apple-darwin < %s -o - | FileCheck %s
@.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
; CHECK-LABEL: test1:
; CHECK-NOT: ___stack_chk_guard
; Function Attrs: noinline nounwind optnone
define void @test1(ptr noundef %msg) #0 {
entry:
%msg.addr = alloca ptr, align 8
%a = alloca [1000 x i8], align 1, !stack-protector !2
store ptr %msg, ptr %msg.addr, align 8
%arraydecay = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
%0 = load ptr, ptr %msg.addr, align 8
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
ret void
}
; CHECK-LABEL: test2:
; CHECK: ___stack_chk_guard
; Function Attrs: noinline nounwind optnone
define void @test2(ptr noundef %msg) #0 {
entry:
%msg.addr = alloca ptr, align 8
%b = alloca [1000 x i8], align 1
store ptr %msg, ptr %msg.addr, align 8
%arraydecay = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
%0 = load ptr, ptr %msg.addr, align 8
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
ret void
}
; sspreq protects every function unconditionally, so the metadata is ignored
; there and test3 still gets a guard despite carrying it.
; CHECK-LABEL: test3:
; CHECK: ___stack_chk_guard
; Function Attrs: noinline nounwind optnone
define void @test3(ptr noundef %msg) #4 {
entry:
%msg.addr = alloca ptr, align 8
%a = alloca [1000 x i8], align 1, !stack-protector !2
store ptr %msg, ptr %msg.addr, align 8
%arraydecay = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
%0 = load ptr, ptr %msg.addr, align 8
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
ret void
}
; Control for test3: same function without the metadata, also protected.
; CHECK-LABEL: test4:
; CHECK: ___stack_chk_guard
; Function Attrs: noinline nounwind optnone
define void @test4(ptr noundef %msg) #4 {
entry:
%msg.addr = alloca ptr, align 8
%b = alloca [1000 x i8], align 1
store ptr %msg, ptr %msg.addr, align 8
%arraydecay = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
%0 = load ptr, ptr %msg.addr, align 8
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
ret void
}
; sspstrong honors the metadata, like ssp.
; CHECK-LABEL: test5:
; CHECK-NOT: ___stack_chk_guard
; Function Attrs: noinline nounwind optnone
define void @test5(ptr noundef %msg) #5 {
entry:
%msg.addr = alloca ptr, align 8
%a = alloca [1000 x i8], align 1, !stack-protector !2
store ptr %msg, ptr %msg.addr, align 8
%arraydecay = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
%0 = load ptr, ptr %msg.addr, align 8
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %a, i64 0, i64 0
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
ret void
}
; Control for test5: same function without the metadata, protected.
; CHECK-LABEL: test6:
; CHECK: ___stack_chk_guard
; Function Attrs: noinline nounwind optnone
define void @test6(ptr noundef %msg) #5 {
entry:
%msg.addr = alloca ptr, align 8
%b = alloca [1000 x i8], align 1
store ptr %msg, ptr %msg.addr, align 8
%arraydecay = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
%0 = load ptr, ptr %msg.addr, align 8
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %0) #3
%arraydecay1 = getelementptr inbounds [1000 x i8], ptr %b, i64 0, i64 0
%call2 = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %arraydecay1)
ret void
}
; Function Attrs: nounwind
declare ptr @strcpy(ptr noundef, ptr noundef) #1
declare i32 @printf(ptr noundef, ...) #2
attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" ssp }
attributes #1 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #3 = { nounwind }
attributes #4 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" sspreq }
attributes #5 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" sspstrong }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 22.0.0"}
!2 = !{i32 0}