| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: llc < %s -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes X64,SDAG-X64 |
| ; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes X64,GISEL-X64 |
| ; RUN: llc < %s -mattr=+avx512f -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes AVX512,SDAG-AVX512 |
| ; RUN: llc < %s -global-isel -global-isel-abort=1 -mattr=+avx512f -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s --check-prefixes AVX512,GISEL-AVX512 |
| |
| define double @test_ui64_to_double(i64 %x) { |
| ; SDAG-X64-LABEL: test_ui64_to_double: |
| ; SDAG-X64: # %bb.0: # %entry |
| ; SDAG-X64-NEXT: movq %rdi, %xmm1 |
| ; SDAG-X64-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[1],mem[1] |
| ; SDAG-X64-NEXT: subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 |
| ; SDAG-X64-NEXT: movapd %xmm1, %xmm0 |
| ; SDAG-X64-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1] |
| ; SDAG-X64-NEXT: addsd %xmm1, %xmm0 |
| ; SDAG-X64-NEXT: retq |
| ; |
| ; GISEL-X64-LABEL: test_ui64_to_double: |
| ; GISEL-X64: # %bb.0: # %entry |
| ; GISEL-X64-NEXT: movabsq $4841369599423283200, %rax # imm = 0x4330000000000000 |
| ; GISEL-X64-NEXT: movabsq $4985484787499139072, %rcx # imm = 0x4530000000000000 |
| ; GISEL-X64-NEXT: movsd {{.*#+}} xmm0 = [1.9342813118337666E+25,0.0E+0] |
| ; GISEL-X64-NEXT: movl $4294967295, %edx # imm = 0xFFFFFFFF |
| ; GISEL-X64-NEXT: andq %rdi, %rdx |
| ; GISEL-X64-NEXT: orq %rax, %rdx |
| ; GISEL-X64-NEXT: shrq $32, %rdi |
| ; GISEL-X64-NEXT: orq %rdi, %rcx |
| ; GISEL-X64-NEXT: movq %rcx, %xmm1 |
| ; GISEL-X64-NEXT: subsd %xmm0, %xmm1 |
| ; GISEL-X64-NEXT: movq %rdx, %xmm0 |
| ; GISEL-X64-NEXT: addsd %xmm1, %xmm0 |
| ; GISEL-X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_ui64_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtusi2sd %rdi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i64 %x to double |
| ret double %conv |
| } |
| |
| define double @test_ui32_to_double(i32 %x) { |
| ; X64-LABEL: test_ui32_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: movl %edi, %eax |
| ; X64-NEXT: cvtsi2sd %rax, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_ui32_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtusi2sd %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i32 %x to double |
| ret double %conv |
| } |
| |
| define double @test_ui16_to_double(i16 zeroext %x) { |
| ; X64-LABEL: test_ui16_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2sd %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; SDAG-AVX512-LABEL: test_ui16_to_double: |
| ; SDAG-AVX512: # %bb.0: # %entry |
| ; SDAG-AVX512-NEXT: vcvtsi2sd %edi, %xmm0, %xmm0 |
| ; SDAG-AVX512-NEXT: retq |
| ; |
| ; GISEL-AVX512-LABEL: test_ui16_to_double: |
| ; GISEL-AVX512: # %bb.0: # %entry |
| ; GISEL-AVX512-NEXT: vcvtusi2sd %edi, %xmm0, %xmm0 |
| ; GISEL-AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i16 %x to double |
| ret double %conv |
| } |
| |
| define double @test_ui8_to_double(i8 zeroext %x) { |
| ; X64-LABEL: test_ui8_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2sd %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; SDAG-AVX512-LABEL: test_ui8_to_double: |
| ; SDAG-AVX512: # %bb.0: # %entry |
| ; SDAG-AVX512-NEXT: vcvtsi2sd %edi, %xmm0, %xmm0 |
| ; SDAG-AVX512-NEXT: retq |
| ; |
| ; GISEL-AVX512-LABEL: test_ui8_to_double: |
| ; GISEL-AVX512: # %bb.0: # %entry |
| ; GISEL-AVX512-NEXT: vcvtusi2sd %edi, %xmm0, %xmm0 |
| ; GISEL-AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i8 %x to double |
| ret double %conv |
| } |
| |
| define float @test_ui64_to_float(i64 %x) { |
| ; SDAG-X64-LABEL: test_ui64_to_float: |
| ; SDAG-X64: # %bb.0: # %entry |
| ; SDAG-X64-NEXT: testq %rdi, %rdi |
| ; SDAG-X64-NEXT: js .LBB4_1 |
| ; SDAG-X64-NEXT: # %bb.2: # %entry |
| ; SDAG-X64-NEXT: cvtsi2ss %rdi, %xmm0 |
| ; SDAG-X64-NEXT: retq |
| ; SDAG-X64-NEXT: .LBB4_1: |
| ; SDAG-X64-NEXT: movq %rdi, %rax |
| ; SDAG-X64-NEXT: shrq %rax |
| ; SDAG-X64-NEXT: andl $1, %edi |
| ; SDAG-X64-NEXT: orq %rax, %rdi |
| ; SDAG-X64-NEXT: cvtsi2ss %rdi, %xmm0 |
| ; SDAG-X64-NEXT: addss %xmm0, %xmm0 |
| ; SDAG-X64-NEXT: retq |
| ; |
| ; GISEL-X64-LABEL: test_ui64_to_float: |
| ; GISEL-X64: # %bb.0: # %entry |
| ; GISEL-X64-NEXT: cvtsi2ss %rdi, %xmm0 |
| ; GISEL-X64-NEXT: movq %rdi, %rax |
| ; GISEL-X64-NEXT: shrq %rax |
| ; GISEL-X64-NEXT: movq %rdi, %rcx |
| ; GISEL-X64-NEXT: andq $1, %rcx |
| ; GISEL-X64-NEXT: orq %rax, %rcx |
| ; GISEL-X64-NEXT: cvtsi2ss %rcx, %xmm1 |
| ; GISEL-X64-NEXT: addss %xmm1, %xmm1 |
| ; GISEL-X64-NEXT: xorl %eax, %eax |
| ; GISEL-X64-NEXT: cmpq $0, %rdi |
| ; GISEL-X64-NEXT: setl %al |
| ; GISEL-X64-NEXT: andl $1, %eax |
| ; GISEL-X64-NEXT: movd %xmm1, %eax |
| ; GISEL-X64-NEXT: movd %xmm0, %ecx |
| ; GISEL-X64-NEXT: cmovnel %eax, %ecx |
| ; GISEL-X64-NEXT: movd %ecx, %xmm0 |
| ; GISEL-X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_ui64_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtusi2ss %rdi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i64 %x to float |
| ret float %conv |
| } |
| |
| define float @test_ui32_to_float(i32 %x) { |
| ; X64-LABEL: test_ui32_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: movl %edi, %eax |
| ; X64-NEXT: cvtsi2ss %rax, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_ui32_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtusi2ss %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i32 %x to float |
| ret float %conv |
| } |
| |
| define float @test_ui16_to_float(i16 zeroext %x) { |
| ; X64-LABEL: test_ui16_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2ss %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; SDAG-AVX512-LABEL: test_ui16_to_float: |
| ; SDAG-AVX512: # %bb.0: # %entry |
| ; SDAG-AVX512-NEXT: vcvtsi2ss %edi, %xmm0, %xmm0 |
| ; SDAG-AVX512-NEXT: retq |
| ; |
| ; GISEL-AVX512-LABEL: test_ui16_to_float: |
| ; GISEL-AVX512: # %bb.0: # %entry |
| ; GISEL-AVX512-NEXT: vcvtusi2ss %edi, %xmm0, %xmm0 |
| ; GISEL-AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i16 %x to float |
| ret float %conv |
| } |
| |
| define float @test_ui8_to_float(i8 zeroext %x) { |
| ; X64-LABEL: test_ui8_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2ss %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; SDAG-AVX512-LABEL: test_ui8_to_float: |
| ; SDAG-AVX512: # %bb.0: # %entry |
| ; SDAG-AVX512-NEXT: vcvtsi2ss %edi, %xmm0, %xmm0 |
| ; SDAG-AVX512-NEXT: retq |
| ; |
| ; GISEL-AVX512-LABEL: test_ui8_to_float: |
| ; GISEL-AVX512: # %bb.0: # %entry |
| ; GISEL-AVX512-NEXT: vcvtusi2ss %edi, %xmm0, %xmm0 |
| ; GISEL-AVX512-NEXT: retq |
| entry: |
| %conv = uitofp i8 %x to float |
| ret float %conv |
| } |
| |
| define double @test_si64_to_double(i64 %x) { |
| ; X64-LABEL: test_si64_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2sd %rdi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si64_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2sd %rdi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i64 %x to double |
| ret double %conv |
| } |
| |
| define double @test_si32_to_double(i32 %x) { |
| ; X64-LABEL: test_si32_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2sd %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si32_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2sd %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i32 %x to double |
| ret double %conv |
| } |
| |
| define double @test_si16_to_double(i16 signext %x) { |
| ; X64-LABEL: test_si16_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2sd %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si16_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2sd %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i16 %x to double |
| ret double %conv |
| } |
| |
| define double @test_si8_to_double(i8 signext %x) { |
| ; X64-LABEL: test_si8_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2sd %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si8_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2sd %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i8 %x to double |
| ret double %conv |
| } |
| |
| define double @test_si31_to_double(i31 %x) { |
| ; X64-LABEL: test_si31_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: addl %edi, %edi |
| ; X64-NEXT: sarl %edi |
| ; X64-NEXT: cvtsi2sd %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si31_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: addl %edi, %edi |
| ; AVX512-NEXT: sarl %edi |
| ; AVX512-NEXT: vcvtsi2sd %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i31 %x to double |
| ret double %conv |
| } |
| |
| define double @test_si33_to_double(i33 %x) { |
| ; X64-LABEL: test_si33_to_double: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: shlq $31, %rdi |
| ; X64-NEXT: sarq $31, %rdi |
| ; X64-NEXT: cvtsi2sd %rdi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si33_to_double: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: shlq $31, %rdi |
| ; AVX512-NEXT: sarq $31, %rdi |
| ; AVX512-NEXT: vcvtsi2sd %rdi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i33 %x to double |
| ret double %conv |
| } |
| |
| define float @test_si64_to_float(i64 %x) { |
| ; X64-LABEL: test_si64_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2ss %rdi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si64_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2ss %rdi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i64 %x to float |
| ret float %conv |
| } |
| |
| define float @test_si32_to_float(i32 %x) { |
| ; X64-LABEL: test_si32_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2ss %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si32_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2ss %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i32 %x to float |
| ret float %conv |
| } |
| |
| define float @test_si16_to_float(i16 signext %x) { |
| ; X64-LABEL: test_si16_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2ss %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si16_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2ss %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i16 %x to float |
| ret float %conv |
| } |
| |
| define float @test_si8_to_float(i8 signext %x) { |
| ; X64-LABEL: test_si8_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: cvtsi2ss %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si8_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: vcvtsi2ss %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i8 %x to float |
| ret float %conv |
| } |
| |
| define float @test_si31_to_float(i31 %x) { |
| ; X64-LABEL: test_si31_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: addl %edi, %edi |
| ; X64-NEXT: sarl %edi |
| ; X64-NEXT: cvtsi2ss %edi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si31_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: addl %edi, %edi |
| ; AVX512-NEXT: sarl %edi |
| ; AVX512-NEXT: vcvtsi2ss %edi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i31 %x to float |
| ret float %conv |
| } |
| |
| define float @test_si33_to_float(i33 %x) { |
| ; X64-LABEL: test_si33_to_float: |
| ; X64: # %bb.0: # %entry |
| ; X64-NEXT: shlq $31, %rdi |
| ; X64-NEXT: sarq $31, %rdi |
| ; X64-NEXT: cvtsi2ss %rdi, %xmm0 |
| ; X64-NEXT: retq |
| ; |
| ; AVX512-LABEL: test_si33_to_float: |
| ; AVX512: # %bb.0: # %entry |
| ; AVX512-NEXT: shlq $31, %rdi |
| ; AVX512-NEXT: sarq $31, %rdi |
| ; AVX512-NEXT: vcvtsi2ss %rdi, %xmm0, %xmm0 |
| ; AVX512-NEXT: retq |
| entry: |
| %conv = sitofp i33 %x to float |
| ret float %conv |
| } |