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