1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \ 3; RUN: -target-abi lp64f -disable-strictnode-mutation < %s | \ 4; RUN: FileCheck %s -check-prefix=RV64IZFH 5; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \ 6; RUN: -target-abi lp64 -disable-strictnode-mutation < %s | \ 7; RUN: FileCheck %s -check-prefix=RV64IZHINX 8 9; This file exhaustively checks half<->i32 conversions. In general, 10; fcvt.l[u].h can be selected instead of fcvt.w[u].h because poison is 11; generated for an fpto[s|u]i conversion if the result doesn't fit in the 12; target type. 13 14define i32 @aext_fptosi(half %a) nounwind strictfp { 15; RV64IZFH-LABEL: aext_fptosi: 16; RV64IZFH: # %bb.0: 17; RV64IZFH-NEXT: fcvt.w.h a0, fa0, rtz 18; RV64IZFH-NEXT: ret 19; 20; RV64IZHINX-LABEL: aext_fptosi: 21; RV64IZHINX: # %bb.0: 22; RV64IZHINX-NEXT: fcvt.w.h a0, a0, rtz 23; RV64IZHINX-NEXT: ret 24 %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict") 25 ret i32 %1 26} 27declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata) 28 29define signext i32 @sext_fptosi(half %a) nounwind strictfp { 30; RV64IZFH-LABEL: sext_fptosi: 31; RV64IZFH: # %bb.0: 32; RV64IZFH-NEXT: fcvt.w.h a0, fa0, rtz 33; RV64IZFH-NEXT: ret 34; 35; RV64IZHINX-LABEL: sext_fptosi: 36; RV64IZHINX: # %bb.0: 37; RV64IZHINX-NEXT: fcvt.w.h a0, a0, rtz 38; RV64IZHINX-NEXT: ret 39 %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict") 40 ret i32 %1 41} 42 43define zeroext i32 @zext_fptosi(half %a) nounwind strictfp { 44; RV64IZFH-LABEL: zext_fptosi: 45; RV64IZFH: # %bb.0: 46; RV64IZFH-NEXT: fcvt.w.h a0, fa0, rtz 47; RV64IZFH-NEXT: slli a0, a0, 32 48; RV64IZFH-NEXT: srli a0, a0, 32 49; RV64IZFH-NEXT: ret 50; 51; RV64IZHINX-LABEL: zext_fptosi: 52; RV64IZHINX: # %bb.0: 53; RV64IZHINX-NEXT: fcvt.w.h a0, a0, rtz 54; RV64IZHINX-NEXT: slli a0, a0, 32 55; RV64IZHINX-NEXT: srli a0, a0, 32 56; RV64IZHINX-NEXT: ret 57 %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %a, metadata !"fpexcept.strict") 58 ret i32 %1 59} 60 61define i32 @aext_fptoui(half %a) nounwind strictfp { 62; RV64IZFH-LABEL: aext_fptoui: 63; RV64IZFH: # %bb.0: 64; RV64IZFH-NEXT: fcvt.wu.h a0, fa0, rtz 65; RV64IZFH-NEXT: ret 66; 67; RV64IZHINX-LABEL: aext_fptoui: 68; RV64IZHINX: # %bb.0: 69; RV64IZHINX-NEXT: fcvt.wu.h a0, a0, rtz 70; RV64IZHINX-NEXT: ret 71 %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict") 72 ret i32 %1 73} 74declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata) 75 76define signext i32 @sext_fptoui(half %a) nounwind strictfp { 77; RV64IZFH-LABEL: sext_fptoui: 78; RV64IZFH: # %bb.0: 79; RV64IZFH-NEXT: fcvt.wu.h a0, fa0, rtz 80; RV64IZFH-NEXT: ret 81; 82; RV64IZHINX-LABEL: sext_fptoui: 83; RV64IZHINX: # %bb.0: 84; RV64IZHINX-NEXT: fcvt.wu.h a0, a0, rtz 85; RV64IZHINX-NEXT: ret 86 %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict") 87 ret i32 %1 88} 89 90define zeroext i32 @zext_fptoui(half %a) nounwind strictfp { 91; RV64IZFH-LABEL: zext_fptoui: 92; RV64IZFH: # %bb.0: 93; RV64IZFH-NEXT: fcvt.lu.h a0, fa0, rtz 94; RV64IZFH-NEXT: ret 95; 96; RV64IZHINX-LABEL: zext_fptoui: 97; RV64IZHINX: # %bb.0: 98; RV64IZHINX-NEXT: fcvt.lu.h a0, a0, rtz 99; RV64IZHINX-NEXT: ret 100 %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %a, metadata !"fpexcept.strict") 101 ret i32 %1 102} 103 104define half @uitofp_aext_i32_to_f16(i32 %a) nounwind strictfp { 105; RV64IZFH-LABEL: uitofp_aext_i32_to_f16: 106; RV64IZFH: # %bb.0: 107; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 108; RV64IZFH-NEXT: ret 109; 110; RV64IZHINX-LABEL: uitofp_aext_i32_to_f16: 111; RV64IZHINX: # %bb.0: 112; RV64IZHINX-NEXT: fcvt.h.wu a0, a0 113; RV64IZHINX-NEXT: ret 114 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 115 ret half %1 116} 117declare half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata, metadata) 118 119define half @uitofp_sext_i32_to_f16(i32 signext %a) nounwind strictfp { 120; RV64IZFH-LABEL: uitofp_sext_i32_to_f16: 121; RV64IZFH: # %bb.0: 122; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 123; RV64IZFH-NEXT: ret 124; 125; RV64IZHINX-LABEL: uitofp_sext_i32_to_f16: 126; RV64IZHINX: # %bb.0: 127; RV64IZHINX-NEXT: fcvt.h.wu a0, a0 128; RV64IZHINX-NEXT: ret 129 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 130 ret half %1 131} 132 133define half @uitofp_zext_i32_to_f16(i32 zeroext %a) nounwind strictfp { 134; RV64IZFH-LABEL: uitofp_zext_i32_to_f16: 135; RV64IZFH: # %bb.0: 136; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 137; RV64IZFH-NEXT: ret 138; 139; RV64IZHINX-LABEL: uitofp_zext_i32_to_f16: 140; RV64IZHINX: # %bb.0: 141; RV64IZHINX-NEXT: fcvt.h.wu a0, a0 142; RV64IZHINX-NEXT: ret 143 %1 = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 144 ret half %1 145} 146 147define half @sitofp_aext_i32_to_f16(i32 %a) nounwind strictfp { 148; RV64IZFH-LABEL: sitofp_aext_i32_to_f16: 149; RV64IZFH: # %bb.0: 150; RV64IZFH-NEXT: fcvt.h.w fa0, a0 151; RV64IZFH-NEXT: ret 152; 153; RV64IZHINX-LABEL: sitofp_aext_i32_to_f16: 154; RV64IZHINX: # %bb.0: 155; RV64IZHINX-NEXT: fcvt.h.w a0, a0 156; RV64IZHINX-NEXT: ret 157 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 158 ret half %1 159} 160declare half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata, metadata) 161 162define half @sitofp_sext_i32_to_f16(i32 signext %a) nounwind strictfp { 163; RV64IZFH-LABEL: sitofp_sext_i32_to_f16: 164; RV64IZFH: # %bb.0: 165; RV64IZFH-NEXT: fcvt.h.w fa0, a0 166; RV64IZFH-NEXT: ret 167; 168; RV64IZHINX-LABEL: sitofp_sext_i32_to_f16: 169; RV64IZHINX: # %bb.0: 170; RV64IZHINX-NEXT: fcvt.h.w a0, a0 171; RV64IZHINX-NEXT: ret 172 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 173 ret half %1 174} 175 176define half @sitofp_zext_i32_to_f16(i32 zeroext %a) nounwind strictfp { 177; RV64IZFH-LABEL: sitofp_zext_i32_to_f16: 178; RV64IZFH: # %bb.0: 179; RV64IZFH-NEXT: fcvt.h.w fa0, a0 180; RV64IZFH-NEXT: ret 181; 182; RV64IZHINX-LABEL: sitofp_zext_i32_to_f16: 183; RV64IZHINX: # %bb.0: 184; RV64IZHINX-NEXT: fcvt.h.w a0, a0 185; RV64IZHINX-NEXT: ret 186 %1 = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.strict") 187 ret half %1 188} 189