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