Files
clang-p2996/llvm/test/CodeGen/AArch64/arm64-fast-isel-conversion-fallback.ll
David Green 1729e6e742 [AArch64] Improve bf16 fp_extend lowering. (#118966)
A bf16 fp_extend is just a shift into the higher bits. This changes the
lowering from using a relatively ugly tablegen pattern, to ISel
generating the shift using an extended vector. This is cleaner and
should optimize better. StrictFP goes through the same route as it
cannot round or set flags.
2025-01-07 11:43:14 +00:00

415 lines
11 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc -O0 -fast-isel -verify-machineinstrs -mtriple=arm64-eabi < %s | FileCheck --enable-var-scope %s
; Test fptosi
define i32 @fptosi_wh(half %a) nounwind ssp {
; CHECK-LABEL: fptosi_wh:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvt s0, h0
; CHECK-NEXT: fcvtzs w0, s0
; CHECK-NEXT: ret
entry:
%conv = fptosi half %a to i32
ret i32 %conv
}
; Test fptoui
define i32 @fptoui_swh(half %a) nounwind ssp {
; CHECK-LABEL: fptoui_swh:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fcvt s0, h0
; CHECK-NEXT: fcvtzu w0, s0
; CHECK-NEXT: ret
entry:
%conv = fptoui half %a to i32
ret i32 %conv
}
; Test sitofp
define half @sitofp_hw_i1(i1 %a) nounwind ssp {
; CHECK-LABEL: sitofp_hw_i1:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sbfx w8, w0, #0, #1
; CHECK-NEXT: scvtf s0, w8
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i1 %a to half
ret half %conv
}
; Test sitofp
define half @sitofp_hw_i8(i8 %a) nounwind ssp {
; CHECK-LABEL: sitofp_hw_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxtb w8, w0
; CHECK-NEXT: scvtf s0, w8
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i8 %a to half
ret half %conv
}
; Test sitofp
define half @sitofp_hw_i16(i16 %a) nounwind ssp {
; CHECK-LABEL: sitofp_hw_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxth w8, w0
; CHECK-NEXT: scvtf s0, w8
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i16 %a to half
ret half %conv
}
; Test sitofp
define half @sitofp_hw_i32(i32 %a) nounwind ssp {
; CHECK-LABEL: sitofp_hw_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: scvtf s0, w0
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i32 %a to half
ret half %conv
}
; Test sitofp
define half @sitofp_hx(i64 %a) nounwind ssp {
; CHECK-LABEL: sitofp_hx:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: scvtf s0, x0
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i64 %a to half
ret half %conv
}
; Test uitofp
define half @uitofp_hw_i1(i1 %a) nounwind ssp {
; CHECK-LABEL: uitofp_hw_i1:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: and w8, w0, #0x1
; CHECK-NEXT: ucvtf s0, w8
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i1 %a to half
ret half %conv
}
; Test uitofp
define half @uitofp_hw_i8(i8 %a) nounwind ssp {
; CHECK-LABEL: uitofp_hw_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: and w8, w0, #0xff
; CHECK-NEXT: ucvtf s0, w8
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i8 %a to half
ret half %conv
}
; Test uitofp
define half @uitofp_hw_i16(i16 %a) nounwind ssp {
; CHECK-LABEL: uitofp_hw_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: and w8, w0, #0xffff
; CHECK-NEXT: ucvtf s0, w8
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i16 %a to half
ret half %conv
}
; Test uitofp
define half @uitofp_hw_i32(i32 %a) nounwind ssp {
; CHECK-LABEL: uitofp_hw_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ucvtf s0, w0
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i32 %a to half
ret half %conv
}
; Test uitofp
define half @uitofp_hx(i64 %a) nounwind ssp {
; CHECK-LABEL: uitofp_hx:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ucvtf s0, x0
; CHECK-NEXT: fcvt h0, s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i64 %a to half
ret half %conv
}
; Test fptosi
define i32 @fptosi_bf(bfloat %a) nounwind ssp {
; CHECK-LABEL: fptosi_bf:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fmov s1, s0
; CHECK-NEXT: // implicit-def: $d0
; CHECK-NEXT: fmov s0, s1
; CHECK-NEXT: shll v0.4s, v0.4h, #16
; CHECK-NEXT: // kill: def $s0 killed $s0 killed $q0
; CHECK-NEXT: fcvtzs w0, s0
; CHECK-NEXT: ret
entry:
%conv = fptosi bfloat %a to i32
ret i32 %conv
}
; Test fptoui
define i32 @fptoui_sbf(bfloat %a) nounwind ssp {
; CHECK-LABEL: fptoui_sbf:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: fmov s1, s0
; CHECK-NEXT: // implicit-def: $d0
; CHECK-NEXT: fmov s0, s1
; CHECK-NEXT: shll v0.4s, v0.4h, #16
; CHECK-NEXT: // kill: def $s0 killed $s0 killed $q0
; CHECK-NEXT: fcvtzu w0, s0
; CHECK-NEXT: ret
entry:
%conv = fptoui bfloat %a to i32
ret i32 %conv
}
; Test sitofp
define bfloat @sitofp_bf_i1(i1 %a) nounwind ssp {
; CHECK-LABEL: sitofp_bf_i1:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sbfx w8, w0, #0, #1
; CHECK-NEXT: scvtf s0, w8
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i1 %a to bfloat
ret bfloat %conv
}
; Test sitofp
define bfloat @sitofp_bf_i8(i8 %a) nounwind ssp {
; CHECK-LABEL: sitofp_bf_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxtb w8, w0
; CHECK-NEXT: scvtf s0, w8
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i8 %a to bfloat
ret bfloat %conv
}
; Test sitofp
define bfloat @sitofp_bf_i16(i16 %a) nounwind ssp {
; CHECK-LABEL: sitofp_bf_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: sxth w8, w0
; CHECK-NEXT: scvtf s0, w8
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i16 %a to bfloat
ret bfloat %conv
}
; Test sitofp
define bfloat @sitofp_bf_i32(i32 %a) nounwind ssp {
; CHECK-LABEL: sitofp_bf_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: scvtf d0, w0
; CHECK-NEXT: fcvtxn s0, d0
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i32 %a to bfloat
ret bfloat %conv
}
; Test sitofp
define bfloat @sitofp_bf_i164(i64 %a) nounwind ssp {
; CHECK-LABEL: sitofp_bf_i164:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: subs x8, x0, #0
; CHECK-NEXT: cneg x10, x0, mi
; CHECK-NEXT: and x8, x10, #0xfffffffffffff000
; CHECK-NEXT: lsr x9, x10, #53
; CHECK-NEXT: subs x9, x9, #0
; CHECK-NEXT: csel x8, x8, x10, ne
; CHECK-NEXT: scvtf d0, x8
; CHECK-NEXT: fmov x8, d0
; CHECK-NEXT: and x9, x0, #0x8000000000000000
; CHECK-NEXT: orr x8, x8, x9
; CHECK-NEXT: cset w9, ne
; CHECK-NEXT: ands x10, x10, #0xfff
; CHECK-NEXT: csel w9, wzr, w9, eq
; CHECK-NEXT: mov w9, w9
; CHECK-NEXT: // kill: def $x9 killed $w9
; CHECK-NEXT: orr x8, x8, x9
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: fcvtxn s0, d0
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = sitofp i64 %a to bfloat
ret bfloat %conv
}
; Test uitofp
define bfloat @uitofp_bf_i1(i1 %a) nounwind ssp {
; CHECK-LABEL: uitofp_bf_i1:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: and w8, w0, #0x1
; CHECK-NEXT: ucvtf s0, w8
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i1 %a to bfloat
ret bfloat %conv
}
; Test uitofp
define bfloat @uitofp_bf_i8(i8 %a) nounwind ssp {
; CHECK-LABEL: uitofp_bf_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: and w8, w0, #0xff
; CHECK-NEXT: ucvtf s0, w8
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i8 %a to bfloat
ret bfloat %conv
}
; Test uitofp
define bfloat @uitofp_bf_i16(i16 %a) nounwind ssp {
; CHECK-LABEL: uitofp_bf_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: and w8, w0, #0xffff
; CHECK-NEXT: ucvtf s0, w8
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i16 %a to bfloat
ret bfloat %conv
}
; Test uitofp
define bfloat @uitofp_bf_i32(i32 %a) nounwind ssp {
; CHECK-LABEL: uitofp_bf_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ucvtf d0, w0
; CHECK-NEXT: fcvtxn s0, d0
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i32 %a to bfloat
ret bfloat %conv
}
; Test uitofp
define bfloat @uitofp_bf_i64(i64 %a) nounwind ssp {
; CHECK-LABEL: uitofp_bf_i64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: and x8, x0, #0xfffffffffffff000
; CHECK-NEXT: lsr x9, x0, #53
; CHECK-NEXT: subs x9, x9, #0
; CHECK-NEXT: csel x8, x8, x0, ne
; CHECK-NEXT: ucvtf d0, x8
; CHECK-NEXT: fmov x8, d0
; CHECK-NEXT: cset w9, ne
; CHECK-NEXT: ands x10, x0, #0xfff
; CHECK-NEXT: csel w9, wzr, w9, eq
; CHECK-NEXT: mov w9, w9
; CHECK-NEXT: // kill: def $x9 killed $w9
; CHECK-NEXT: orr x8, x8, x9
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: fcvtxn s0, d0
; CHECK-NEXT: fmov w9, s0
; CHECK-NEXT: ubfx w8, w9, #16, #1
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: mov w9, #32767 // =0x7fff
; CHECK-NEXT: add w8, w8, w9
; CHECK-NEXT: lsr w8, w8, #16
; CHECK-NEXT: fmov s0, w8
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
; CHECK-NEXT: ret
entry:
%conv = uitofp i64 %a to bfloat
ret bfloat %conv
}