Opc, DL, DstVT, Src,
DAG.getTargetConstant(RISCVFPRndMode::RTZ, DL, Subtarget.getXLenVT()));
+ // fcvt.wu.* sign extends bit 31 on RV64. FP_TO_UINT_SAT expects to zero
+ // extend.
+ if (Opc == RISCVISD::FCVT_WU_RV64)
+ FpToInt = DAG.getZeroExtendInReg(FpToInt, DL, MVT::i32);
+
SDValue ZeroInt = DAG.getConstant(0, DL, DstVT);
return DAG.getSelectCC(DL, Src, Src, ZeroInt, FpToInt, ISD::CondCode::SETUO);
}
SDValue FpToInt = DAG.getNode(Opc, DL, XLenVT, Src,
DAG.getTargetConstant(FRM, DL, XLenVT));
+ // fcvt.wu.* sign extends bit 31 on RV64. FP_TO_UINT_SAT expects to zero
+ // extend.
+ if (Opc == RISCVISD::FCVT_WU_RV64)
+ FpToInt = DAG.getZeroExtendInReg(FpToInt, DL, MVT::i32);
+
// RISCV FP-to-int conversions saturate to the destination register size, but
// don't produce 0 for nan.
SDValue ZeroInt = DAG.getConstant(0, DL, DstVT);
}
define i32 @fcvt_wu_d_sat(double %a) nounwind {
-; CHECKIFD-LABEL: fcvt_wu_d_sat:
-; CHECKIFD: # %bb.0: # %start
-; CHECKIFD-NEXT: feq.d a0, fa0, fa0
-; CHECKIFD-NEXT: beqz a0, .LBB6_2
-; CHECKIFD-NEXT: # %bb.1:
-; CHECKIFD-NEXT: fcvt.wu.d a0, fa0, rtz
-; CHECKIFD-NEXT: .LBB6_2: # %start
-; CHECKIFD-NEXT: ret
+; RV32IFD-LABEL: fcvt_wu_d_sat:
+; RV32IFD: # %bb.0: # %start
+; RV32IFD-NEXT: feq.d a0, fa0, fa0
+; RV32IFD-NEXT: beqz a0, .LBB6_2
+; RV32IFD-NEXT: # %bb.1:
+; RV32IFD-NEXT: fcvt.wu.d a0, fa0, rtz
+; RV32IFD-NEXT: .LBB6_2: # %start
+; RV32IFD-NEXT: ret
+;
+; RV64IFD-LABEL: fcvt_wu_d_sat:
+; RV64IFD: # %bb.0: # %start
+; RV64IFD-NEXT: feq.d a0, fa0, fa0
+; RV64IFD-NEXT: beqz a0, .LBB6_2
+; RV64IFD-NEXT: # %bb.1:
+; RV64IFD-NEXT: fcvt.wu.d a0, fa0, rtz
+; RV64IFD-NEXT: slli a0, a0, 32
+; RV64IFD-NEXT: srli a0, a0, 32
+; RV64IFD-NEXT: .LBB6_2: # %start
+; RV64IFD-NEXT: ret
;
; RV32I-LABEL: fcvt_wu_d_sat:
; RV32I: # %bb.0: # %start
declare i8 @llvm.fptoui.sat.i8.f64(double)
define zeroext i32 @fcvt_wu_d_sat_zext(double %a) nounwind {
-; CHECKIFD-LABEL: fcvt_wu_d_sat_zext:
-; CHECKIFD: # %bb.0: # %start
-; CHECKIFD-NEXT: feq.d a0, fa0, fa0
-; CHECKIFD-NEXT: beqz a0, .LBB33_2
-; CHECKIFD-NEXT: # %bb.1:
-; CHECKIFD-NEXT: fcvt.wu.d a0, fa0, rtz
-; CHECKIFD-NEXT: .LBB33_2: # %start
-; CHECKIFD-NEXT: ret
+; RV32IFD-LABEL: fcvt_wu_d_sat_zext:
+; RV32IFD: # %bb.0: # %start
+; RV32IFD-NEXT: feq.d a0, fa0, fa0
+; RV32IFD-NEXT: beqz a0, .LBB33_2
+; RV32IFD-NEXT: # %bb.1:
+; RV32IFD-NEXT: fcvt.wu.d a0, fa0, rtz
+; RV32IFD-NEXT: .LBB33_2: # %start
+; RV32IFD-NEXT: ret
+;
+; RV64IFD-LABEL: fcvt_wu_d_sat_zext:
+; RV64IFD: # %bb.0: # %start
+; RV64IFD-NEXT: feq.d a0, fa0, fa0
+; RV64IFD-NEXT: beqz a0, .LBB33_2
+; RV64IFD-NEXT: # %bb.1:
+; RV64IFD-NEXT: fcvt.wu.d a0, fa0, rtz
+; RV64IFD-NEXT: slli a0, a0, 32
+; RV64IFD-NEXT: srli a0, a0, 32
+; RV64IFD-NEXT: .LBB33_2: # %start
+; RV64IFD-NEXT: ret
;
; RV32I-LABEL: fcvt_wu_d_sat_zext:
; RV32I: # %bb.0: # %start
}
define i32 @fcvt_wu_s_sat(float %a) nounwind {
-; CHECKIF-LABEL: fcvt_wu_s_sat:
-; CHECKIF: # %bb.0: # %start
-; CHECKIF-NEXT: feq.s a0, fa0, fa0
-; CHECKIF-NEXT: beqz a0, .LBB4_2
-; CHECKIF-NEXT: # %bb.1:
-; CHECKIF-NEXT: fcvt.wu.s a0, fa0, rtz
-; CHECKIF-NEXT: .LBB4_2: # %start
-; CHECKIF-NEXT: ret
+; RV32IF-LABEL: fcvt_wu_s_sat:
+; RV32IF: # %bb.0: # %start
+; RV32IF-NEXT: feq.s a0, fa0, fa0
+; RV32IF-NEXT: beqz a0, .LBB4_2
+; RV32IF-NEXT: # %bb.1:
+; RV32IF-NEXT: fcvt.wu.s a0, fa0, rtz
+; RV32IF-NEXT: .LBB4_2: # %start
+; RV32IF-NEXT: ret
+;
+; RV64IF-LABEL: fcvt_wu_s_sat:
+; RV64IF: # %bb.0: # %start
+; RV64IF-NEXT: feq.s a0, fa0, fa0
+; RV64IF-NEXT: beqz a0, .LBB4_2
+; RV64IF-NEXT: # %bb.1:
+; RV64IF-NEXT: fcvt.wu.s a0, fa0, rtz
+; RV64IF-NEXT: slli a0, a0, 32
+; RV64IF-NEXT: srli a0, a0, 32
+; RV64IF-NEXT: .LBB4_2: # %start
+; RV64IF-NEXT: ret
;
; RV32I-LABEL: fcvt_wu_s_sat:
; RV32I: # %bb.0: # %start
declare i8 @llvm.fptoui.sat.i8.f32(float)
define zeroext i32 @fcvt_wu_s_sat_zext(float %a) nounwind {
-; CHECKIF-LABEL: fcvt_wu_s_sat_zext:
-; CHECKIF: # %bb.0: # %start
-; CHECKIF-NEXT: feq.s a0, fa0, fa0
-; CHECKIF-NEXT: beqz a0, .LBB31_2
-; CHECKIF-NEXT: # %bb.1:
-; CHECKIF-NEXT: fcvt.wu.s a0, fa0, rtz
-; CHECKIF-NEXT: .LBB31_2: # %start
-; CHECKIF-NEXT: ret
+; RV32IF-LABEL: fcvt_wu_s_sat_zext:
+; RV32IF: # %bb.0: # %start
+; RV32IF-NEXT: feq.s a0, fa0, fa0
+; RV32IF-NEXT: beqz a0, .LBB31_2
+; RV32IF-NEXT: # %bb.1:
+; RV32IF-NEXT: fcvt.wu.s a0, fa0, rtz
+; RV32IF-NEXT: .LBB31_2: # %start
+; RV32IF-NEXT: ret
+;
+; RV64IF-LABEL: fcvt_wu_s_sat_zext:
+; RV64IF: # %bb.0: # %start
+; RV64IF-NEXT: feq.s a0, fa0, fa0
+; RV64IF-NEXT: beqz a0, .LBB31_2
+; RV64IF-NEXT: # %bb.1:
+; RV64IF-NEXT: fcvt.wu.s a0, fa0, rtz
+; RV64IF-NEXT: slli a0, a0, 32
+; RV64IF-NEXT: srli a0, a0, 32
+; RV64IF-NEXT: .LBB31_2: # %start
+; RV64IF-NEXT: ret
;
; RV32I-LABEL: fcvt_wu_s_sat_zext:
; RV32I: # %bb.0: # %start
}
define i32 @fcvt_wu_h_sat(half %a) nounwind {
-; CHECKIZFH-LABEL: fcvt_wu_h_sat:
-; CHECKIZFH: # %bb.0: # %start
-; CHECKIZFH-NEXT: feq.h a0, fa0, fa0
-; CHECKIZFH-NEXT: beqz a0, .LBB8_2
-; CHECKIZFH-NEXT: # %bb.1:
-; CHECKIZFH-NEXT: fcvt.wu.h a0, fa0, rtz
-; CHECKIZFH-NEXT: .LBB8_2: # %start
-; CHECKIZFH-NEXT: ret
+; RV32IZFH-LABEL: fcvt_wu_h_sat:
+; RV32IZFH: # %bb.0: # %start
+; RV32IZFH-NEXT: feq.h a0, fa0, fa0
+; RV32IZFH-NEXT: beqz a0, .LBB8_2
+; RV32IZFH-NEXT: # %bb.1:
+; RV32IZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV32IZFH-NEXT: .LBB8_2: # %start
+; RV32IZFH-NEXT: ret
+;
+; RV64IZFH-LABEL: fcvt_wu_h_sat:
+; RV64IZFH: # %bb.0: # %start
+; RV64IZFH-NEXT: feq.h a0, fa0, fa0
+; RV64IZFH-NEXT: beqz a0, .LBB8_2
+; RV64IZFH-NEXT: # %bb.1:
+; RV64IZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV64IZFH-NEXT: slli a0, a0, 32
+; RV64IZFH-NEXT: srli a0, a0, 32
+; RV64IZFH-NEXT: .LBB8_2: # %start
+; RV64IZFH-NEXT: ret
;
; RV32IDZFH-LABEL: fcvt_wu_h_sat:
; RV32IDZFH: # %bb.0: # %start
; RV64IDZFH-NEXT: beqz a0, .LBB8_2
; RV64IDZFH-NEXT: # %bb.1:
; RV64IDZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV64IDZFH-NEXT: slli a0, a0, 32
+; RV64IDZFH-NEXT: srli a0, a0, 32
; RV64IDZFH-NEXT: .LBB8_2: # %start
; RV64IDZFH-NEXT: ret
;
declare i8 @llvm.fptoui.sat.i8.f16(half)
define zeroext i32 @fcvt_wu_h_sat_zext(half %a) nounwind {
-; CHECKIZFH-LABEL: fcvt_wu_h_sat_zext:
-; CHECKIZFH: # %bb.0: # %start
-; CHECKIZFH-NEXT: feq.h a0, fa0, fa0
-; CHECKIZFH-NEXT: beqz a0, .LBB39_2
-; CHECKIZFH-NEXT: # %bb.1:
-; CHECKIZFH-NEXT: fcvt.wu.h a0, fa0, rtz
-; CHECKIZFH-NEXT: .LBB39_2: # %start
-; CHECKIZFH-NEXT: ret
+; RV32IZFH-LABEL: fcvt_wu_h_sat_zext:
+; RV32IZFH: # %bb.0: # %start
+; RV32IZFH-NEXT: feq.h a0, fa0, fa0
+; RV32IZFH-NEXT: beqz a0, .LBB39_2
+; RV32IZFH-NEXT: # %bb.1:
+; RV32IZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV32IZFH-NEXT: .LBB39_2: # %start
+; RV32IZFH-NEXT: ret
+;
+; RV64IZFH-LABEL: fcvt_wu_h_sat_zext:
+; RV64IZFH: # %bb.0: # %start
+; RV64IZFH-NEXT: feq.h a0, fa0, fa0
+; RV64IZFH-NEXT: beqz a0, .LBB39_2
+; RV64IZFH-NEXT: # %bb.1:
+; RV64IZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV64IZFH-NEXT: slli a0, a0, 32
+; RV64IZFH-NEXT: srli a0, a0, 32
+; RV64IZFH-NEXT: .LBB39_2: # %start
+; RV64IZFH-NEXT: ret
;
; RV32IDZFH-LABEL: fcvt_wu_h_sat_zext:
; RV32IDZFH: # %bb.0: # %start
; RV64IDZFH-NEXT: beqz a0, .LBB39_2
; RV64IDZFH-NEXT: # %bb.1:
; RV64IDZFH-NEXT: fcvt.wu.h a0, fa0, rtz
+; RV64IDZFH-NEXT: slli a0, a0, 32
+; RV64IDZFH-NEXT: srli a0, a0, 32
; RV64IDZFH-NEXT: .LBB39_2: # %start
; RV64IDZFH-NEXT: ret
;