Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3482,24 +3482,44 @@ uint64_t DstWidth = DstVT.getScalarSizeInBits(); assert(SatWidth <= DstWidth && "Saturation width cannot exceed result width"); - // TODO: Saturate to SatWidth explicitly. - if (SatWidth != DstWidth) + // In the absence of FP16 support, promote f16 to f32 and saturate the result. + if (SrcVT == MVT::f16 && !Subtarget->hasFullFP16()) { + SrcVal = DAG.getNode(ISD::FP_EXTEND, SDLoc(Op), MVT::f32, SrcVal); + SrcVT = MVT::f32; + } else if (SrcVT != MVT::f64 && SrcVT != MVT::f32 && SrcVT != MVT::f16) return SDValue(); - // In the absence of FP16 support, promote f16 to f32, like LowerFP_TO_INT(). - if (SrcVT == MVT::f16 && !Subtarget->hasFullFP16()) - return DAG.getNode(Op.getOpcode(), SDLoc(Op), DstVT, - DAG.getNode(ISD::FP_EXTEND, SDLoc(Op), MVT::f32, SrcVal), - Op.getOperand(1)); - + SDLoc DL(Op); // Cases that we can emit directly. if ((SrcVT == MVT::f64 || SrcVT == MVT::f32 || (SrcVT == MVT::f16 && Subtarget->hasFullFP16())) && - (DstVT == MVT::i64 || DstVT == MVT::i32)) - return Op; + DstVT == SatVT && (DstVT == MVT::i64 || DstVT == MVT::i32)) + return DAG.getNode(Op.getOpcode(), DL, DstVT, SrcVal, + DAG.getValueType(DstVT)); - // For all other cases, fall back on the expanded form. - return SDValue(); + // Otherwise we emit a cvt that saturates to a higher BW, and saturate the + // result. This is only valid if the legal cvt is smaller than the saturate + // width. + if (DstWidth < SatWidth) + return SDValue(); + + SDValue NativeCvt = + DAG.getNode(Op.getOpcode(), DL, DstVT, SrcVal, DAG.getValueType(DstVT)); + SDValue Sat; + if (Op.getOpcode() == ISD::FP_TO_SINT_SAT) { + SDValue MinC = DAG.getConstant( + APInt::getSignedMaxValue(SatWidth).sextOrSelf(DstWidth), DL, DstVT); + SDValue Min = DAG.getNode(ISD::SMIN, DL, DstVT, NativeCvt, MinC); + SDValue MaxC = DAG.getConstant( + APInt::getSignedMinValue(SatWidth).sextOrSelf(DstWidth), DL, DstVT); + Sat = DAG.getNode(ISD::SMAX, DL, DstVT, Min, MaxC); + } else { + SDValue MinC = DAG.getConstant( + APInt::getAllOnesValue(SatWidth).zextOrSelf(DstWidth), DL, DstVT); + Sat = DAG.getNode(ISD::UMIN, DL, DstVT, NativeCvt, MinC); + } + + return DAG.getNode(ISD::TRUNCATE, DL, DstVT, Sat); } SDValue AArch64TargetLowering::LowerVectorINT_TO_FP(SDValue Op, Index: llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll =================================================================== --- llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll +++ llvm/test/CodeGen/AArch64/fptosi-sat-scalar.ll @@ -20,13 +20,11 @@ define i1 @test_signed_i1_f32(float %f) nounwind { ; CHECK-LABEL: test_signed_i1_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: fmov s1, #-1.00000000 -; CHECK-NEXT: movi d2, #0000000000000000 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w8, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, s0 +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: csel w8, w8, wzr, lt +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: csinv w8, w8, wzr, ge ; CHECK-NEXT: and w0, w8, #0x1 ; CHECK-NEXT: ret %x = call i1 @llvm.fptosi.sat.i1.f32(float %f) @@ -36,15 +34,13 @@ define i8 @test_signed_i8_f32(float %f) nounwind { ; CHECK-LABEL: test_signed_i8_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-1023410176 -; CHECK-NEXT: mov w9, #1123942400 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, s0 +; CHECK-NEXT: mov w9, #127 +; CHECK-NEXT: cmp w8, #127 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #128 +; CHECK-NEXT: mov w9, #-128 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i8 @llvm.fptosi.sat.i8.f32(float %f) ret i8 %x @@ -53,16 +49,13 @@ define i13 @test_signed_i13_f32(float %f) nounwind { ; CHECK-LABEL: test_signed_i13_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-981467136 -; CHECK-NEXT: mov w9, #61440 -; CHECK-NEXT: movk w9, #17791, lsl #16 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, s0 +; CHECK-NEXT: mov w9, #4095 +; CHECK-NEXT: cmp w8, #4095 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #1, lsl #12 // =4096 +; CHECK-NEXT: mov w9, #-4096 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i13 @llvm.fptosi.sat.i13.f32(float %f) ret i13 %x @@ -71,16 +64,13 @@ define i16 @test_signed_i16_f32(float %f) nounwind { ; CHECK-LABEL: test_signed_i16_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-956301312 -; CHECK-NEXT: mov w9, #65024 -; CHECK-NEXT: movk w9, #18175, lsl #16 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, s0 +; CHECK-NEXT: mov w9, #32767 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #8, lsl #12 // =32768 +; CHECK-NEXT: mov w9, #-32768 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i16 @llvm.fptosi.sat.i16.f32(float %f) ret i16 %x @@ -89,16 +79,13 @@ define i19 @test_signed_i19_f32(float %f) nounwind { ; CHECK-LABEL: test_signed_i19_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-931135488 -; CHECK-NEXT: mov w9, #65472 -; CHECK-NEXT: movk w9, #18559, lsl #16 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, s0 +; CHECK-NEXT: mov w9, #262143 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #64, lsl #12 // =262144 +; CHECK-NEXT: mov w9, #-262144 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i19 @llvm.fptosi.sat.i19.f32(float %f) ret i19 %x @@ -116,19 +103,13 @@ define i50 @test_signed_i50_f32(float %f) nounwind { ; CHECK-LABEL: test_signed_i50_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w9, #-671088640 -; CHECK-NEXT: mov w11, #1476395007 -; CHECK-NEXT: fmov s1, w9 ; CHECK-NEXT: fcvtzs x8, s0 -; CHECK-NEXT: mov x10, #-562949953421312 -; CHECK-NEXT: fcmp s0, s1 -; CHECK-NEXT: fmov s1, w11 -; CHECK-NEXT: mov x12, #562949953421311 -; CHECK-NEXT: csel x8, x10, x8, lt -; CHECK-NEXT: fcmp s0, s1 -; CHECK-NEXT: csel x8, x12, x8, gt -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: mov x9, #562949953421311 +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x8, x8, x9, lt +; CHECK-NEXT: mov x9, #-562949953421312 +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x0, x8, x9, gt ; CHECK-NEXT: ret %x = call i50 @llvm.fptosi.sat.i50.f32(float %f) ret i50 %x @@ -219,13 +200,11 @@ define i1 @test_signed_i1_f64(double %f) nounwind { ; CHECK-LABEL: test_signed_i1_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: fmov d1, #-1.00000000 -; CHECK-NEXT: movi d2, #0000000000000000 -; CHECK-NEXT: fmaxnm d1, d0, d1 -; CHECK-NEXT: fminnm d1, d1, d2 -; CHECK-NEXT: fcvtzs w8, d1 -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w8, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, d0 +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: csel w8, w8, wzr, lt +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: csinv w8, w8, wzr, ge ; CHECK-NEXT: and w0, w8, #0x1 ; CHECK-NEXT: ret %x = call i1 @llvm.fptosi.sat.i1.f64(double %f) @@ -235,16 +214,13 @@ define i8 @test_signed_i8_f64(double %f) nounwind { ; CHECK-LABEL: test_signed_i8_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4584664420663164928 -; CHECK-NEXT: mov x9, #211106232532992 -; CHECK-NEXT: movk x9, #16479, lsl #48 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fmaxnm d1, d0, d1 -; CHECK-NEXT: fmov d2, x9 -; CHECK-NEXT: fminnm d1, d1, d2 -; CHECK-NEXT: fcvtzs w8, d1 -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, d0 +; CHECK-NEXT: mov w9, #127 +; CHECK-NEXT: cmp w8, #127 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #128 +; CHECK-NEXT: mov w9, #-128 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i8 @llvm.fptosi.sat.i8.f64(double %f) ret i8 %x @@ -253,16 +229,13 @@ define i13 @test_signed_i13_f64(double %f) nounwind { ; CHECK-LABEL: test_signed_i13_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4562146422526312448 -; CHECK-NEXT: mov x9, #279275953455104 -; CHECK-NEXT: movk x9, #16559, lsl #48 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fmaxnm d1, d0, d1 -; CHECK-NEXT: fmov d2, x9 -; CHECK-NEXT: fminnm d1, d1, d2 -; CHECK-NEXT: fcvtzs w8, d1 -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, d0 +; CHECK-NEXT: mov w9, #4095 +; CHECK-NEXT: cmp w8, #4095 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #1, lsl #12 // =4096 +; CHECK-NEXT: mov w9, #-4096 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i13 @llvm.fptosi.sat.i13.f64(double %f) ret i13 %x @@ -271,16 +244,13 @@ define i16 @test_signed_i16_f64(double %f) nounwind { ; CHECK-LABEL: test_signed_i16_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4548635623644200960 -; CHECK-NEXT: mov x9, #281200098803712 -; CHECK-NEXT: movk x9, #16607, lsl #48 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fmaxnm d1, d0, d1 -; CHECK-NEXT: fmov d2, x9 -; CHECK-NEXT: fminnm d1, d1, d2 -; CHECK-NEXT: fcvtzs w8, d1 -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, d0 +; CHECK-NEXT: mov w9, #32767 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #8, lsl #12 // =32768 +; CHECK-NEXT: mov w9, #-32768 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i16 @llvm.fptosi.sat.i16.f64(double %f) ret i16 %x @@ -289,16 +259,13 @@ define i19 @test_signed_i19_f64(double %f) nounwind { ; CHECK-LABEL: test_signed_i19_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4535124824762089472 -; CHECK-NEXT: mov x9, #281440616972288 -; CHECK-NEXT: movk x9, #16655, lsl #48 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fmaxnm d1, d0, d1 -; CHECK-NEXT: fmov d2, x9 -; CHECK-NEXT: fminnm d1, d1, d2 -; CHECK-NEXT: fcvtzs w8, d1 -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: fcvtzs w8, d0 +; CHECK-NEXT: mov w9, #262143 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: cmn w8, #64, lsl #12 // =262144 +; CHECK-NEXT: mov w9, #-262144 +; CHECK-NEXT: csel w0, w8, w9, gt ; CHECK-NEXT: ret %x = call i19 @llvm.fptosi.sat.i19.f64(double %f) ret i19 %x @@ -316,16 +283,13 @@ define i50 @test_signed_i50_f64(double %f) nounwind { ; CHECK-LABEL: test_signed_i50_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4395513236313604096 -; CHECK-NEXT: mov x9, #-16 -; CHECK-NEXT: movk x9, #17151, lsl #48 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fmaxnm d1, d0, d1 -; CHECK-NEXT: fmov d2, x9 -; CHECK-NEXT: fminnm d1, d1, d2 -; CHECK-NEXT: fcvtzs x8, d1 -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: fcvtzs x8, d0 +; CHECK-NEXT: mov x9, #562949953421311 +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x8, x8, x9, lt +; CHECK-NEXT: mov x9, #-562949953421312 +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x0, x8, x9, gt ; CHECK-NEXT: ret %x = call i50 @llvm.fptosi.sat.i50.f64(double %f) ret i50 %x @@ -414,93 +378,134 @@ declare i128 @llvm.fptosi.sat.i128.f16(half) define i1 @test_signed_i1_f16(half %f) nounwind { -; CHECK-LABEL: test_signed_i1_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: fmov s1, #-1.00000000 -; CHECK-NEXT: movi d2, #0000000000000000 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w8, wzr, w8, vs -; CHECK-NEXT: and w0, w8, #0x1 -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_signed_i1_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzs w8, s0 +; CHECK-CVT-NEXT: cmp w8, #0 +; CHECK-CVT-NEXT: csel w8, w8, wzr, lt +; CHECK-CVT-NEXT: cmp w8, #0 +; CHECK-CVT-NEXT: csinv w8, w8, wzr, ge +; CHECK-CVT-NEXT: and w0, w8, #0x1 +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_signed_i1_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzs w8, h0 +; CHECK-FP16-NEXT: cmp w8, #0 +; CHECK-FP16-NEXT: csel w8, w8, wzr, lt +; CHECK-FP16-NEXT: cmp w8, #0 +; CHECK-FP16-NEXT: csinv w8, w8, wzr, ge +; CHECK-FP16-NEXT: and w0, w8, #0x1 +; CHECK-FP16-NEXT: ret %x = call i1 @llvm.fptosi.sat.i1.f16(half %f) ret i1 %x } define i8 @test_signed_i8_f16(half %f) nounwind { -; CHECK-LABEL: test_signed_i8_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-1023410176 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: mov w9, #1123942400 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_signed_i8_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzs w9, s0 +; CHECK-CVT-NEXT: mov w8, #127 +; CHECK-CVT-NEXT: cmp w9, #127 +; CHECK-CVT-NEXT: csel w8, w9, w8, lt +; CHECK-CVT-NEXT: cmn w8, #128 +; CHECK-CVT-NEXT: mov w9, #-128 +; CHECK-CVT-NEXT: csel w0, w8, w9, gt +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_signed_i8_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzs w8, h0 +; CHECK-FP16-NEXT: mov w9, #127 +; CHECK-FP16-NEXT: cmp w8, #127 +; CHECK-FP16-NEXT: csel w8, w8, w9, lt +; CHECK-FP16-NEXT: cmn w8, #128 +; CHECK-FP16-NEXT: mov w9, #-128 +; CHECK-FP16-NEXT: csel w0, w8, w9, gt +; CHECK-FP16-NEXT: ret %x = call i8 @llvm.fptosi.sat.i8.f16(half %f) ret i8 %x } define i13 @test_signed_i13_f16(half %f) nounwind { -; CHECK-LABEL: test_signed_i13_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-981467136 -; CHECK-NEXT: mov w9, #61440 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movk w9, #17791, lsl #16 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_signed_i13_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzs w9, s0 +; CHECK-CVT-NEXT: mov w8, #4095 +; CHECK-CVT-NEXT: cmp w9, #4095 +; CHECK-CVT-NEXT: csel w8, w9, w8, lt +; CHECK-CVT-NEXT: cmn w8, #1, lsl #12 // =4096 +; CHECK-CVT-NEXT: mov w9, #-4096 +; CHECK-CVT-NEXT: csel w0, w8, w9, gt +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_signed_i13_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzs w8, h0 +; CHECK-FP16-NEXT: mov w9, #4095 +; CHECK-FP16-NEXT: cmp w8, #4095 +; CHECK-FP16-NEXT: csel w8, w8, w9, lt +; CHECK-FP16-NEXT: cmn w8, #1, lsl #12 // =4096 +; CHECK-FP16-NEXT: mov w9, #-4096 +; CHECK-FP16-NEXT: csel w0, w8, w9, gt +; CHECK-FP16-NEXT: ret %x = call i13 @llvm.fptosi.sat.i13.f16(half %f) ret i13 %x } define i16 @test_signed_i16_f16(half %f) nounwind { -; CHECK-LABEL: test_signed_i16_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-956301312 -; CHECK-NEXT: mov w9, #65024 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movk w9, #18175, lsl #16 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_signed_i16_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: mov w8, #32767 +; CHECK-CVT-NEXT: fcvtzs w9, s0 +; CHECK-CVT-NEXT: cmp w9, w8 +; CHECK-CVT-NEXT: csel w8, w9, w8, lt +; CHECK-CVT-NEXT: cmn w8, #8, lsl #12 // =32768 +; CHECK-CVT-NEXT: mov w9, #-32768 +; CHECK-CVT-NEXT: csel w0, w8, w9, gt +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_signed_i16_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzs w8, h0 +; CHECK-FP16-NEXT: mov w9, #32767 +; CHECK-FP16-NEXT: cmp w8, w9 +; CHECK-FP16-NEXT: csel w8, w8, w9, lt +; CHECK-FP16-NEXT: cmn w8, #8, lsl #12 // =32768 +; CHECK-FP16-NEXT: mov w9, #-32768 +; CHECK-FP16-NEXT: csel w0, w8, w9, gt +; CHECK-FP16-NEXT: ret %x = call i16 @llvm.fptosi.sat.i16.f16(half %f) ret i16 %x } define i19 @test_signed_i19_f16(half %f) nounwind { -; CHECK-LABEL: test_signed_i19_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-931135488 -; CHECK-NEXT: mov w9, #65472 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movk w9, #18559, lsl #16 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fmaxnm s1, s0, s1 -; CHECK-NEXT: fmov s2, w9 -; CHECK-NEXT: fminnm s1, s1, s2 -; CHECK-NEXT: fcvtzs w8, s1 -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel w0, wzr, w8, vs -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_signed_i19_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: mov w8, #262143 +; CHECK-CVT-NEXT: fcvtzs w9, s0 +; CHECK-CVT-NEXT: cmp w9, w8 +; CHECK-CVT-NEXT: csel w8, w9, w8, lt +; CHECK-CVT-NEXT: cmn w8, #64, lsl #12 // =262144 +; CHECK-CVT-NEXT: mov w9, #-262144 +; CHECK-CVT-NEXT: csel w0, w8, w9, gt +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_signed_i19_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzs w8, h0 +; CHECK-FP16-NEXT: mov w9, #262143 +; CHECK-FP16-NEXT: cmp w8, w9 +; CHECK-FP16-NEXT: csel w8, w8, w9, lt +; CHECK-FP16-NEXT: cmn w8, #64, lsl #12 // =262144 +; CHECK-FP16-NEXT: mov w9, #-262144 +; CHECK-FP16-NEXT: csel w0, w8, w9, gt +; CHECK-FP16-NEXT: ret %x = call i19 @llvm.fptosi.sat.i19.f16(half %f) ret i19 %x } @@ -521,23 +526,28 @@ } define i50 @test_signed_i50_f16(half %f) nounwind { -; CHECK-LABEL: test_signed_i50_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-671088640 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: mov w8, #1476395007 -; CHECK-NEXT: mov x9, #-562949953421312 -; CHECK-NEXT: fcmp s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fcvtzs x8, s0 -; CHECK-NEXT: csel x8, x9, x8, lt -; CHECK-NEXT: mov x9, #562949953421311 -; CHECK-NEXT: fcmp s0, s1 -; CHECK-NEXT: csel x8, x9, x8, gt -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel x0, xzr, x8, vs -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_signed_i50_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: mov x8, #562949953421311 +; CHECK-CVT-NEXT: fcvtzs x9, s0 +; CHECK-CVT-NEXT: cmp x9, x8 +; CHECK-CVT-NEXT: csel x8, x9, x8, lt +; CHECK-CVT-NEXT: mov x9, #-562949953421312 +; CHECK-CVT-NEXT: cmp x8, x9 +; CHECK-CVT-NEXT: csel x0, x8, x9, gt +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_signed_i50_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzs x8, h0 +; CHECK-FP16-NEXT: mov x9, #562949953421311 +; CHECK-FP16-NEXT: cmp x8, x9 +; CHECK-FP16-NEXT: csel x8, x8, x9, lt +; CHECK-FP16-NEXT: mov x9, #-562949953421312 +; CHECK-FP16-NEXT: cmp x8, x9 +; CHECK-FP16-NEXT: csel x0, x8, x9, gt +; CHECK-FP16-NEXT: ret %x = call i50 @llvm.fptosi.sat.i50.f16(half %f) ret i50 %x } Index: llvm/test/CodeGen/AArch64/fptosi-sat-vector.ll =================================================================== --- llvm/test/CodeGen/AArch64/fptosi-sat-vector.ll +++ llvm/test/CodeGen/AArch64/fptosi-sat-vector.ll @@ -893,30 +893,22 @@ define <2 x i50> @test_signed_v2f32_v2i50(<2 x float> %f) { ; CHECK-LABEL: test_signed_v2f32_v2i50: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-671088640 ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 ; CHECK-NEXT: mov s1, v0.s[1] -; CHECK-NEXT: mov w10, #1476395007 -; CHECK-NEXT: fmov s2, w8 +; CHECK-NEXT: mov x8, #562949953421311 +; CHECK-NEXT: fcvtzs x11, s1 +; CHECK-NEXT: cmp x11, x8 ; CHECK-NEXT: mov x9, #-562949953421312 -; CHECK-NEXT: fmov s3, w10 -; CHECK-NEXT: fcvtzs x10, s1 -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: mov x11, #562949953421311 -; CHECK-NEXT: csel x10, x9, x10, lt -; CHECK-NEXT: fcmp s1, s3 -; CHECK-NEXT: csel x10, x11, x10, gt -; CHECK-NEXT: fcmp s1, s1 -; CHECK-NEXT: fcvtzs x8, s0 -; CHECK-NEXT: csel x10, xzr, x10, vs -; CHECK-NEXT: fcmp s0, s2 -; CHECK-NEXT: csel x8, x9, x8, lt -; CHECK-NEXT: fcmp s0, s3 -; CHECK-NEXT: csel x8, x11, x8, gt -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel x8, xzr, x8, vs +; CHECK-NEXT: csel x11, x11, x8, lt +; CHECK-NEXT: fcvtzs x10, s0 +; CHECK-NEXT: cmp x11, x9 +; CHECK-NEXT: csel x11, x11, x9, gt +; CHECK-NEXT: cmp x10, x8 +; CHECK-NEXT: csel x8, x10, x8, lt +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x8, x8, x9, gt ; CHECK-NEXT: fmov d0, x8 -; CHECK-NEXT: mov v0.d[1], x10 +; CHECK-NEXT: mov v0.d[1], x11 ; CHECK-NEXT: ret %x = call <2 x i50> @llvm.fptosi.sat.v2f32.v2i50(<2 x float> %f) ret <2 x i50> %x @@ -1088,20 +1080,18 @@ ; CHECK-LABEL: test_signed_v2f64_v2i1: ; CHECK: // %bb.0: ; CHECK-NEXT: mov d1, v0.d[1] -; CHECK-NEXT: fmov d2, #-1.00000000 -; CHECK-NEXT: movi d3, #0000000000000000 -; CHECK-NEXT: fmaxnm d4, d1, d2 -; CHECK-NEXT: fcmp d1, d1 -; CHECK-NEXT: fmaxnm d1, d0, d2 -; CHECK-NEXT: fminnm d2, d4, d3 -; CHECK-NEXT: fminnm d1, d1, d3 -; CHECK-NEXT: fcvtzs w8, d2 ; CHECK-NEXT: fcvtzs w9, d1 -; CHECK-NEXT: csel w8, wzr, w8, vs -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w9, wzr, w9, vs -; CHECK-NEXT: fmov s0, w9 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: cmp w9, #0 +; CHECK-NEXT: csel w9, w9, wzr, lt +; CHECK-NEXT: fcvtzs w8, d0 +; CHECK-NEXT: cmp w9, #0 +; CHECK-NEXT: csinv w9, w9, wzr, ge +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: csel w8, w8, wzr, lt +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: csinv w8, w8, wzr, ge +; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: mov v0.s[1], w9 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i1> @llvm.fptosi.sat.v2f64.v2i1(<2 x double> %f) @@ -1111,24 +1101,21 @@ define <2 x i8> @test_signed_v2f64_v2i8(<2 x double> %f) { ; CHECK-LABEL: test_signed_v2f64_v2i8: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4584664420663164928 -; CHECK-NEXT: mov x9, #211106232532992 ; CHECK-NEXT: mov d1, v0.d[1] -; CHECK-NEXT: movk x9, #16479, lsl #48 -; CHECK-NEXT: fmov d2, x8 -; CHECK-NEXT: fmaxnm d3, d1, d2 -; CHECK-NEXT: fmov d4, x9 -; CHECK-NEXT: fcmp d1, d1 -; CHECK-NEXT: fmaxnm d1, d0, d2 -; CHECK-NEXT: fminnm d2, d3, d4 -; CHECK-NEXT: fminnm d1, d1, d4 -; CHECK-NEXT: fcvtzs w8, d2 -; CHECK-NEXT: fcvtzs w9, d1 -; CHECK-NEXT: csel w8, wzr, w8, vs -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w9, wzr, w9, vs -; CHECK-NEXT: fmov s0, w9 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: fcvtzs w11, d1 +; CHECK-NEXT: mov w8, #127 +; CHECK-NEXT: cmp w11, #127 +; CHECK-NEXT: csel w11, w11, w8, lt +; CHECK-NEXT: mov w9, #-128 +; CHECK-NEXT: fcvtzs w10, d0 +; CHECK-NEXT: cmn w11, #128 +; CHECK-NEXT: csel w11, w11, w9, gt +; CHECK-NEXT: cmp w10, #127 +; CHECK-NEXT: csel w8, w10, w8, lt +; CHECK-NEXT: cmn w8, #128 +; CHECK-NEXT: csel w8, w8, w9, gt +; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: mov v0.s[1], w11 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i8> @llvm.fptosi.sat.v2f64.v2i8(<2 x double> %f) @@ -1138,24 +1125,21 @@ define <2 x i13> @test_signed_v2f64_v2i13(<2 x double> %f) { ; CHECK-LABEL: test_signed_v2f64_v2i13: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4562146422526312448 -; CHECK-NEXT: mov x9, #279275953455104 ; CHECK-NEXT: mov d1, v0.d[1] -; CHECK-NEXT: movk x9, #16559, lsl #48 -; CHECK-NEXT: fmov d2, x8 -; CHECK-NEXT: fmaxnm d3, d1, d2 -; CHECK-NEXT: fmov d4, x9 -; CHECK-NEXT: fcmp d1, d1 -; CHECK-NEXT: fmaxnm d1, d0, d2 -; CHECK-NEXT: fminnm d2, d3, d4 -; CHECK-NEXT: fminnm d1, d1, d4 -; CHECK-NEXT: fcvtzs w8, d2 -; CHECK-NEXT: fcvtzs w9, d1 -; CHECK-NEXT: csel w8, wzr, w8, vs -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w9, wzr, w9, vs -; CHECK-NEXT: fmov s0, w9 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: fcvtzs w11, d1 +; CHECK-NEXT: mov w8, #4095 +; CHECK-NEXT: cmp w11, #4095 +; CHECK-NEXT: csel w11, w11, w8, lt +; CHECK-NEXT: mov w9, #-4096 +; CHECK-NEXT: fcvtzs w10, d0 +; CHECK-NEXT: cmn w11, #1, lsl #12 // =4096 +; CHECK-NEXT: csel w11, w11, w9, gt +; CHECK-NEXT: cmp w10, #4095 +; CHECK-NEXT: csel w8, w10, w8, lt +; CHECK-NEXT: cmn w8, #1, lsl #12 // =4096 +; CHECK-NEXT: csel w8, w8, w9, gt +; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: mov v0.s[1], w11 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i13> @llvm.fptosi.sat.v2f64.v2i13(<2 x double> %f) @@ -1165,24 +1149,21 @@ define <2 x i16> @test_signed_v2f64_v2i16(<2 x double> %f) { ; CHECK-LABEL: test_signed_v2f64_v2i16: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4548635623644200960 -; CHECK-NEXT: mov x9, #281200098803712 ; CHECK-NEXT: mov d1, v0.d[1] -; CHECK-NEXT: movk x9, #16607, lsl #48 -; CHECK-NEXT: fmov d2, x8 -; CHECK-NEXT: fmaxnm d3, d1, d2 -; CHECK-NEXT: fmov d4, x9 -; CHECK-NEXT: fcmp d1, d1 -; CHECK-NEXT: fmaxnm d1, d0, d2 -; CHECK-NEXT: fminnm d2, d3, d4 -; CHECK-NEXT: fminnm d1, d1, d4 -; CHECK-NEXT: fcvtzs w8, d2 -; CHECK-NEXT: fcvtzs w9, d1 -; CHECK-NEXT: csel w8, wzr, w8, vs -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w9, wzr, w9, vs -; CHECK-NEXT: fmov s0, w9 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: mov w8, #32767 +; CHECK-NEXT: fcvtzs w11, d1 +; CHECK-NEXT: cmp w11, w8 +; CHECK-NEXT: csel w11, w11, w8, lt +; CHECK-NEXT: mov w9, #-32768 +; CHECK-NEXT: fcvtzs w10, d0 +; CHECK-NEXT: cmn w11, #8, lsl #12 // =32768 +; CHECK-NEXT: csel w11, w11, w9, gt +; CHECK-NEXT: cmp w10, w8 +; CHECK-NEXT: csel w8, w10, w8, lt +; CHECK-NEXT: cmn w8, #8, lsl #12 // =32768 +; CHECK-NEXT: csel w8, w8, w9, gt +; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: mov v0.s[1], w11 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i16> @llvm.fptosi.sat.v2f64.v2i16(<2 x double> %f) @@ -1192,24 +1173,21 @@ define <2 x i19> @test_signed_v2f64_v2i19(<2 x double> %f) { ; CHECK-LABEL: test_signed_v2f64_v2i19: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4535124824762089472 -; CHECK-NEXT: mov x9, #281440616972288 ; CHECK-NEXT: mov d1, v0.d[1] -; CHECK-NEXT: movk x9, #16655, lsl #48 -; CHECK-NEXT: fmov d2, x8 -; CHECK-NEXT: fmaxnm d3, d1, d2 -; CHECK-NEXT: fmov d4, x9 -; CHECK-NEXT: fcmp d1, d1 -; CHECK-NEXT: fmaxnm d1, d0, d2 -; CHECK-NEXT: fminnm d2, d3, d4 -; CHECK-NEXT: fminnm d1, d1, d4 -; CHECK-NEXT: fcvtzs w8, d2 -; CHECK-NEXT: fcvtzs w9, d1 -; CHECK-NEXT: csel w8, wzr, w8, vs -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel w9, wzr, w9, vs -; CHECK-NEXT: fmov s0, w9 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: mov w8, #262143 +; CHECK-NEXT: fcvtzs w11, d1 +; CHECK-NEXT: cmp w11, w8 +; CHECK-NEXT: csel w11, w11, w8, lt +; CHECK-NEXT: mov w9, #-262144 +; CHECK-NEXT: fcvtzs w10, d0 +; CHECK-NEXT: cmn w11, #64, lsl #12 // =262144 +; CHECK-NEXT: csel w11, w11, w9, gt +; CHECK-NEXT: cmp w10, w8 +; CHECK-NEXT: csel w8, w10, w8, lt +; CHECK-NEXT: cmn w8, #64, lsl #12 // =262144 +; CHECK-NEXT: csel w8, w8, w9, gt +; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: mov v0.s[1], w11 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i19> @llvm.fptosi.sat.v2f64.v2i19(<2 x double> %f) @@ -1233,24 +1211,21 @@ define <2 x i50> @test_signed_v2f64_v2i50(<2 x double> %f) { ; CHECK-LABEL: test_signed_v2f64_v2i50: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-4395513236313604096 -; CHECK-NEXT: mov x9, #-16 ; CHECK-NEXT: mov d1, v0.d[1] -; CHECK-NEXT: movk x9, #17151, lsl #48 -; CHECK-NEXT: fmov d2, x8 -; CHECK-NEXT: fmaxnm d3, d1, d2 -; CHECK-NEXT: fmov d4, x9 -; CHECK-NEXT: fcmp d1, d1 -; CHECK-NEXT: fmaxnm d1, d0, d2 -; CHECK-NEXT: fminnm d2, d3, d4 -; CHECK-NEXT: fminnm d1, d1, d4 -; CHECK-NEXT: fcvtzs x8, d2 -; CHECK-NEXT: fcvtzs x9, d1 -; CHECK-NEXT: csel x8, xzr, x8, vs -; CHECK-NEXT: fcmp d0, d0 -; CHECK-NEXT: csel x9, xzr, x9, vs -; CHECK-NEXT: fmov d0, x9 -; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: mov x8, #562949953421311 +; CHECK-NEXT: fcvtzs x11, d1 +; CHECK-NEXT: cmp x11, x8 +; CHECK-NEXT: mov x9, #-562949953421312 +; CHECK-NEXT: csel x11, x11, x8, lt +; CHECK-NEXT: fcvtzs x10, d0 +; CHECK-NEXT: cmp x11, x9 +; CHECK-NEXT: csel x11, x11, x9, gt +; CHECK-NEXT: cmp x10, x8 +; CHECK-NEXT: csel x8, x10, x8, lt +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x8, x8, x9, gt +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: mov v0.d[1], x11 ; CHECK-NEXT: ret %x = call <2 x i50> @llvm.fptosi.sat.v2f64.v2i50(<2 x double> %f) ret <2 x i50> %x @@ -1512,42 +1487,35 @@ ; ; CHECK-FP16-LABEL: test_signed_v4f16_v4i19: ; CHECK-FP16: // %bb.0: -; CHECK-FP16-NEXT: mov w8, #-931135488 -; CHECK-FP16-NEXT: mov w9, #65472 ; CHECK-FP16-NEXT: // kill: def $d0 killed $d0 def $q0 -; CHECK-FP16-NEXT: movk w9, #18559, lsl #16 -; CHECK-FP16-NEXT: fcvt s2, h0 -; CHECK-FP16-NEXT: fmov s3, w8 -; CHECK-FP16-NEXT: fmov s4, w9 -; CHECK-FP16-NEXT: fmaxnm s5, s2, s3 ; CHECK-FP16-NEXT: mov h1, v0.h[1] -; CHECK-FP16-NEXT: fminnm s5, s5, s4 -; CHECK-FP16-NEXT: fcvtzs w8, s5 -; CHECK-FP16-NEXT: mov h5, v0.h[2] -; CHECK-FP16-NEXT: mov h0, v0.h[3] -; CHECK-FP16-NEXT: fcvt s1, h1 -; CHECK-FP16-NEXT: fcvt s6, h0 -; CHECK-FP16-NEXT: fmaxnm s0, s1, s3 -; CHECK-FP16-NEXT: fminnm s0, s0, s4 -; CHECK-FP16-NEXT: fcvt s5, h5 -; CHECK-FP16-NEXT: fcmp s1, s1 -; CHECK-FP16-NEXT: fcvtzs w9, s0 -; CHECK-FP16-NEXT: fmaxnm s0, s5, s3 -; CHECK-FP16-NEXT: csel w9, wzr, w9, vs -; CHECK-FP16-NEXT: fcmp s2, s2 -; CHECK-FP16-NEXT: fmaxnm s1, s6, s3 -; CHECK-FP16-NEXT: fminnm s3, s0, s4 -; CHECK-FP16-NEXT: csel w8, wzr, w8, vs -; CHECK-FP16-NEXT: fminnm s1, s1, s4 -; CHECK-FP16-NEXT: fmov s0, w8 -; CHECK-FP16-NEXT: fcvtzs w8, s3 -; CHECK-FP16-NEXT: fcmp s5, s5 -; CHECK-FP16-NEXT: mov v0.s[1], w9 -; CHECK-FP16-NEXT: fcvtzs w9, s1 -; CHECK-FP16-NEXT: csel w8, wzr, w8, vs -; CHECK-FP16-NEXT: fcmp s6, s6 -; CHECK-FP16-NEXT: mov v0.s[2], w8 -; CHECK-FP16-NEXT: csel w8, wzr, w9, vs +; CHECK-FP16-NEXT: mov w8, #262143 +; CHECK-FP16-NEXT: fcvtzs w11, h1 +; CHECK-FP16-NEXT: cmp w11, w8 +; CHECK-FP16-NEXT: csel w11, w11, w8, lt +; CHECK-FP16-NEXT: mov w9, #-262144 +; CHECK-FP16-NEXT: fcvtzs w10, h0 +; CHECK-FP16-NEXT: cmn w11, #64, lsl #12 // =262144 +; CHECK-FP16-NEXT: csel w11, w11, w9, gt +; CHECK-FP16-NEXT: cmp w10, w8 +; CHECK-FP16-NEXT: csel w10, w10, w8, lt +; CHECK-FP16-NEXT: cmn w10, #64, lsl #12 // =262144 +; CHECK-FP16-NEXT: mov h2, v0.h[2] +; CHECK-FP16-NEXT: csel w10, w10, w9, gt +; CHECK-FP16-NEXT: mov h1, v0.h[3] +; CHECK-FP16-NEXT: fmov s0, w10 +; CHECK-FP16-NEXT: fcvtzs w10, h2 +; CHECK-FP16-NEXT: cmp w10, w8 +; CHECK-FP16-NEXT: csel w10, w10, w8, lt +; CHECK-FP16-NEXT: mov v0.s[1], w11 +; CHECK-FP16-NEXT: fcvtzs w11, h1 +; CHECK-FP16-NEXT: cmn w10, #64, lsl #12 // =262144 +; CHECK-FP16-NEXT: csel w10, w10, w9, gt +; CHECK-FP16-NEXT: cmp w11, w8 +; CHECK-FP16-NEXT: csel w8, w11, w8, lt +; CHECK-FP16-NEXT: cmn w8, #64, lsl #12 // =262144 +; CHECK-FP16-NEXT: mov v0.s[2], w10 +; CHECK-FP16-NEXT: csel w8, w8, w9, gt ; CHECK-FP16-NEXT: mov v0.s[3], w8 ; CHECK-FP16-NEXT: ret %x = call <4 x i19> @llvm.fptosi.sat.v4f16.v4i19(<4 x half> %f) @@ -1581,51 +1549,69 @@ } define <4 x i50> @test_signed_v4f16_v4i50(<4 x half> %f) { -; CHECK-LABEL: test_signed_v4f16_v4i50: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #-671088640 -; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 -; CHECK-NEXT: fcvt s1, h0 -; CHECK-NEXT: mov w10, #1476395007 -; CHECK-NEXT: fmov s2, w8 -; CHECK-NEXT: mov x9, #-562949953421312 -; CHECK-NEXT: fcvtzs x12, s1 -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: fmov s3, w10 -; CHECK-NEXT: mov x11, #562949953421311 -; CHECK-NEXT: csel x8, x9, x12, lt -; CHECK-NEXT: fcmp s1, s3 -; CHECK-NEXT: csel x8, x11, x8, gt -; CHECK-NEXT: fcmp s1, s1 -; CHECK-NEXT: mov h1, v0.h[1] -; CHECK-NEXT: fcvt s1, h1 -; CHECK-NEXT: fcvtzs x10, s1 -; CHECK-NEXT: csel x0, xzr, x8, vs -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: csel x8, x9, x10, lt -; CHECK-NEXT: fcmp s1, s3 -; CHECK-NEXT: csel x8, x11, x8, gt -; CHECK-NEXT: fcmp s1, s1 -; CHECK-NEXT: mov h1, v0.h[2] -; CHECK-NEXT: fcvt s1, h1 -; CHECK-NEXT: fcvtzs x10, s1 -; CHECK-NEXT: csel x1, xzr, x8, vs -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: mov h0, v0.h[3] -; CHECK-NEXT: csel x8, x9, x10, lt -; CHECK-NEXT: fcmp s1, s3 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: csel x8, x11, x8, gt -; CHECK-NEXT: fcmp s1, s1 -; CHECK-NEXT: fcvtzs x12, s0 -; CHECK-NEXT: csel x2, xzr, x8, vs -; CHECK-NEXT: fcmp s0, s2 -; CHECK-NEXT: csel x8, x9, x12, lt -; CHECK-NEXT: fcmp s0, s3 -; CHECK-NEXT: csel x8, x11, x8, gt -; CHECK-NEXT: fcmp s0, s0 -; CHECK-NEXT: csel x3, xzr, x8, vs -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_signed_v4f16_v4i50: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: fcvt s1, h0 +; CHECK-CVT-NEXT: mov x8, #562949953421311 +; CHECK-CVT-NEXT: fcvtzs x10, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: cmp x10, x8 +; CHECK-CVT-NEXT: mov x9, #-562949953421312 +; CHECK-CVT-NEXT: fcvt s1, h1 +; CHECK-CVT-NEXT: csel x10, x10, x8, lt +; CHECK-CVT-NEXT: fcvtzs x11, s1 +; CHECK-CVT-NEXT: cmp x10, x9 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: csel x0, x10, x9, gt +; CHECK-CVT-NEXT: cmp x11, x8 +; CHECK-CVT-NEXT: fcvt s1, h1 +; CHECK-CVT-NEXT: csel x10, x11, x8, lt +; CHECK-CVT-NEXT: fcvtzs x12, s1 +; CHECK-CVT-NEXT: cmp x10, x9 +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: csel x1, x10, x9, gt +; CHECK-CVT-NEXT: cmp x12, x8 +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: csel x10, x12, x8, lt +; CHECK-CVT-NEXT: fcvtzs x13, s0 +; CHECK-CVT-NEXT: cmp x10, x9 +; CHECK-CVT-NEXT: csel x2, x10, x9, gt +; CHECK-CVT-NEXT: cmp x13, x8 +; CHECK-CVT-NEXT: csel x8, x13, x8, lt +; CHECK-CVT-NEXT: cmp x8, x9 +; CHECK-CVT-NEXT: csel x3, x8, x9, gt +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_signed_v4f16_v4i50: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-FP16-NEXT: fcvtzs x8, h0 +; CHECK-FP16-NEXT: mov x9, #562949953421311 +; CHECK-FP16-NEXT: cmp x8, x9 +; CHECK-FP16-NEXT: mov x10, #-562949953421312 +; CHECK-FP16-NEXT: mov h1, v0.h[1] +; CHECK-FP16-NEXT: csel x8, x8, x9, lt +; CHECK-FP16-NEXT: fcvtzs x11, h1 +; CHECK-FP16-NEXT: cmp x8, x10 +; CHECK-FP16-NEXT: csel x0, x8, x10, gt +; CHECK-FP16-NEXT: cmp x11, x9 +; CHECK-FP16-NEXT: mov h1, v0.h[2] +; CHECK-FP16-NEXT: csel x8, x11, x9, lt +; CHECK-FP16-NEXT: fcvtzs x12, h1 +; CHECK-FP16-NEXT: cmp x8, x10 +; CHECK-FP16-NEXT: csel x1, x8, x10, gt +; CHECK-FP16-NEXT: cmp x12, x9 +; CHECK-FP16-NEXT: mov h0, v0.h[3] +; CHECK-FP16-NEXT: csel x8, x12, x9, lt +; CHECK-FP16-NEXT: fcvtzs x13, h0 +; CHECK-FP16-NEXT: cmp x8, x10 +; CHECK-FP16-NEXT: csel x2, x8, x10, gt +; CHECK-FP16-NEXT: cmp x13, x9 +; CHECK-FP16-NEXT: csel x8, x13, x9, lt +; CHECK-FP16-NEXT: cmp x8, x10 +; CHECK-FP16-NEXT: csel x3, x8, x10, gt +; CHECK-FP16-NEXT: ret %x = call <4 x i50> @llvm.fptosi.sat.v4f16.v4i50(<4 x half> %f) ret <4 x i50> %x } Index: llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll =================================================================== --- llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll +++ llvm/test/CodeGen/AArch64/fptoui-sat-scalar.ll @@ -20,11 +20,9 @@ define i1 @test_unsigned_i1_f32(float %f) nounwind { ; CHECK-LABEL: test_unsigned_i1_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, #1.00000000 -; CHECK-NEXT: fminnm s0, s0, s1 ; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: cmp w8, #1 +; CHECK-NEXT: csinc w8, w8, wzr, lo ; CHECK-NEXT: and w0, w8, #0x1 ; CHECK-NEXT: ret %x = call i1 @llvm.fptoui.sat.i1.f32(float %f) @@ -34,12 +32,10 @@ define i8 @test_unsigned_i8_f32(float %f) nounwind { ; CHECK-LABEL: test_unsigned_i8_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: mov w8, #1132396544 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: cmp w8, #255 +; CHECK-NEXT: mov w9, #255 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i8 @llvm.fptoui.sat.i8.f32(float %f) ret i8 %x @@ -48,13 +44,10 @@ define i13 @test_unsigned_i13_f32(float %f) nounwind { ; CHECK-LABEL: test_unsigned_i13_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #63488 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk w8, #17919, lsl #16 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: mov w9, #8191 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i13 @llvm.fptoui.sat.i13.f32(float %f) ret i13 %x @@ -63,13 +56,10 @@ define i16 @test_unsigned_i16_f32(float %f) nounwind { ; CHECK-LABEL: test_unsigned_i16_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #65280 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk w8, #18303, lsl #16 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: mov w9, #65535 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i16 @llvm.fptoui.sat.i16.f32(float %f) ret i16 %x @@ -78,13 +68,10 @@ define i19 @test_unsigned_i19_f32(float %f) nounwind { ; CHECK-LABEL: test_unsigned_i19_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #65504 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk w8, #18687, lsl #16 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: mov w9, #524287 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i19 @llvm.fptoui.sat.i19.f32(float %f) ret i19 %x @@ -102,14 +89,10 @@ define i50 @test_unsigned_i50_f32(float %f) nounwind { ; CHECK-LABEL: test_unsigned_i50_f32: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w9, #1484783615 ; CHECK-NEXT: fcvtzu x8, s0 -; CHECK-NEXT: fcmp s0, #0.0 -; CHECK-NEXT: fmov s1, w9 -; CHECK-NEXT: csel x8, xzr, x8, lt -; CHECK-NEXT: fcmp s0, s1 ; CHECK-NEXT: mov x9, #1125899906842623 -; CHECK-NEXT: csel x0, x9, x8, gt +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x0, x8, x9, lo ; CHECK-NEXT: ret %x = call i50 @llvm.fptoui.sat.i50.f32(float %f) ret i50 %x @@ -187,11 +170,9 @@ define i1 @test_unsigned_i1_f64(double %f) nounwind { ; CHECK-LABEL: test_unsigned_i1_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d1, #1.00000000 -; CHECK-NEXT: fminnm d0, d0, d1 ; CHECK-NEXT: fcvtzu w8, d0 +; CHECK-NEXT: cmp w8, #1 +; CHECK-NEXT: csinc w8, w8, wzr, lo ; CHECK-NEXT: and w0, w8, #0x1 ; CHECK-NEXT: ret %x = call i1 @llvm.fptoui.sat.i1.f64(double %f) @@ -201,13 +182,10 @@ define i8 @test_unsigned_i8_f64(double %f) nounwind { ; CHECK-LABEL: test_unsigned_i8_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #246290604621824 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16495, lsl #48 -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fminnm d0, d0, d1 -; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: fcvtzu w8, d0 +; CHECK-NEXT: cmp w8, #255 +; CHECK-NEXT: mov w9, #255 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i8 @llvm.fptoui.sat.i8.f64(double %f) ret i8 %x @@ -216,13 +194,10 @@ define i13 @test_unsigned_i13_f64(double %f) nounwind { ; CHECK-LABEL: test_unsigned_i13_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #280375465082880 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16575, lsl #48 -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fminnm d0, d0, d1 -; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: fcvtzu w8, d0 +; CHECK-NEXT: mov w9, #8191 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i13 @llvm.fptoui.sat.i13.f64(double %f) ret i13 %x @@ -231,13 +206,10 @@ define i16 @test_unsigned_i16_f64(double %f) nounwind { ; CHECK-LABEL: test_unsigned_i16_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #281337537757184 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16623, lsl #48 -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fminnm d0, d0, d1 -; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: fcvtzu w8, d0 +; CHECK-NEXT: mov w9, #65535 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i16 @llvm.fptoui.sat.i16.f64(double %f) ret i16 %x @@ -246,13 +218,10 @@ define i19 @test_unsigned_i19_f64(double %f) nounwind { ; CHECK-LABEL: test_unsigned_i19_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #281457796841472 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16671, lsl #48 -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fminnm d0, d0, d1 -; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: fcvtzu w8, d0 +; CHECK-NEXT: mov w9, #524287 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w0, w8, w9, lo ; CHECK-NEXT: ret %x = call i19 @llvm.fptoui.sat.i19.f64(double %f) ret i19 %x @@ -270,13 +239,10 @@ define i50 @test_unsigned_i50_f64(double %f) nounwind { ; CHECK-LABEL: test_unsigned_i50_f64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-8 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #17167, lsl #48 -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d1, x8 -; CHECK-NEXT: fminnm d0, d0, d1 -; CHECK-NEXT: fcvtzu x0, d0 +; CHECK-NEXT: fcvtzu x8, d0 +; CHECK-NEXT: mov x9, #1125899906842623 +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x0, x8, x9, lo ; CHECK-NEXT: ret %x = call i50 @llvm.fptoui.sat.i50.f64(double %f) ret i50 %x @@ -352,79 +318,106 @@ declare i128 @llvm.fptoui.sat.i128.f16(half) define i1 @test_unsigned_i1_f16(half %f) nounwind { -; CHECK-LABEL: test_unsigned_i1_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, #1.00000000 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w8, s0 -; CHECK-NEXT: and w0, w8, #0x1 -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_unsigned_i1_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzu w8, s0 +; CHECK-CVT-NEXT: cmp w8, #1 +; CHECK-CVT-NEXT: csinc w8, w8, wzr, lo +; CHECK-CVT-NEXT: and w0, w8, #0x1 +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_unsigned_i1_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzu w8, h0 +; CHECK-FP16-NEXT: cmp w8, #1 +; CHECK-FP16-NEXT: csinc w8, w8, wzr, lo +; CHECK-FP16-NEXT: and w0, w8, #0x1 +; CHECK-FP16-NEXT: ret %x = call i1 @llvm.fptoui.sat.i1.f16(half %f) ret i1 %x } define i8 @test_unsigned_i8_f16(half %f) nounwind { -; CHECK-LABEL: test_unsigned_i8_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: mov w8, #1132396544 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_unsigned_i8_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzu w8, s0 +; CHECK-CVT-NEXT: cmp w8, #255 +; CHECK-CVT-NEXT: mov w9, #255 +; CHECK-CVT-NEXT: csel w0, w8, w9, lo +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_unsigned_i8_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzu w8, h0 +; CHECK-FP16-NEXT: cmp w8, #255 +; CHECK-FP16-NEXT: mov w9, #255 +; CHECK-FP16-NEXT: csel w0, w8, w9, lo +; CHECK-FP16-NEXT: ret %x = call i8 @llvm.fptoui.sat.i8.f16(half %f) ret i8 %x } define i13 @test_unsigned_i13_f16(half %f) nounwind { -; CHECK-LABEL: test_unsigned_i13_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #63488 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk w8, #17919, lsl #16 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_unsigned_i13_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzu w8, s0 +; CHECK-CVT-NEXT: mov w9, #8191 +; CHECK-CVT-NEXT: cmp w8, w9 +; CHECK-CVT-NEXT: csel w0, w8, w9, lo +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_unsigned_i13_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzu w8, h0 +; CHECK-FP16-NEXT: mov w9, #8191 +; CHECK-FP16-NEXT: cmp w8, w9 +; CHECK-FP16-NEXT: csel w0, w8, w9, lo +; CHECK-FP16-NEXT: ret %x = call i13 @llvm.fptoui.sat.i13.f16(half %f) ret i13 %x } define i16 @test_unsigned_i16_f16(half %f) nounwind { -; CHECK-LABEL: test_unsigned_i16_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #65280 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk w8, #18303, lsl #16 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_unsigned_i16_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzu w8, s0 +; CHECK-CVT-NEXT: mov w9, #65535 +; CHECK-CVT-NEXT: cmp w8, w9 +; CHECK-CVT-NEXT: csel w0, w8, w9, lo +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_unsigned_i16_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzu w8, h0 +; CHECK-FP16-NEXT: mov w9, #65535 +; CHECK-FP16-NEXT: cmp w8, w9 +; CHECK-FP16-NEXT: csel w0, w8, w9, lo +; CHECK-FP16-NEXT: ret %x = call i16 @llvm.fptoui.sat.i16.f16(half %f) ret i16 %x } define i19 @test_unsigned_i19_f16(half %f) nounwind { -; CHECK-LABEL: test_unsigned_i19_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #65504 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk w8, #18687, lsl #16 -; CHECK-NEXT: fmaxnm s0, s0, s1 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: fminnm s0, s0, s1 -; CHECK-NEXT: fcvtzu w0, s0 -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_unsigned_i19_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzu w8, s0 +; CHECK-CVT-NEXT: mov w9, #524287 +; CHECK-CVT-NEXT: cmp w8, w9 +; CHECK-CVT-NEXT: csel w0, w8, w9, lo +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_unsigned_i19_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzu w8, h0 +; CHECK-FP16-NEXT: mov w9, #524287 +; CHECK-FP16-NEXT: cmp w8, w9 +; CHECK-FP16-NEXT: csel w0, w8, w9, lo +; CHECK-FP16-NEXT: ret %x = call i19 @llvm.fptoui.sat.i19.f16(half %f) ret i19 %x } @@ -445,18 +438,22 @@ } define i50 @test_unsigned_i50_f16(half %f) nounwind { -; CHECK-LABEL: test_unsigned_i50_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: mov w8, #1484783615 -; CHECK-NEXT: fcvtzu x9, s0 -; CHECK-NEXT: fcmp s0, #0.0 -; CHECK-NEXT: fmov s1, w8 -; CHECK-NEXT: csel x8, xzr, x9, lt -; CHECK-NEXT: fcmp s0, s1 -; CHECK-NEXT: mov x9, #1125899906842623 -; CHECK-NEXT: csel x0, x9, x8, gt -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_unsigned_i50_f16: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzu x8, s0 +; CHECK-CVT-NEXT: mov x9, #1125899906842623 +; CHECK-CVT-NEXT: cmp x8, x9 +; CHECK-CVT-NEXT: csel x0, x8, x9, lo +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_unsigned_i50_f16: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: fcvtzu x8, h0 +; CHECK-FP16-NEXT: mov x9, #1125899906842623 +; CHECK-FP16-NEXT: cmp x8, x9 +; CHECK-FP16-NEXT: csel x0, x8, x9, lo +; CHECK-FP16-NEXT: ret %x = call i50 @llvm.fptoui.sat.i50.f16(half %f) ret i50 %x } Index: llvm/test/CodeGen/AArch64/fptoui-sat-vector.ll =================================================================== --- llvm/test/CodeGen/AArch64/fptoui-sat-vector.ll +++ llvm/test/CodeGen/AArch64/fptoui-sat-vector.ll @@ -814,21 +814,15 @@ ; CHECK: // %bb.0: ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 ; CHECK-NEXT: mov s1, v0.s[1] -; CHECK-NEXT: mov w8, #1484783615 -; CHECK-NEXT: fmov s2, w8 -; CHECK-NEXT: fcvtzu x8, s1 -; CHECK-NEXT: fcmp s1, #0.0 -; CHECK-NEXT: mov x9, #1125899906842623 -; CHECK-NEXT: csel x8, xzr, x8, lt -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: fcvtzu x10, s0 -; CHECK-NEXT: csel x8, x9, x8, gt -; CHECK-NEXT: fcmp s0, #0.0 -; CHECK-NEXT: csel x10, xzr, x10, lt -; CHECK-NEXT: fcmp s0, s2 -; CHECK-NEXT: csel x9, x9, x10, gt -; CHECK-NEXT: fmov d0, x9 -; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: mov x8, #1125899906842623 +; CHECK-NEXT: fcvtzu x10, s1 +; CHECK-NEXT: fcvtzu x9, s0 +; CHECK-NEXT: cmp x10, x8 +; CHECK-NEXT: csel x10, x10, x8, lo +; CHECK-NEXT: cmp x9, x8 +; CHECK-NEXT: csel x8, x9, x8, lo +; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: mov v0.d[1], x10 ; CHECK-NEXT: ret %x = call <2 x i50> @llvm.fptoui.sat.v2f32.v2i50(<2 x float> %f) ret <2 x i50> %x @@ -967,17 +961,15 @@ define <2 x i1> @test_unsigned_v2f64_v2i1(<2 x double> %f) { ; CHECK-LABEL: test_unsigned_v2f64_v2i1: ; CHECK: // %bb.0: -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: fmov d2, #1.00000000 -; CHECK-NEXT: mov d3, v0.d[1] -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmaxnm d1, d3, d1 -; CHECK-NEXT: fminnm d0, d0, d2 +; CHECK-NEXT: mov d1, v0.d[1] +; CHECK-NEXT: fcvtzu w9, d1 ; CHECK-NEXT: fcvtzu w8, d0 -; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: cmp w9, #1 +; CHECK-NEXT: csinc w9, w9, wzr, lo +; CHECK-NEXT: cmp w8, #1 +; CHECK-NEXT: csinc w8, w8, wzr, lo ; CHECK-NEXT: fmov s0, w8 -; CHECK-NEXT: fcvtzu w8, d1 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: mov v0.s[1], w9 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i1> @llvm.fptoui.sat.v2f64.v2i1(<2 x double> %f) @@ -987,19 +979,16 @@ define <2 x i8> @test_unsigned_v2f64_v2i8(<2 x double> %f) { ; CHECK-LABEL: test_unsigned_v2f64_v2i8: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #246290604621824 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16495, lsl #48 -; CHECK-NEXT: mov d2, v0.d[1] -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d3, x8 -; CHECK-NEXT: fmaxnm d1, d2, d1 -; CHECK-NEXT: fminnm d0, d0, d3 -; CHECK-NEXT: fcvtzu w8, d0 -; CHECK-NEXT: fminnm d1, d1, d3 +; CHECK-NEXT: mov d1, v0.d[1] +; CHECK-NEXT: fcvtzu w10, d1 +; CHECK-NEXT: mov w8, #255 +; CHECK-NEXT: fcvtzu w9, d0 +; CHECK-NEXT: cmp w10, #255 +; CHECK-NEXT: csel w10, w10, w8, lo +; CHECK-NEXT: cmp w9, #255 +; CHECK-NEXT: csel w8, w9, w8, lo ; CHECK-NEXT: fmov s0, w8 -; CHECK-NEXT: fcvtzu w8, d1 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: mov v0.s[1], w10 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i8> @llvm.fptoui.sat.v2f64.v2i8(<2 x double> %f) @@ -1009,19 +998,16 @@ define <2 x i13> @test_unsigned_v2f64_v2i13(<2 x double> %f) { ; CHECK-LABEL: test_unsigned_v2f64_v2i13: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #280375465082880 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16575, lsl #48 -; CHECK-NEXT: mov d2, v0.d[1] -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d3, x8 -; CHECK-NEXT: fmaxnm d1, d2, d1 -; CHECK-NEXT: fminnm d0, d0, d3 -; CHECK-NEXT: fcvtzu w8, d0 -; CHECK-NEXT: fminnm d1, d1, d3 +; CHECK-NEXT: mov d1, v0.d[1] +; CHECK-NEXT: mov w8, #8191 +; CHECK-NEXT: fcvtzu w10, d1 +; CHECK-NEXT: fcvtzu w9, d0 +; CHECK-NEXT: cmp w10, w8 +; CHECK-NEXT: csel w10, w10, w8, lo +; CHECK-NEXT: cmp w9, w8 +; CHECK-NEXT: csel w8, w9, w8, lo ; CHECK-NEXT: fmov s0, w8 -; CHECK-NEXT: fcvtzu w8, d1 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: mov v0.s[1], w10 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i13> @llvm.fptoui.sat.v2f64.v2i13(<2 x double> %f) @@ -1031,19 +1017,16 @@ define <2 x i16> @test_unsigned_v2f64_v2i16(<2 x double> %f) { ; CHECK-LABEL: test_unsigned_v2f64_v2i16: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #281337537757184 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16623, lsl #48 -; CHECK-NEXT: mov d2, v0.d[1] -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d3, x8 -; CHECK-NEXT: fmaxnm d1, d2, d1 -; CHECK-NEXT: fminnm d0, d0, d3 -; CHECK-NEXT: fcvtzu w8, d0 -; CHECK-NEXT: fminnm d1, d1, d3 +; CHECK-NEXT: mov d1, v0.d[1] +; CHECK-NEXT: mov w8, #65535 +; CHECK-NEXT: fcvtzu w10, d1 +; CHECK-NEXT: fcvtzu w9, d0 +; CHECK-NEXT: cmp w10, w8 +; CHECK-NEXT: csel w10, w10, w8, lo +; CHECK-NEXT: cmp w9, w8 +; CHECK-NEXT: csel w8, w9, w8, lo ; CHECK-NEXT: fmov s0, w8 -; CHECK-NEXT: fcvtzu w8, d1 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: mov v0.s[1], w10 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i16> @llvm.fptoui.sat.v2f64.v2i16(<2 x double> %f) @@ -1053,19 +1036,16 @@ define <2 x i19> @test_unsigned_v2f64_v2i19(<2 x double> %f) { ; CHECK-LABEL: test_unsigned_v2f64_v2i19: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #281457796841472 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #16671, lsl #48 -; CHECK-NEXT: mov d2, v0.d[1] -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d3, x8 -; CHECK-NEXT: fmaxnm d1, d2, d1 -; CHECK-NEXT: fminnm d0, d0, d3 -; CHECK-NEXT: fcvtzu w8, d0 -; CHECK-NEXT: fminnm d1, d1, d3 +; CHECK-NEXT: mov d1, v0.d[1] +; CHECK-NEXT: mov w8, #524287 +; CHECK-NEXT: fcvtzu w10, d1 +; CHECK-NEXT: fcvtzu w9, d0 +; CHECK-NEXT: cmp w10, w8 +; CHECK-NEXT: csel w10, w10, w8, lo +; CHECK-NEXT: cmp w9, w8 +; CHECK-NEXT: csel w8, w9, w8, lo ; CHECK-NEXT: fmov s0, w8 -; CHECK-NEXT: fcvtzu w8, d1 -; CHECK-NEXT: mov v0.s[1], w8 +; CHECK-NEXT: mov v0.s[1], w10 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0 ; CHECK-NEXT: ret %x = call <2 x i19> @llvm.fptoui.sat.v2f64.v2i19(<2 x double> %f) @@ -1089,19 +1069,16 @@ define <2 x i50> @test_unsigned_v2f64_v2i50(<2 x double> %f) { ; CHECK-LABEL: test_unsigned_v2f64_v2i50: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x8, #-8 -; CHECK-NEXT: movi d1, #0000000000000000 -; CHECK-NEXT: movk x8, #17167, lsl #48 -; CHECK-NEXT: mov d2, v0.d[1] -; CHECK-NEXT: fmaxnm d0, d0, d1 -; CHECK-NEXT: fmov d3, x8 -; CHECK-NEXT: fmaxnm d1, d2, d1 -; CHECK-NEXT: fminnm d0, d0, d3 -; CHECK-NEXT: fcvtzu x8, d0 -; CHECK-NEXT: fminnm d1, d1, d3 +; CHECK-NEXT: mov d1, v0.d[1] +; CHECK-NEXT: mov x8, #1125899906842623 +; CHECK-NEXT: fcvtzu x10, d1 +; CHECK-NEXT: fcvtzu x9, d0 +; CHECK-NEXT: cmp x10, x8 +; CHECK-NEXT: csel x10, x10, x8, lo +; CHECK-NEXT: cmp x9, x8 +; CHECK-NEXT: csel x8, x9, x8, lo ; CHECK-NEXT: fmov d0, x8 -; CHECK-NEXT: fcvtzu x8, d1 -; CHECK-NEXT: mov v0.d[1], x8 +; CHECK-NEXT: mov v0.d[1], x10 ; CHECK-NEXT: ret %x = call <2 x i50> @llvm.fptoui.sat.v2f64.v2i50(<2 x double> %f) ret <2 x i50> %x @@ -1318,32 +1295,25 @@ ; CHECK-FP16-LABEL: test_unsigned_v4f16_v4i19: ; CHECK-FP16: // %bb.0: ; CHECK-FP16-NEXT: // kill: def $d0 killed $d0 def $q0 -; CHECK-FP16-NEXT: fcvt s1, h0 -; CHECK-FP16-NEXT: mov w8, #65504 -; CHECK-FP16-NEXT: mov h3, v0.h[1] -; CHECK-FP16-NEXT: mov h4, v0.h[2] -; CHECK-FP16-NEXT: mov h0, v0.h[3] -; CHECK-FP16-NEXT: movi d2, #0000000000000000 -; CHECK-FP16-NEXT: movk w8, #18687, lsl #16 -; CHECK-FP16-NEXT: fcvt s3, h3 -; CHECK-FP16-NEXT: fcvt s4, h4 -; CHECK-FP16-NEXT: fcvt s0, h0 -; CHECK-FP16-NEXT: fmaxnm s1, s1, s2 -; CHECK-FP16-NEXT: fmaxnm s3, s3, s2 -; CHECK-FP16-NEXT: fmaxnm s4, s4, s2 -; CHECK-FP16-NEXT: fmaxnm s0, s0, s2 -; CHECK-FP16-NEXT: fmov s2, w8 -; CHECK-FP16-NEXT: fminnm s1, s1, s2 -; CHECK-FP16-NEXT: fcvtzu w8, s1 -; CHECK-FP16-NEXT: fminnm s1, s3, s2 -; CHECK-FP16-NEXT: fminnm s3, s4, s2 -; CHECK-FP16-NEXT: fminnm s2, s0, s2 -; CHECK-FP16-NEXT: fmov s0, w8 -; CHECK-FP16-NEXT: fcvtzu w8, s1 -; CHECK-FP16-NEXT: mov v0.s[1], w8 -; CHECK-FP16-NEXT: fcvtzu w8, s3 -; CHECK-FP16-NEXT: mov v0.s[2], w8 -; CHECK-FP16-NEXT: fcvtzu w8, s2 +; CHECK-FP16-NEXT: mov h1, v0.h[1] +; CHECK-FP16-NEXT: mov w8, #524287 +; CHECK-FP16-NEXT: fcvtzu w10, h1 +; CHECK-FP16-NEXT: fcvtzu w9, h0 +; CHECK-FP16-NEXT: cmp w10, w8 +; CHECK-FP16-NEXT: csel w10, w10, w8, lo +; CHECK-FP16-NEXT: cmp w9, w8 +; CHECK-FP16-NEXT: mov h2, v0.h[2] +; CHECK-FP16-NEXT: csel w9, w9, w8, lo +; CHECK-FP16-NEXT: mov h1, v0.h[3] +; CHECK-FP16-NEXT: fmov s0, w9 +; CHECK-FP16-NEXT: fcvtzu w9, h2 +; CHECK-FP16-NEXT: mov v0.s[1], w10 +; CHECK-FP16-NEXT: fcvtzu w10, h1 +; CHECK-FP16-NEXT: cmp w9, w8 +; CHECK-FP16-NEXT: csel w9, w9, w8, lo +; CHECK-FP16-NEXT: cmp w10, w8 +; CHECK-FP16-NEXT: mov v0.s[2], w9 +; CHECK-FP16-NEXT: csel w8, w10, w8, lo ; CHECK-FP16-NEXT: mov v0.s[3], w8 ; CHECK-FP16-NEXT: ret %x = call <4 x i19> @llvm.fptoui.sat.v4f16.v4i19(<4 x half> %f) @@ -1377,40 +1347,51 @@ } define <4 x i50> @test_unsigned_v4f16_v4i50(<4 x half> %f) { -; CHECK-LABEL: test_unsigned_v4f16_v4i50: -; CHECK: // %bb.0: -; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 -; CHECK-NEXT: fcvt s1, h0 -; CHECK-NEXT: mov w8, #1484783615 -; CHECK-NEXT: fcvtzu x10, s1 -; CHECK-NEXT: fcmp s1, #0.0 -; CHECK-NEXT: fmov s2, w8 -; CHECK-NEXT: csel x8, xzr, x10, lt -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: mov h1, v0.h[1] -; CHECK-NEXT: mov x9, #1125899906842623 -; CHECK-NEXT: fcvt s1, h1 -; CHECK-NEXT: fcvtzu x10, s1 -; CHECK-NEXT: csel x0, x9, x8, gt -; CHECK-NEXT: fcmp s1, #0.0 -; CHECK-NEXT: csel x8, xzr, x10, lt -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: mov h1, v0.h[2] -; CHECK-NEXT: fcvt s1, h1 -; CHECK-NEXT: mov h0, v0.h[3] -; CHECK-NEXT: fcvtzu x10, s1 -; CHECK-NEXT: csel x1, x9, x8, gt -; CHECK-NEXT: fcmp s1, #0.0 -; CHECK-NEXT: fcvt s0, h0 -; CHECK-NEXT: csel x8, xzr, x10, lt -; CHECK-NEXT: fcmp s1, s2 -; CHECK-NEXT: fcvtzu x11, s0 -; CHECK-NEXT: csel x2, x9, x8, gt -; CHECK-NEXT: fcmp s0, #0.0 -; CHECK-NEXT: csel x8, xzr, x11, lt -; CHECK-NEXT: fcmp s0, s2 -; CHECK-NEXT: csel x3, x9, x8, gt -; CHECK-NEXT: ret +; CHECK-CVT-LABEL: test_unsigned_v4f16_v4i50: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: fcvt s1, h0 +; CHECK-CVT-NEXT: fcvtzu x9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: fcvt s1, h1 +; CHECK-CVT-NEXT: mov x8, #1125899906842623 +; CHECK-CVT-NEXT: fcvtzu x10, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: fcvt s1, h1 +; CHECK-CVT-NEXT: cmp x9, x8 +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvtzu x11, s1 +; CHECK-CVT-NEXT: csel x0, x9, x8, lo +; CHECK-CVT-NEXT: cmp x10, x8 +; CHECK-CVT-NEXT: fcvtzu x12, s0 +; CHECK-CVT-NEXT: csel x1, x10, x8, lo +; CHECK-CVT-NEXT: cmp x11, x8 +; CHECK-CVT-NEXT: csel x2, x11, x8, lo +; CHECK-CVT-NEXT: cmp x12, x8 +; CHECK-CVT-NEXT: csel x3, x12, x8, lo +; CHECK-CVT-NEXT: ret +; +; CHECK-FP16-LABEL: test_unsigned_v4f16_v4i50: +; CHECK-FP16: // %bb.0: +; CHECK-FP16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-FP16-NEXT: fcvtzu x8, h0 +; CHECK-FP16-NEXT: mov x9, #1125899906842623 +; CHECK-FP16-NEXT: mov h1, v0.h[1] +; CHECK-FP16-NEXT: fcvtzu x10, h1 +; CHECK-FP16-NEXT: mov h1, v0.h[2] +; CHECK-FP16-NEXT: cmp x8, x9 +; CHECK-FP16-NEXT: mov h0, v0.h[3] +; CHECK-FP16-NEXT: fcvtzu x11, h1 +; CHECK-FP16-NEXT: csel x0, x8, x9, lo +; CHECK-FP16-NEXT: cmp x10, x9 +; CHECK-FP16-NEXT: fcvtzu x12, h0 +; CHECK-FP16-NEXT: csel x1, x10, x9, lo +; CHECK-FP16-NEXT: cmp x11, x9 +; CHECK-FP16-NEXT: csel x2, x11, x9, lo +; CHECK-FP16-NEXT: cmp x12, x9 +; CHECK-FP16-NEXT: csel x3, x12, x9, lo +; CHECK-FP16-NEXT: ret %x = call <4 x i50> @llvm.fptoui.sat.v4f16.v4i50(<4 x half> %f) ret <4 x i50> %x }