| ; RUN: llc -mtriple aarch64-linux-gnu -mattr=+pauth -asm-verbose=false -disable-post-ra -o - %s | FileCheck %s |
| |
| ; CHECK-LABEL: test_tailcall: |
| ; CHECK-NEXT: pacibsp |
| ; CHECK-NEXT: str x30, [sp, #-16]! |
| ; CHECK-NEXT: bl bar |
| ; CHECK-NEXT: ldr x30, [sp], #16 |
| ; CHECK-NEXT: autibsp |
| ; CHECK-NEXT: eor x16, x30, x30, lsl #1 |
| ; CHECK-NEXT: tbz x16, #62, [[GOOD:.L.*]] |
| ; CHECK-NEXT: brk #0xc471 |
| ; CHECK-NEXT: [[GOOD]]: |
| ; CHECK-NEXT: b bar |
| define i32 @test_tailcall() #0 { |
| call i32 @bar() |
| %c = tail call i32 @bar() |
| ret i32 %c |
| } |
| |
| ; CHECK-LABEL: test_tailcall_noframe: |
| ; CHECK-NEXT: b bar |
| define i32 @test_tailcall_noframe() #0 { |
| %c = tail call i32 @bar() |
| ret i32 %c |
| } |
| |
| ; CHECK-LABEL: test_tailcall_indirect: |
| ; CHECK: autibsp |
| ; CHECK: eor x16, x30, x30, lsl #1 |
| ; CHECK: tbz x16, #62, [[GOOD:.L.*]] |
| ; CHECK: brk #0xc471 |
| ; CHECK: [[GOOD]]: |
| ; CHECK: br x0 |
| define void @test_tailcall_indirect(ptr %fptr) #0 { |
| call i32 @test_tailcall() |
| tail call void %fptr() |
| ret void |
| } |
| |
| ; CHECK-LABEL: test_tailcall_indirect_in_x9: |
| ; CHECK: autibsp |
| ; CHECK: eor x16, x30, x30, lsl #1 |
| ; CHECK: tbz x16, #62, [[GOOD:.L.*]] |
| ; CHECK: brk #0xc471 |
| ; CHECK: [[GOOD]]: |
| ; CHECK: br x9 |
| define void @test_tailcall_indirect_in_x9(ptr sret(i64) %ret, [8 x i64] %in, ptr %fptr) #0 { |
| %ptr = alloca i8, i32 16 |
| call i32 @test_tailcall() |
| tail call void %fptr(ptr sret(i64) %ret, [8 x i64] %in) |
| ret void |
| } |
| |
| ; CHECK-LABEL: test_auth_tailcall_indirect: |
| ; CHECK: autibsp |
| ; CHECK: eor x16, x30, x30, lsl #1 |
| ; CHECK: tbz x16, #62, [[GOOD:.L.*]] |
| ; CHECK: brk #0xc471 |
| ; CHECK: [[GOOD]]: |
| ; CHECK: mov x16, #42 |
| ; CHECK: braa x0, x16 |
| define void @test_auth_tailcall_indirect(ptr %fptr) #0 { |
| call i32 @test_tailcall() |
| tail call void %fptr() [ "ptrauth"(i32 0, i64 42) ] |
| ret void |
| } |
| |
| ; CHECK-LABEL: test_auth_tailcall_indirect_in_x9: |
| ; CHECK: autibsp |
| ; CHECK: eor x16, x30, x30, lsl #1 |
| ; CHECK: tbz x16, #62, [[GOOD:.L.*]] |
| ; CHECK: brk #0xc471 |
| ; CHECK: [[GOOD]]: |
| ; CHECK: brabz x9 |
| define void @test_auth_tailcall_indirect_in_x9(ptr sret(i64) %ret, [8 x i64] %in, ptr %fptr) #0 { |
| %ptr = alloca i8, i32 16 |
| call i32 @test_tailcall() |
| tail call void %fptr(ptr sret(i64) %ret, [8 x i64] %in) [ "ptrauth"(i32 1, i64 0) ] |
| ret void |
| } |
| |
| ; CHECK-LABEL: test_auth_tailcall_indirect_bti: |
| ; CHECK: autibsp |
| ; CHECK: eor x17, x30, x30, lsl #1 |
| ; CHECK: tbz x17, #62, [[GOOD:.L.*]] |
| ; CHECK: brk #0xc471 |
| ; CHECK: [[GOOD]]: |
| ; CHECK: brabz x16 |
| define void @test_auth_tailcall_indirect_bti(ptr sret(i64) %ret, [8 x i64] %in, ptr %fptr) #0 "branch-target-enforcement"="true" { |
| %ptr = alloca i8, i32 16 |
| call i32 @test_tailcall() |
| tail call void %fptr(ptr sret(i64) %ret, [8 x i64] %in) [ "ptrauth"(i32 1, i64 0) ] |
| ret void |
| } |
| |
| declare i32 @bar() |
| |
| attributes #0 = { nounwind "ptrauth-returns" "ptrauth-auth-traps" } |