
This patch addresses the signed/zero extension of poison by using a poison value of the extended type instead of a constant zero of the extended type.
188 lines
5.8 KiB
LLVM
188 lines
5.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
|
|
; RUN: llc -mtriple=x86_64-pc-linux -stackrealign -verify-machineinstrs < %s | FileCheck %s
|
|
|
|
; Calling convention ghccc uses ebp to pass parameter, so calling a function
|
|
; using ghccc clobbers ebp. We should save and restore ebp around such a call
|
|
; if ebp is used as frame pointer.
|
|
|
|
declare ghccc i32 @external(i32)
|
|
|
|
; Basic test with ghccc calling convention.
|
|
define i32 @test1(i32 %0, i32 %1) {
|
|
; CHECK-LABEL: test1:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: .cfi_offset %rbp, -16
|
|
; CHECK-NEXT: movq %rsp, %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_register %rbp
|
|
; CHECK-NEXT: pushq %r15
|
|
; CHECK-NEXT: pushq %r14
|
|
; CHECK-NEXT: pushq %r13
|
|
; CHECK-NEXT: pushq %r12
|
|
; CHECK-NEXT: pushq %rbx
|
|
; CHECK-NEXT: andq $-16, %rsp
|
|
; CHECK-NEXT: subq $16, %rsp
|
|
; CHECK-NEXT: .cfi_offset %rbx, -56
|
|
; CHECK-NEXT: .cfi_offset %r12, -48
|
|
; CHECK-NEXT: .cfi_offset %r13, -40
|
|
; CHECK-NEXT: .cfi_offset %r14, -32
|
|
; CHECK-NEXT: .cfi_offset %r15, -24
|
|
; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_remember_state
|
|
; CHECK-NEXT: .cfi_escape 0x0f, 0x06, 0x77, 0x08, 0x06, 0x11, 0x10, 0x22 #
|
|
; CHECK-NEXT: movl %esi, %ebp
|
|
; CHECK-NEXT: movq %rdi, %r13
|
|
; CHECK-NEXT: callq external@PLT
|
|
; CHECK-NEXT: addq $8, %rsp
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_restore_state
|
|
; CHECK-NEXT: leaq -40(%rbp), %rsp
|
|
; CHECK-NEXT: popq %rbx
|
|
; CHECK-NEXT: popq %r12
|
|
; CHECK-NEXT: popq %r13
|
|
; CHECK-NEXT: popq %r14
|
|
; CHECK-NEXT: popq %r15
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
|
|
; CHECK-NEXT: retq
|
|
%x = call ghccc i32 @external(i32 %0, i32 %1)
|
|
ret i32 %x
|
|
}
|
|
|
|
; Calling convention hipe has similar behavior. It clobbers rbp but not rbx.
|
|
|
|
declare cc 11 i64 @hipe1(i64)
|
|
declare cc 11 i64 @hipe2(i64, i64, i64, i64, i64, i64, i64)
|
|
|
|
; Basic test with hipe calling convention.
|
|
define i64 @test2(i64 %a0, i64 %a1) {
|
|
; CHECK-LABEL: test2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: .cfi_offset %rbp, -16
|
|
; CHECK-NEXT: movq %rsp, %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_register %rbp
|
|
; CHECK-NEXT: pushq %r15
|
|
; CHECK-NEXT: pushq %r14
|
|
; CHECK-NEXT: pushq %r13
|
|
; CHECK-NEXT: pushq %r12
|
|
; CHECK-NEXT: pushq %rbx
|
|
; CHECK-NEXT: andq $-16, %rsp
|
|
; CHECK-NEXT: subq $16, %rsp
|
|
; CHECK-NEXT: .cfi_offset %rbx, -56
|
|
; CHECK-NEXT: .cfi_offset %r12, -48
|
|
; CHECK-NEXT: .cfi_offset %r13, -40
|
|
; CHECK-NEXT: .cfi_offset %r14, -32
|
|
; CHECK-NEXT: .cfi_offset %r15, -24
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_remember_state
|
|
; CHECK-NEXT: .cfi_escape 0x0f, 0x06, 0x77, 0x08, 0x06, 0x11, 0x10, 0x22 #
|
|
; CHECK-NEXT: movq %rsi, %rbp
|
|
; CHECK-NEXT: movq %rdi, %r15
|
|
; CHECK-NEXT: callq hipe1@PLT
|
|
; CHECK-NEXT: addq $8, %rsp
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_restore_state
|
|
; CHECK-NEXT: movq %r15, %rax
|
|
; CHECK-NEXT: leaq -40(%rbp), %rsp
|
|
; CHECK-NEXT: popq %rbx
|
|
; CHECK-NEXT: popq %r12
|
|
; CHECK-NEXT: popq %r13
|
|
; CHECK-NEXT: popq %r14
|
|
; CHECK-NEXT: popq %r15
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
|
|
; CHECK-NEXT: retq
|
|
%x = call cc 11 i64 @hipe1(i64 %a0, i64 %a1)
|
|
ret i64 %x
|
|
}
|
|
|
|
@buf = dso_local global [20 x ptr] zeroinitializer, align 16
|
|
|
|
; longjmp modifies fp, it is expected behavior, wo should not save/restore fp
|
|
; around it.
|
|
define void @test4() {
|
|
; CHECK-LABEL: test4:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: .cfi_offset %rbp, -16
|
|
; CHECK-NEXT: movq %rsp, %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_register %rbp
|
|
; CHECK-NEXT: pushq %r15
|
|
; CHECK-NEXT: pushq %r14
|
|
; CHECK-NEXT: pushq %r13
|
|
; CHECK-NEXT: pushq %r12
|
|
; CHECK-NEXT: pushq %rbx
|
|
; CHECK-NEXT: andq $-16, %rsp
|
|
; CHECK-NEXT: subq $16, %rsp
|
|
; CHECK-NEXT: .cfi_offset %rbx, -56
|
|
; CHECK-NEXT: .cfi_offset %r12, -48
|
|
; CHECK-NEXT: .cfi_offset %r13, -40
|
|
; CHECK-NEXT: .cfi_offset %r14, -32
|
|
; CHECK-NEXT: .cfi_offset %r15, -24
|
|
; CHECK-NEXT: xorl %r13d, %r13d
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: pushq %rax
|
|
; CHECK-NEXT: .cfi_remember_state
|
|
; CHECK-NEXT: .cfi_escape 0x0f, 0x06, 0x77, 0x08, 0x06, 0x11, 0x10, 0x22 #
|
|
; CHECK-NEXT: callq external@PLT
|
|
; CHECK-NEXT: addq $8, %rsp
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_restore_state
|
|
; CHECK-NEXT: movq buf(%rip), %rbp
|
|
; CHECK-NEXT: movq buf+8(%rip), %rax
|
|
; CHECK-NEXT: movq buf+16(%rip), %rsp
|
|
; CHECK-NEXT: jmpq *%rax
|
|
entry:
|
|
%x = call ghccc i32 @external(i32 0)
|
|
call void @llvm.eh.sjlj.longjmp(ptr @buf)
|
|
unreachable
|
|
}
|
|
|
|
declare ghccc void @tail()
|
|
|
|
; We should not save/restore fp/bp around terminator.
|
|
define ghccc void @test5() {
|
|
; CHECK-LABEL: test5:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: pushq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-NEXT: .cfi_offset %rbp, -16
|
|
; CHECK-NEXT: movq %rsp, %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa_register %rbp
|
|
; CHECK-NEXT: andq $-8, %rsp
|
|
; CHECK-NEXT: testb %al, %al
|
|
; CHECK-NEXT: jne .LBB3_2
|
|
; CHECK-NEXT: # %bb.1: # %then
|
|
; CHECK-NEXT: movq $0, (%rax)
|
|
; CHECK-NEXT: movq %rbp, %rsp
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
|
|
; CHECK-NEXT: retq
|
|
; CHECK-NEXT: .LBB3_2: # %else
|
|
; CHECK-NEXT: .cfi_def_cfa %rbp, 16
|
|
; CHECK-NEXT: movq %rbp, %rsp
|
|
; CHECK-NEXT: popq %rbp
|
|
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
|
|
; CHECK-NEXT: jmp tail@PLT # TAILCALL
|
|
entry:
|
|
br i1 poison, label %then, label %else
|
|
|
|
then:
|
|
store i64 0, ptr undef
|
|
br label %exit
|
|
|
|
else:
|
|
musttail call ghccc void @tail()
|
|
ret void
|
|
|
|
exit:
|
|
ret void
|
|
}
|