; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=+cmov -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefix=X86 ; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=+cmov -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=X86-GISEL ; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=+cmov -fast-isel=0 -global-isel=0 | FileCheck %s --check-prefix=X86 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel -fast-isel-abort=1 | FileCheck %s --check-prefix=X64 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=X64-GISEL ; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel=0 -global-isel=0 | FileCheck %s --check-prefix=X64 ; Test that we can generate an fcmove, and also that it passes verification. define x86_fp80 @cmove_cmp(x86_fp80 %a, x86_fp80 %b, i32 %c) { ; X86-LABEL: cmove_cmp: ; X86: # %bb.0: ; X86-NEXT: fldt {{[0-9]+}}(%esp) ; X86-NEXT: fldt {{[0-9]+}}(%esp) ; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp) ; X86-NEXT: fadd %st(1), %st ; X86-NEXT: fxch %st(1) ; X86-NEXT: fcmove %st(1), %st ; X86-NEXT: fstp %st(1) ; X86-NEXT: retl ; ; X86-GISEL-LABEL: cmove_cmp: ; X86-GISEL: # %bb.0: ; X86-GISEL-NEXT: fldt {{[0-9]+}}(%esp) ; X86-GISEL-NEXT: fldt {{[0-9]+}}(%esp) ; X86-GISEL-NEXT: xorl %eax, %eax ; X86-GISEL-NEXT: cmpl $0, {{[0-9]+}}(%esp) ; X86-GISEL-NEXT: sete %al ; X86-GISEL-NEXT: fadd %st, %st(1) ; X86-GISEL-NEXT: andl $1, %eax ; X86-GISEL-NEXT: testl %eax, %eax ; X86-GISEL-NEXT: fxch %st(1) ; X86-GISEL-NEXT: fcmove %st(1), %st ; X86-GISEL-NEXT: fstp %st(1) ; X86-GISEL-NEXT: retl ; ; X64-LABEL: cmove_cmp: ; X64: # %bb.0: ; X64-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-NEXT: testl %edi, %edi ; X64-NEXT: fadd %st(1), %st ; X64-NEXT: fxch %st(1) ; X64-NEXT: fcmove %st(1), %st ; X64-NEXT: fstp %st(1) ; X64-NEXT: retq ; ; X64-GISEL-LABEL: cmove_cmp: ; X64-GISEL: # %bb.0: ; X64-GISEL-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-GISEL-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-GISEL-NEXT: xorl %eax, %eax ; X64-GISEL-NEXT: cmpl $0, %edi ; X64-GISEL-NEXT: sete %al ; X64-GISEL-NEXT: fadd %st, %st(1) ; X64-GISEL-NEXT: andl $1, %eax ; X64-GISEL-NEXT: testl %eax, %eax ; X64-GISEL-NEXT: fxch %st(1) ; X64-GISEL-NEXT: fcmove %st(1), %st ; X64-GISEL-NEXT: fstp %st(1) ; X64-GISEL-NEXT: retq %test = icmp eq i32 %c, 0 %add = fadd x86_fp80 %a, %b %ret = select i1 %test, x86_fp80 %add, x86_fp80 %b ret x86_fp80 %ret } define x86_fp80 @cmove_arg(x86_fp80 %a, x86_fp80 %b, i1 %test) { ; X86-LABEL: cmove_arg: ; X86: # %bb.0: ; X86-NEXT: fldt {{[0-9]+}}(%esp) ; X86-NEXT: fldt {{[0-9]+}}(%esp) ; X86-NEXT: fadd %st(1), %st ; X86-NEXT: testb $1, {{[0-9]+}}(%esp) ; X86-NEXT: fxch %st(1) ; X86-NEXT: fcmovne %st(1), %st ; X86-NEXT: fstp %st(1) ; X86-NEXT: retl ; ; X86-GISEL-LABEL: cmove_arg: ; X86-GISEL: # %bb.0: ; X86-GISEL-NEXT: fldt {{[0-9]+}}(%esp) ; X86-GISEL-NEXT: fldt {{[0-9]+}}(%esp) ; X86-GISEL-NEXT: fadd %st, %st(1) ; X86-GISEL-NEXT: movl $1, %eax ; X86-GISEL-NEXT: andl {{[0-9]+}}(%esp), %eax ; X86-GISEL-NEXT: testl %eax, %eax ; X86-GISEL-NEXT: fxch %st(1) ; X86-GISEL-NEXT: fcmove %st(1), %st ; X86-GISEL-NEXT: fstp %st(1) ; X86-GISEL-NEXT: retl ; ; X64-LABEL: cmove_arg: ; X64: # %bb.0: ; X64-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-NEXT: fadd %st(1), %st ; X64-NEXT: testb $1, %dil ; X64-NEXT: fxch %st(1) ; X64-NEXT: fcmovne %st(1), %st ; X64-NEXT: fstp %st(1) ; X64-NEXT: retq ; ; X64-GISEL-LABEL: cmove_arg: ; X64-GISEL: # %bb.0: ; X64-GISEL-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-GISEL-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-GISEL-NEXT: fadd %st, %st(1) ; X64-GISEL-NEXT: andl $1, %edi ; X64-GISEL-NEXT: testl %edi, %edi ; X64-GISEL-NEXT: fxch %st(1) ; X64-GISEL-NEXT: fcmove %st(1), %st ; X64-GISEL-NEXT: fstp %st(1) ; X64-GISEL-NEXT: retq %add = fadd x86_fp80 %a, %b %ret = select i1 %test, x86_fp80 %add, x86_fp80 %b ret x86_fp80 %ret } define x86_fp80 @cmove_load(x86_fp80 %a, x86_fp80 %b, ptr %p) { ; X86-LABEL: cmove_load: ; X86: # %bb.0: ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ; X86-NEXT: fldt {{[0-9]+}}(%esp) ; X86-NEXT: fldt {{[0-9]+}}(%esp) ; X86-NEXT: fadd %st(1), %st ; X86-NEXT: cmpb $0, (%eax) ; X86-NEXT: fxch %st(1) ; X86-NEXT: fcmovne %st(1), %st ; X86-NEXT: fstp %st(1) ; X86-NEXT: retl ; ; X86-GISEL-LABEL: cmove_load: ; X86-GISEL: # %bb.0: ; X86-GISEL-NEXT: fldt {{[0-9]+}}(%esp) ; X86-GISEL-NEXT: fldt {{[0-9]+}}(%esp) ; X86-GISEL-NEXT: movl {{[0-9]+}}(%esp), %eax ; X86-GISEL-NEXT: fadd %st, %st(1) ; X86-GISEL-NEXT: movzbl (%eax), %eax ; X86-GISEL-NEXT: andl $1, %eax ; X86-GISEL-NEXT: testl %eax, %eax ; X86-GISEL-NEXT: fxch %st(1) ; X86-GISEL-NEXT: fcmove %st(1), %st ; X86-GISEL-NEXT: fstp %st(1) ; X86-GISEL-NEXT: retl ; ; X64-LABEL: cmove_load: ; X64: # %bb.0: ; X64-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-NEXT: fadd %st(1), %st ; X64-NEXT: cmpb $0, (%rdi) ; X64-NEXT: fxch %st(1) ; X64-NEXT: fcmovne %st(1), %st ; X64-NEXT: fstp %st(1) ; X64-NEXT: retq ; ; X64-GISEL-LABEL: cmove_load: ; X64-GISEL: # %bb.0: ; X64-GISEL-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-GISEL-NEXT: fldt {{[0-9]+}}(%rsp) ; X64-GISEL-NEXT: fadd %st, %st(1) ; X64-GISEL-NEXT: movzbl (%rdi), %eax ; X64-GISEL-NEXT: andl $1, %eax ; X64-GISEL-NEXT: testl %eax, %eax ; X64-GISEL-NEXT: fxch %st(1) ; X64-GISEL-NEXT: fcmove %st(1), %st ; X64-GISEL-NEXT: fstp %st(1) ; X64-GISEL-NEXT: retq %test = load i1, ptr %p %add = fadd x86_fp80 %a, %b %ret = select i1 %test, x86_fp80 %add, x86_fp80 %b ret x86_fp80 %ret }