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 < %s | FileCheck %s -check-prefix=RV64IZFH 4; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \ 5; RUN: -target-abi lp64 < %s | FileCheck %s -check-prefix=RV64IZHINX 6 7; This file exhaustively checks half<->i32 conversions. In general, 8; fcvt.l[u].h can be selected instead of fcvt.w[u].h 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(half %a) nounwind { 13; RV64IZFH-LABEL: aext_fptosi: 14; RV64IZFH: # %bb.0: 15; RV64IZFH-NEXT: fcvt.w.h a0, fa0, rtz 16; RV64IZFH-NEXT: ret 17; 18; RV64IZHINX-LABEL: aext_fptosi: 19; RV64IZHINX: # %bb.0: 20; RV64IZHINX-NEXT: fcvt.w.h a0, a0, rtz 21; RV64IZHINX-NEXT: ret 22 %1 = fptosi half %a to i32 23 ret i32 %1 24} 25 26define signext i32 @sext_fptosi(half %a) nounwind { 27; RV64IZFH-LABEL: sext_fptosi: 28; RV64IZFH: # %bb.0: 29; RV64IZFH-NEXT: fcvt.w.h a0, fa0, rtz 30; RV64IZFH-NEXT: ret 31; 32; RV64IZHINX-LABEL: sext_fptosi: 33; RV64IZHINX: # %bb.0: 34; RV64IZHINX-NEXT: fcvt.w.h a0, a0, rtz 35; RV64IZHINX-NEXT: ret 36 %1 = fptosi half %a to i32 37 ret i32 %1 38} 39 40define zeroext i32 @zext_fptosi(half %a) nounwind { 41; RV64IZFH-LABEL: zext_fptosi: 42; RV64IZFH: # %bb.0: 43; RV64IZFH-NEXT: fcvt.w.h a0, fa0, rtz 44; RV64IZFH-NEXT: slli a0, a0, 32 45; RV64IZFH-NEXT: srli a0, a0, 32 46; RV64IZFH-NEXT: ret 47; 48; RV64IZHINX-LABEL: zext_fptosi: 49; RV64IZHINX: # %bb.0: 50; RV64IZHINX-NEXT: fcvt.w.h a0, a0, rtz 51; RV64IZHINX-NEXT: slli a0, a0, 32 52; RV64IZHINX-NEXT: srli a0, a0, 32 53; RV64IZHINX-NEXT: ret 54 %1 = fptosi half %a to i32 55 ret i32 %1 56} 57 58define i32 @aext_fptoui(half %a) nounwind { 59; RV64IZFH-LABEL: aext_fptoui: 60; RV64IZFH: # %bb.0: 61; RV64IZFH-NEXT: fcvt.wu.h a0, fa0, rtz 62; RV64IZFH-NEXT: ret 63; 64; RV64IZHINX-LABEL: aext_fptoui: 65; RV64IZHINX: # %bb.0: 66; RV64IZHINX-NEXT: fcvt.wu.h a0, a0, rtz 67; RV64IZHINX-NEXT: ret 68 %1 = fptoui half %a to i32 69 ret i32 %1 70} 71 72define signext i32 @sext_fptoui(half %a) nounwind { 73; RV64IZFH-LABEL: sext_fptoui: 74; RV64IZFH: # %bb.0: 75; RV64IZFH-NEXT: fcvt.wu.h a0, fa0, rtz 76; RV64IZFH-NEXT: ret 77; 78; RV64IZHINX-LABEL: sext_fptoui: 79; RV64IZHINX: # %bb.0: 80; RV64IZHINX-NEXT: fcvt.wu.h a0, a0, rtz 81; RV64IZHINX-NEXT: ret 82 %1 = fptoui half %a to i32 83 ret i32 %1 84} 85 86define zeroext i32 @zext_fptoui(half %a) nounwind { 87; RV64IZFH-LABEL: zext_fptoui: 88; RV64IZFH: # %bb.0: 89; RV64IZFH-NEXT: fcvt.lu.h a0, fa0, rtz 90; RV64IZFH-NEXT: ret 91; 92; RV64IZHINX-LABEL: zext_fptoui: 93; RV64IZHINX: # %bb.0: 94; RV64IZHINX-NEXT: fcvt.lu.h a0, a0, rtz 95; RV64IZHINX-NEXT: ret 96 %1 = fptoui half %a to i32 97 ret i32 %1 98} 99 100define i16 @bcvt_f16_to_aext_i16(half %a, half %b) nounwind { 101; RV64IZFH-LABEL: bcvt_f16_to_aext_i16: 102; RV64IZFH: # %bb.0: 103; RV64IZFH-NEXT: fadd.h fa5, fa0, fa1 104; RV64IZFH-NEXT: fmv.x.h a0, fa5 105; RV64IZFH-NEXT: ret 106; 107; RV64IZHINX-LABEL: bcvt_f16_to_aext_i16: 108; RV64IZHINX: # %bb.0: 109; RV64IZHINX-NEXT: fadd.h a0, a0, a1 110; RV64IZHINX-NEXT: ret 111 %1 = fadd half %a, %b 112 %2 = bitcast half %1 to i16 113 ret i16 %2 114} 115 116define signext i16 @bcvt_f16_to_sext_i16(half %a, half %b) nounwind { 117; RV64IZFH-LABEL: bcvt_f16_to_sext_i16: 118; RV64IZFH: # %bb.0: 119; RV64IZFH-NEXT: fadd.h fa5, fa0, fa1 120; RV64IZFH-NEXT: fmv.x.h a0, fa5 121; RV64IZFH-NEXT: ret 122; 123; RV64IZHINX-LABEL: bcvt_f16_to_sext_i16: 124; RV64IZHINX: # %bb.0: 125; RV64IZHINX-NEXT: fadd.h a0, a0, a1 126; RV64IZHINX-NEXT: slli a0, a0, 48 127; RV64IZHINX-NEXT: srai a0, a0, 48 128; RV64IZHINX-NEXT: ret 129 %1 = fadd half %a, %b 130 %2 = bitcast half %1 to i16 131 ret i16 %2 132} 133 134define zeroext i16 @bcvt_f16_to_zext_i16(half %a, half %b) nounwind { 135; RV64IZFH-LABEL: bcvt_f16_to_zext_i16: 136; RV64IZFH: # %bb.0: 137; RV64IZFH-NEXT: fadd.h fa5, fa0, fa1 138; RV64IZFH-NEXT: fmv.x.h a0, fa5 139; RV64IZFH-NEXT: slli a0, a0, 48 140; RV64IZFH-NEXT: srli a0, a0, 48 141; RV64IZFH-NEXT: ret 142; 143; RV64IZHINX-LABEL: bcvt_f16_to_zext_i16: 144; RV64IZHINX: # %bb.0: 145; RV64IZHINX-NEXT: fadd.h a0, a0, a1 146; RV64IZHINX-NEXT: slli a0, a0, 48 147; RV64IZHINX-NEXT: srli a0, a0, 48 148; RV64IZHINX-NEXT: ret 149 %1 = fadd half %a, %b 150 %2 = bitcast half %1 to i16 151 ret i16 %2 152} 153 154define half @bcvt_i64_to_f16_via_i16(i64 %a, i64 %b) nounwind { 155; RV64IZFH-LABEL: bcvt_i64_to_f16_via_i16: 156; RV64IZFH: # %bb.0: 157; RV64IZFH-NEXT: fmv.h.x fa5, a0 158; RV64IZFH-NEXT: fmv.h.x fa4, a1 159; RV64IZFH-NEXT: fadd.h fa0, fa5, fa4 160; RV64IZFH-NEXT: ret 161; 162; RV64IZHINX-LABEL: bcvt_i64_to_f16_via_i16: 163; RV64IZHINX: # %bb.0: 164; RV64IZHINX-NEXT: fadd.h a0, a0, a1 165; RV64IZHINX-NEXT: ret 166 %1 = trunc i64 %a to i16 167 %2 = trunc i64 %b to i16 168 %3 = bitcast i16 %1 to half 169 %4 = bitcast i16 %2 to half 170 %5 = fadd half %3, %4 171 ret half %5 172} 173 174define half @uitofp_aext_i32_to_f16(i32 %a) nounwind { 175; RV64IZFH-LABEL: uitofp_aext_i32_to_f16: 176; RV64IZFH: # %bb.0: 177; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 178; RV64IZFH-NEXT: ret 179; 180; RV64IZHINX-LABEL: uitofp_aext_i32_to_f16: 181; RV64IZHINX: # %bb.0: 182; RV64IZHINX-NEXT: fcvt.h.wu a0, a0 183; RV64IZHINX-NEXT: ret 184 %1 = uitofp i32 %a to half 185 ret half %1 186} 187 188define half @uitofp_sext_i32_to_f16(i32 signext %a) nounwind { 189; RV64IZFH-LABEL: uitofp_sext_i32_to_f16: 190; RV64IZFH: # %bb.0: 191; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 192; RV64IZFH-NEXT: ret 193; 194; RV64IZHINX-LABEL: uitofp_sext_i32_to_f16: 195; RV64IZHINX: # %bb.0: 196; RV64IZHINX-NEXT: fcvt.h.wu a0, a0 197; RV64IZHINX-NEXT: ret 198 %1 = uitofp i32 %a to half 199 ret half %1 200} 201 202define half @uitofp_zext_i32_to_f16(i32 zeroext %a) nounwind { 203; RV64IZFH-LABEL: uitofp_zext_i32_to_f16: 204; RV64IZFH: # %bb.0: 205; RV64IZFH-NEXT: fcvt.h.wu fa0, a0 206; RV64IZFH-NEXT: ret 207; 208; RV64IZHINX-LABEL: uitofp_zext_i32_to_f16: 209; RV64IZHINX: # %bb.0: 210; RV64IZHINX-NEXT: fcvt.h.wu a0, a0 211; RV64IZHINX-NEXT: ret 212 %1 = uitofp i32 %a to half 213 ret half %1 214} 215 216define half @sitofp_aext_i32_to_f16(i32 %a) nounwind { 217; RV64IZFH-LABEL: sitofp_aext_i32_to_f16: 218; RV64IZFH: # %bb.0: 219; RV64IZFH-NEXT: fcvt.h.w fa0, a0 220; RV64IZFH-NEXT: ret 221; 222; RV64IZHINX-LABEL: sitofp_aext_i32_to_f16: 223; RV64IZHINX: # %bb.0: 224; RV64IZHINX-NEXT: fcvt.h.w a0, a0 225; RV64IZHINX-NEXT: ret 226 %1 = sitofp i32 %a to half 227 ret half %1 228} 229 230define half @sitofp_sext_i32_to_f16(i32 signext %a) nounwind { 231; RV64IZFH-LABEL: sitofp_sext_i32_to_f16: 232; RV64IZFH: # %bb.0: 233; RV64IZFH-NEXT: fcvt.h.w fa0, a0 234; RV64IZFH-NEXT: ret 235; 236; RV64IZHINX-LABEL: sitofp_sext_i32_to_f16: 237; RV64IZHINX: # %bb.0: 238; RV64IZHINX-NEXT: fcvt.h.w a0, a0 239; RV64IZHINX-NEXT: ret 240 %1 = sitofp i32 %a to half 241 ret half %1 242} 243 244define half @sitofp_zext_i32_to_f16(i32 zeroext %a) nounwind { 245; RV64IZFH-LABEL: sitofp_zext_i32_to_f16: 246; RV64IZFH: # %bb.0: 247; RV64IZFH-NEXT: fcvt.h.w fa0, a0 248; RV64IZFH-NEXT: ret 249; 250; RV64IZHINX-LABEL: sitofp_zext_i32_to_f16: 251; RV64IZHINX: # %bb.0: 252; RV64IZHINX-NEXT: fcvt.h.w a0, a0 253; RV64IZHINX-NEXT: ret 254 %1 = sitofp i32 %a to half 255 ret half %1 256} 257