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