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