Changeset View
Changeset View
Standalone View
Standalone View
llvm/test/CodeGen/AArch64/arm64ec-cfg.ll
- This file was added.
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs | |||||
; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s | FileCheck %s | |||||
define void @f(ptr %g) { | |||||
entry: | |||||
call void %g() | |||||
ret void | |||||
} | |||||
define void @f2(ptr %g) { | |||||
entry: | |||||
call void %g(i32 1, i32 2, i32 3, i32 4, i32 5) | |||||
ret void | |||||
} | |||||
define void @f3(ptr %g) { | |||||
entry: | |||||
call void %g([4 x float] zeroinitializer) | |||||
ret void | |||||
} | |||||
; CHECK-LABEL: f: | |||||
; CHECK: .seh_proc f | |||||
; CHECK-NEXT: // %bb.0: // %entry | |||||
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |||||
; CHECK-NEXT: .seh_save_reg_x x30, 16 | |||||
; CHECK-NEXT: .seh_endprologue | |||||
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall | |||||
; CHECK-NEXT: adrp x10, thunk | |||||
; CHECK-NEXT: add x10, x10, :lo12:thunk | |||||
; CHECK-NEXT: mov x11, x0 | |||||
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall] | |||||
; CHECK-NEXT: blr x8 | |||||
; CHECK-NEXT: blr x11 | |||||
; CHECK-NEXT: .seh_startepilogue | |||||
dpaoliello: Yeah, this isn't right: indirect calls should be transformed like this, but direct calls… | |||||
I'm not sure what isn't right here, specifically? In this testcase, all the calls are indirect. And we can't call __os_arm64x_check_icall directly, I think; __os_arm64x_check_icall is the address of the function, not the function itself. (I don't think there's any rule that says we *can't* transform direct calls this way, but probably we shouldn't.) efriedma: I'm not sure what isn't right here, specifically?
In this testcase, all the calls are indirect. | |||||
Not Done ReplyInline ActionsAh, sorry, I misread the code. Yeah, this is correct - although it looks like we should add some direct-call cases then :) dpaoliello: Ah, sorry, I misread the code. Yeah, this is correct - although it looks like we should add… | |||||
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |||||
; CHECK-NEXT: .seh_save_reg_x x30, 16 | |||||
; CHECK-NEXT: .seh_endepilogue | |||||
; CHECK-NEXT: ret | |||||
; CHECK-NEXT: .seh_endfunclet | |||||
; CHECK-NEXT: .seh_endproc | |||||
; | |||||
; CHECK-LABEL: f2: | |||||
; CHECK: .seh_proc f2 | |||||
; CHECK-NEXT: // %bb.0: // %entry | |||||
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |||||
; CHECK-NEXT: .seh_save_reg_x x30, 16 | |||||
; CHECK-NEXT: .seh_endprologue | |||||
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall | |||||
; CHECK-NEXT: adrp x10, thunk.1 | |||||
; CHECK-NEXT: add x10, x10, :lo12:thunk.1 | |||||
; CHECK-NEXT: mov x11, x0 | |||||
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall] | |||||
; CHECK-NEXT: blr x8 | |||||
; CHECK-NEXT: mov w0, #1 | |||||
; CHECK-NEXT: mov w1, #2 | |||||
; CHECK-NEXT: mov w2, #3 | |||||
; CHECK-NEXT: mov w3, #4 | |||||
; CHECK-NEXT: mov w4, #5 | |||||
; CHECK-NEXT: blr x11 | |||||
; CHECK-NEXT: .seh_startepilogue | |||||
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |||||
; CHECK-NEXT: .seh_save_reg_x x30, 16 | |||||
; CHECK-NEXT: .seh_endepilogue | |||||
; CHECK-NEXT: ret | |||||
; CHECK-NEXT: .seh_endfunclet | |||||
; CHECK-NEXT: .seh_endproc | |||||
; | |||||
; CHECK-LABEL: f3: | |||||
; CHECK: .seh_proc f3 | |||||
; CHECK-NEXT: // %bb.0: // %entry | |||||
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill | |||||
; CHECK-NEXT: .seh_save_reg_x x30, 16 | |||||
; CHECK-NEXT: .seh_endprologue | |||||
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall | |||||
; CHECK-NEXT: adrp x10, thunk.2 | |||||
; CHECK-NEXT: add x10, x10, :lo12:thunk.2 | |||||
; CHECK-NEXT: mov x11, x0 | |||||
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall] | |||||
; CHECK-NEXT: blr x8 | |||||
; CHECK-NEXT: movi d0, #0000000000000000 | |||||
; CHECK-NEXT: movi d1, #0000000000000000 | |||||
; CHECK-NEXT: movi d2, #0000000000000000 | |||||
; CHECK-NEXT: movi d3, #0000000000000000 | |||||
; CHECK-NEXT: blr x11 | |||||
; CHECK-NEXT: .seh_startepilogue | |||||
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload | |||||
; CHECK-NEXT: .seh_save_reg_x x30, 16 | |||||
; CHECK-NEXT: .seh_endepilogue | |||||
; CHECK-NEXT: ret | |||||
; CHECK-NEXT: .seh_endfunclet | |||||
; CHECK-NEXT: .seh_endproc | |||||
; | |||||
; CHECK-LABEL: thunk: | |||||
; CHECK: .seh_proc thunk | |||||
; CHECK-NEXT: // %bb.0: | |||||
; CHECK-NEXT: sub sp, sp, #48 | |||||
; CHECK-NEXT: .seh_stackalloc 48 | |||||
; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill | |||||
; CHECK-NEXT: .seh_save_fplr 32 | |||||
; CHECK-NEXT: add x29, sp, #32 | |||||
; CHECK-NEXT: .seh_add_fp 32 | |||||
; CHECK-NEXT: .seh_endprologue | |||||
; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect | |||||
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect] | |||||
; CHECK-NEXT: blr x8 | |||||
; CHECK-NEXT: .seh_startepilogue | |||||
; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload | |||||
; CHECK-NEXT: .seh_save_fplr 32 | |||||
; CHECK-NEXT: add sp, sp, #48 | |||||
; CHECK-NEXT: .seh_stackalloc 48 | |||||
; CHECK-NEXT: .seh_endepilogue | |||||
; CHECK-NEXT: ret | |||||
; CHECK-NEXT: .seh_endfunclet | |||||
; CHECK-NEXT: .seh_endproc | |||||
; | |||||
; CHECK-LABEL: thunk.1: | |||||
; CHECK: .seh_proc thunk.1 | |||||
; CHECK-NEXT: // %bb.0: | |||||
; CHECK-NEXT: sub sp, sp, #64 | |||||
; CHECK-NEXT: .seh_stackalloc 64 | |||||
; CHECK-NEXT: stp x29, x30, [sp, #48] // 16-byte Folded Spill | |||||
; CHECK-NEXT: .seh_save_fplr 48 | |||||
; CHECK-NEXT: add x29, sp, #48 | |||||
; CHECK-NEXT: .seh_add_fp 48 | |||||
; CHECK-NEXT: .seh_endprologue | |||||
; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect | |||||
; CHECK-NEXT: str w4, [sp, #32] | |||||
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect] | |||||
; CHECK-NEXT: blr x8 | |||||
; CHECK-NEXT: .seh_startepilogue | |||||
; CHECK-NEXT: ldp x29, x30, [sp, #48] // 16-byte Folded Reload | |||||
; CHECK-NEXT: .seh_save_fplr 48 | |||||
; CHECK-NEXT: add sp, sp, #64 | |||||
; CHECK-NEXT: .seh_stackalloc 64 | |||||
; CHECK-NEXT: .seh_endepilogue | |||||
; CHECK-NEXT: ret | |||||
; CHECK-NEXT: .seh_endfunclet | |||||
; CHECK-NEXT: .seh_endproc | |||||
; | |||||
; CHECK-LABEL: thunk.2: | |||||
; CHECK: .seh_proc thunk.2 | |||||
; CHECK-NEXT: // %bb.0: | |||||
; CHECK-NEXT: sub sp, sp, #64 | |||||
; CHECK-NEXT: .seh_stackalloc 64 | |||||
; CHECK-NEXT: stp x29, x30, [sp, #48] // 16-byte Folded Spill | |||||
; CHECK-NEXT: .seh_save_fplr 48 | |||||
; CHECK-NEXT: add x29, sp, #48 | |||||
; CHECK-NEXT: .seh_add_fp 48 | |||||
; CHECK-NEXT: .seh_endprologue | |||||
; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect | |||||
; CHECK-NEXT: sub x0, x29, #16 | |||||
; CHECK-NEXT: stp s1, s2, [x29, #-12] | |||||
; CHECK-NEXT: stur s0, [x29, #-16] | |||||
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect] | |||||
; CHECK-NEXT: stur s3, [x29, #-4] | |||||
; CHECK-NEXT: blr x8 | |||||
; CHECK-NEXT: .seh_startepilogue | |||||
; CHECK-NEXT: ldp x29, x30, [sp, #48] // 16-byte Folded Reload | |||||
; CHECK-NEXT: .seh_save_fplr 48 | |||||
; CHECK-NEXT: add sp, sp, #64 | |||||
; CHECK-NEXT: .seh_stackalloc 64 | |||||
; CHECK-NEXT: .seh_endepilogue | |||||
; CHECK-NEXT: ret | |||||
; CHECK-NEXT: .seh_endfunclet | |||||
; CHECK-NEXT: .seh_endproc |
Yeah, this isn't right: indirect calls should be transformed like this, but direct calls shouldn't be changed. It's the linker's responsibility to rewrite direct calls (it will lookup the thunk by name).