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