diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -504,6 +504,10 @@ /// Constrained floating point add in round-to-zero mode. STRICT_FADDRTZ, + /// Floating-point-to-integer conversion instructions + STRICT_FP_TO_UINT_IN_VSR, + STRICT_FP_TO_SINT_IN_VSR, + // NOTE: The nodes below may require PC-Rel specific patterns if the // address could be PC-Relative. When adding new nodes below, consider // whether or not the address can be PC-Relative and add the corresponding diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1781,6 +1781,10 @@ return "PPCISD::STRICT_FCFIDS"; case PPCISD::STRICT_FCFIDUS: return "PPCISD::STRICT_FCFIDUS"; + case PPCISD::STRICT_FP_TO_UINT_IN_VSR: + return "PPCISD::STRICT_FP_TO_UINT_IN_VSR"; + case PPCISD::STRICT_FP_TO_SINT_IN_VSR: + return "PPCISD::STRICT_FP_TO_SINT_IN_VSR"; case PPCISD::LXVRZX: return "PPCISD::LXVRZX"; case PPCISD::STORE_COND: return "PPCISD::STORE_COND"; @@ -14839,11 +14843,14 @@ SelectionDAG &DAG = DCI.DAG; SDLoc dl(N); unsigned Opcode = N->getOperand(1).getOpcode(); + bool IsStrict = N->getOperand(1)->isStrictFPOpcode(); - assert((Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT) - && "Not a FP_TO_INT Instruction!"); + assert((Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT || + Opcode == ISD::STRICT_FP_TO_SINT || + Opcode == ISD::STRICT_FP_TO_UINT) && + "Not a FP_TO_INT Instruction!"); - SDValue Val = N->getOperand(1).getOperand(0); + SDValue Val = N->getOperand(1).getOperand(IsStrict ? 1 : 0); EVT Op1VT = N->getOperand(1).getValueType(); EVT ResVT = Val.getValueType(); @@ -14869,9 +14876,15 @@ } // Set signed or unsigned conversion opcode. - unsigned ConvOpcode = (Opcode == ISD::FP_TO_SINT) ? - PPCISD::FP_TO_SINT_IN_VSR : - PPCISD::FP_TO_UINT_IN_VSR; + unsigned ConvOpcode = 0; + if (Opcode == ISD::FP_TO_SINT) + ConvOpcode = PPCISD::FP_TO_SINT_IN_VSR; + else if (Opcode == ISD::FP_TO_UINT) + ConvOpcode = PPCISD::FP_TO_UINT_IN_VSR; + else if (Opcode == ISD::STRICT_FP_TO_SINT) + ConvOpcode = PPCISD::STRICT_FP_TO_SINT_IN_VSR; + else if (Opcode == ISD::STRICT_FP_TO_UINT) + ConvOpcode = PPCISD::STRICT_FP_TO_UINT_IN_VSR; Val = DAG.getNode(ConvOpcode, dl, ResVT == MVT::f128 ? MVT::f128 : MVT::f64, Val); @@ -15323,8 +15336,9 @@ EVT Op1VT = N->getOperand(1).getValueType(); unsigned Opcode = N->getOperand(1).getOpcode(); - if (Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT) { - SDValue Val= combineStoreFPToInt(N, DCI); + if (Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT || + Opcode == ISD::STRICT_FP_TO_SINT || Opcode == ISD::STRICT_FP_TO_UINT) { + SDValue Val = combineStoreFPToInt(N, DCI); if (Val) return Val; } diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -30,7 +30,10 @@ ]>; def SDT_PPCcv_fp_to_int : SDTypeProfile<1, 1, [ SDTCisFP<0>, SDTCisFP<1> - ]>; +]>; +def SDT_PPCstrict_cv_fp_to_int : SDTypeProfile<1, 1, [ + SDTCisFP<0>, SDTCisFP<0>, SDTCisFP<1> +]>; def SDT_PPCstore_scal_int_from_vsr : SDTypeProfile<0, 3, [ SDTCisVT<0, f64>, SDTCisPtrTy<1>, SDTCisPtrTy<2> ]>; @@ -168,6 +171,17 @@ SDNode<"PPCISD::FP_TO_UINT_IN_VSR", SDT_PPCcv_fp_to_int, []>; def PPCcv_fp_to_sint_in_vsr: SDNode<"PPCISD::FP_TO_SINT_IN_VSR", SDT_PPCcv_fp_to_int, []>; +def PPCstrict_cv_fp_to_uint_in_vsr: + SDNode<"PPCISD::STRICT_FP_TO_UINT_IN_VSR", SDT_PPCcv_fp_to_int, []>; +def PPCstrict_cv_fp_to_sint_in_vsr: + SDNode<"PPCISD::STRICT_FP_TO_SINT_IN_VSR", SDT_PPCcv_fp_to_int, []>; +def PPCany_cv_fp_to_uint_in_vsr : PatFrags<(ops node:$op), + [(PPCcv_fp_to_uint_in_vsr node:$op), + (PPCstrict_cv_fp_to_uint_in_vsr node:$op)]>; +def PPCany_cv_fp_to_sint_in_vsr : PatFrags<(ops node:$op), + [(PPCcv_fp_to_sint_in_vsr node:$op), + (PPCstrict_cv_fp_to_sint_in_vsr node:$op)]>; + def PPCstore_scal_int_from_vsr: SDNode<"PPCISD::ST_VSR_SCAL_INT", SDT_PPCstore_scal_int_from_vsr, [SDNPHasChain, SDNPMayStore]>; diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -3161,10 +3161,10 @@ // Any pre-Power9 VSX subtarget. let Predicates = [HasVSX, NoP9Vector] in { def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 8), + (f64 (PPCany_cv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 8), (STXSDX (XSCVDPSXDS f64:$src), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 8), + (f64 (PPCany_cv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 8), (STXSDX (XSCVDPUXDS f64:$src), ForceXForm:$dst)>; // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads). @@ -3295,10 +3295,10 @@ // Instructions for converting float to i32 feeding a store. def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 4), + (f64 (PPCany_cv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 4), (STIWX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 4), + (f64 (PPCany_cv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 4), (STIWX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>; def : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)), @@ -4035,64 +4035,64 @@ // Instructions for store(fptosi). // The 8-byte version is repeated here due to availability of D-Form STXSD. def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), XForm:$dst, 8), + (f64 (PPCany_cv_fp_to_sint_in_vsr f128:$src)), XForm:$dst, 8), (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), XForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), DSForm:$dst, 8), + (f64 (PPCany_cv_fp_to_sint_in_vsr f128:$src)), DSForm:$dst, 8), (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), DSForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 4), + (f64 (PPCany_cv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 4), (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 2), + (f64 (PPCany_cv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 2), (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 1), + (f64 (PPCany_cv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 1), (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), XForm:$dst, 8), + (f64 (PPCany_cv_fp_to_sint_in_vsr f64:$src)), XForm:$dst, 8), (STXSDX (XSCVDPSXDS f64:$src), XForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), DSForm:$dst, 8), + (f64 (PPCany_cv_fp_to_sint_in_vsr f64:$src)), DSForm:$dst, 8), (STXSD (XSCVDPSXDS f64:$src), DSForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 2), + (f64 (PPCany_cv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 2), (STXSIHX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 1), + (f64 (PPCany_cv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 1), (STXSIBX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>; // Instructions for store(fptoui). def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), XForm:$dst, 8), + (f64 (PPCany_cv_fp_to_uint_in_vsr f128:$src)), XForm:$dst, 8), (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), XForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), DSForm:$dst, 8), + (f64 (PPCany_cv_fp_to_uint_in_vsr f128:$src)), DSForm:$dst, 8), (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), DSForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 4), + (f64 (PPCany_cv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 4), (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 2), + (f64 (PPCany_cv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 2), (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 1), + (f64 (PPCany_cv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 1), (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), XForm:$dst, 8), + (f64 (PPCany_cv_fp_to_uint_in_vsr f64:$src)), XForm:$dst, 8), (STXSDX (XSCVDPUXDS f64:$src), XForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), DSForm:$dst, 8), + (f64 (PPCany_cv_fp_to_uint_in_vsr f64:$src)), DSForm:$dst, 8), (STXSD (XSCVDPUXDS f64:$src), DSForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 2), + (f64 (PPCany_cv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 2), (STXSIHX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>; def : Pat<(PPCstore_scal_int_from_vsr - (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 1), + (f64 (PPCany_cv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 1), (STXSIBX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>; // Round & Convert QP -> DP/SP diff --git a/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll b/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll --- a/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll +++ b/llvm/test/CodeGen/PowerPC/fp-strict-conv.ll @@ -330,8 +330,7 @@ ; CHECK-LABEL: d_to_i32_store: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: xscvdpsxws f0, f1 -; CHECK-NEXT: mffprwz r3, f0 -; CHECK-NEXT: stw r3, 0(r4) +; CHECK-NEXT: stfiwx f0, 0, r4 ; CHECK-NEXT: blr ; ; NOVSX-LABEL: d_to_i32_store: @@ -349,13 +348,6 @@ } define void @d_to_i64_store(double %m, ptr %addr) #0 { -; CHECK-LABEL: d_to_i64_store: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xscvdpsxds f0, f1 -; CHECK-NEXT: mffprd r3, f0 -; CHECK-NEXT: std r3, 0(r4) -; CHECK-NEXT: blr -; ; NOVSX-LABEL: d_to_i64_store: ; NOVSX: # %bb.0: # %entry ; NOVSX-NEXT: fctidz f0, f1 @@ -370,13 +362,6 @@ } define void @d_to_u64_store(double %m, ptr %addr) #0 { -; CHECK-LABEL: d_to_u64_store: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xscvdpuxds f0, f1 -; CHECK-NEXT: mffprd r3, f0 -; CHECK-NEXT: std r3, 0(r4) -; CHECK-NEXT: blr -; ; NOVSX-LABEL: d_to_u64_store: ; NOVSX: # %bb.0: # %entry ; NOVSX-NEXT: fctiduz f0, f1 @@ -394,8 +379,7 @@ ; CHECK-LABEL: d_to_u32_store: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: xscvdpuxws f0, f1 -; CHECK-NEXT: mffprwz r3, f0 -; CHECK-NEXT: stw r3, 0(r4) +; CHECK-NEXT: stfiwx f0, 0, r4 ; CHECK-NEXT: blr ; ; NOVSX-LABEL: d_to_u32_store: @@ -413,13 +397,6 @@ } define void @f_to_i32_store(float %m, ptr %addr) #0 { -; CHECK-LABEL: f_to_i32_store: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xscvdpsxws f0, f1 -; CHECK-NEXT: mffprwz r3, f0 -; CHECK-NEXT: stw r3, 0(r4) -; CHECK-NEXT: blr -; ; NOVSX-LABEL: f_to_i32_store: ; NOVSX: # %bb.0: # %entry ; NOVSX-NEXT: fctiwz f0, f1 @@ -435,13 +412,6 @@ } define void @f_to_i64_store(float %m, ptr %addr) #0 { -; CHECK-LABEL: f_to_i64_store: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xscvdpsxds f0, f1 -; CHECK-NEXT: mffprd r3, f0 -; CHECK-NEXT: std r3, 0(r4) -; CHECK-NEXT: blr -; ; NOVSX-LABEL: f_to_i64_store: ; NOVSX: # %bb.0: # %entry ; NOVSX-NEXT: fctidz f0, f1 @@ -456,13 +426,6 @@ } define void @f_to_u64_store(float %m, ptr %addr) #0 { -; CHECK-LABEL: f_to_u64_store: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xscvdpuxds f0, f1 -; CHECK-NEXT: mffprd r3, f0 -; CHECK-NEXT: std r3, 0(r4) -; CHECK-NEXT: blr -; ; NOVSX-LABEL: f_to_u64_store: ; NOVSX: # %bb.0: # %entry ; NOVSX-NEXT: fctiduz f0, f1 @@ -477,13 +440,6 @@ } define void @f_to_u32_store(float %m, ptr %addr) #0 { -; CHECK-LABEL: f_to_u32_store: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xscvdpuxws f0, f1 -; CHECK-NEXT: mffprwz r3, f0 -; CHECK-NEXT: stw r3, 0(r4) -; CHECK-NEXT: blr -; ; NOVSX-LABEL: f_to_u32_store: ; NOVSX: # %bb.0: # %entry ; NOVSX-NEXT: fctiwuz f0, f1 @@ -643,11 +599,27 @@ } define void @fptoint_nofpexcept_f64(double %m, ptr %addr1, ptr %addr2) { -; MIR-LABEL: name: fptoint_nofpexcept_f64 -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXWS -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXDS -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXDS +; NOVSX-LABEL: fptoint_nofpexcept_f64: +; NOVSX: # %bb.0: # %entry +; NOVSX-NEXT: fctiwz f0, f1 +; NOVSX-NEXT: fctiwuz f2, f1 +; NOVSX-NEXT: addi r3, r1, -4 +; NOVSX-NEXT: fctidz f3, f1 +; NOVSX-NEXT: fctiduz f1, f1 +; NOVSX-NEXT: stfiwx f0, 0, r3 +; NOVSX-NEXT: addi r3, r1, -8 +; NOVSX-NEXT: lwz r6, -4(r1) +; NOVSX-NEXT: stfiwx f2, 0, r3 +; NOVSX-NEXT: stfd f3, -16(r1) +; NOVSX-NEXT: stfd f1, -24(r1) +; NOVSX-NEXT: lwz r3, -8(r1) +; NOVSX-NEXT: ld r7, -16(r1) +; NOVSX-NEXT: ld r8, -24(r1) +; NOVSX-NEXT: stw r6, 0(r4) +; NOVSX-NEXT: stw r3, 0(r4) +; NOVSX-NEXT: std r7, 0(r5) +; NOVSX-NEXT: std r8, 0(r5) +; NOVSX-NEXT: blr entry: %conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %m, metadata !"fpexcept.ignore") #0 %conv2 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %m, metadata !"fpexcept.ignore") #0 @@ -661,11 +633,27 @@ } define void @fptoint_nofpexcept_f32(float %m, ptr %addr1, ptr %addr2) { -; MIR-LABEL: name: fptoint_nofpexcept_f32 -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXWS -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXWS -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPSXDS -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVDPUXDS +; NOVSX-LABEL: fptoint_nofpexcept_f32: +; NOVSX: # %bb.0: # %entry +; NOVSX-NEXT: fctiwz f0, f1 +; NOVSX-NEXT: fctiwuz f2, f1 +; NOVSX-NEXT: addi r3, r1, -4 +; NOVSX-NEXT: fctidz f3, f1 +; NOVSX-NEXT: fctiduz f1, f1 +; NOVSX-NEXT: stfiwx f0, 0, r3 +; NOVSX-NEXT: addi r3, r1, -8 +; NOVSX-NEXT: lwz r6, -4(r1) +; NOVSX-NEXT: stfiwx f2, 0, r3 +; NOVSX-NEXT: stfd f3, -16(r1) +; NOVSX-NEXT: stfd f1, -24(r1) +; NOVSX-NEXT: lwz r3, -8(r1) +; NOVSX-NEXT: ld r7, -16(r1) +; NOVSX-NEXT: ld r8, -24(r1) +; NOVSX-NEXT: stw r6, 0(r4) +; NOVSX-NEXT: stw r3, 0(r4) +; NOVSX-NEXT: std r7, 0(r5) +; NOVSX-NEXT: std r8, 0(r5) +; NOVSX-NEXT: blr entry: %conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %m, metadata !"fpexcept.ignore") #0 %conv2 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %m, metadata !"fpexcept.ignore") #0 @@ -679,11 +667,29 @@ } define void @inttofp_nofpexcept_i32(i32 %m, ptr %addr1, ptr %addr2) { -; MIR-LABEL: name: inttofp_nofpexcept_i32 -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDSP -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDSP -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDDP -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDDP +; NOVSX-LABEL: inttofp_nofpexcept_i32: +; NOVSX: # %bb.0: # %entry +; NOVSX-NEXT: addi r6, r1, -4 +; NOVSX-NEXT: stw r3, -4(r1) +; NOVSX-NEXT: lfiwax f0, 0, r6 +; NOVSX-NEXT: stw r3, -8(r1) +; NOVSX-NEXT: addi r6, r1, -8 +; NOVSX-NEXT: lfiwzx f1, 0, r6 +; NOVSX-NEXT: stw r3, -12(r1) +; NOVSX-NEXT: addi r6, r1, -12 +; NOVSX-NEXT: lfiwax f2, 0, r6 +; NOVSX-NEXT: stw r3, -16(r1) +; NOVSX-NEXT: addi r3, r1, -16 +; NOVSX-NEXT: lfiwzx f3, 0, r3 +; NOVSX-NEXT: fcfids f0, f0 +; NOVSX-NEXT: fcfidus f1, f1 +; NOVSX-NEXT: fcfid f2, f2 +; NOVSX-NEXT: fcfidu f3, f3 +; NOVSX-NEXT: stfs f0, 0(r4) +; NOVSX-NEXT: stfs f1, 0(r4) +; NOVSX-NEXT: stfd f2, 0(r5) +; NOVSX-NEXT: stfd f3, 0(r5) +; NOVSX-NEXT: blr entry: %conv1 = tail call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 %conv2 = tail call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 @@ -697,11 +703,32 @@ } define void @inttofp_nofpexcept_i64(i64 %m, ptr %addr1, ptr %addr2) { -; MIR-LABEL: name: inttofp_nofpexcept_i64 -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDSP -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDSP -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVSXDDP -; MIR: renamable $f{{[0-9]+}} = nofpexcept XSCVUXDDP +; CHECK-LABEL: inttofp_nofpexcept_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mtfprd f0, r3 +; CHECK-NEXT: xscvsxdsp f1, f0 +; CHECK-NEXT: xscvuxdsp f2, f0 +; CHECK-NEXT: xscvsxddp f3, f0 +; CHECK-NEXT: xscvuxddp f0, f0 +; CHECK-NEXT: stfs f1, 0(r4) +; CHECK-NEXT: stfs f2, 0(r4) +; CHECK-NEXT: stfd f3, 0(r5) +; CHECK-NEXT: stfd f0, 0(r5) +; CHECK-NEXT: blr +; +; NOVSX-LABEL: inttofp_nofpexcept_i64: +; NOVSX: # %bb.0: # %entry +; NOVSX-NEXT: std r3, -8(r1) +; NOVSX-NEXT: lfd f0, -8(r1) +; NOVSX-NEXT: fcfids f1, f0 +; NOVSX-NEXT: fcfidus f2, f0 +; NOVSX-NEXT: fcfid f3, f0 +; NOVSX-NEXT: fcfidu f0, f0 +; NOVSX-NEXT: stfs f1, 0(r4) +; NOVSX-NEXT: stfs f2, 0(r4) +; NOVSX-NEXT: stfd f3, 0(r5) +; NOVSX-NEXT: stfd f0, 0(r5) +; NOVSX-NEXT: blr entry: %conv1 = tail call float @llvm.experimental.constrained.sitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 %conv2 = tail call float @llvm.experimental.constrained.uitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 @@ -715,8 +742,21 @@ } define <2 x double> @inttofp_nofpexcept_vec(<2 x i16> %m) { -; MIR-LABEL: name: inttofp_nofpexcept_vec -; MIR: renamable $v{{[0-9]+}} = nofpexcept XVCVSXDDP +; NOVSX-LABEL: inttofp_nofpexcept_vec: +; NOVSX: # %bb.0: # %entry +; NOVSX-NEXT: addi r3, r1, -32 +; NOVSX-NEXT: addi r4, r1, -4 +; NOVSX-NEXT: stvx v2, 0, r3 +; NOVSX-NEXT: lha r3, -32(r1) +; NOVSX-NEXT: stw r3, -8(r1) +; NOVSX-NEXT: lha r3, -30(r1) +; NOVSX-NEXT: stw r3, -4(r1) +; NOVSX-NEXT: addi r3, r1, -8 +; NOVSX-NEXT: lfiwax f0, 0, r3 +; NOVSX-NEXT: lfiwax f2, 0, r4 +; NOVSX-NEXT: fcfid f1, f0 +; NOVSX-NEXT: fcfid f2, f2 +; NOVSX-NEXT: blr entry: %conv = tail call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i16(<2 x i16> %m, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 ret <2 x double> %conv @@ -725,3 +765,5 @@ declare <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i16(<2 x i16>, metadata, metadata) attributes #0 = { strictfp } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; MIR: {{.*}} diff --git a/llvm/test/CodeGen/PowerPC/nofpexcept.ll b/llvm/test/CodeGen/PowerPC/nofpexcept.ll --- a/llvm/test/CodeGen/PowerPC/nofpexcept.ll +++ b/llvm/test/CodeGen/PowerPC/nofpexcept.ll @@ -75,78 +75,82 @@ ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; CHECK-NEXT: liveins: $f1, $f2, $v2, $x7, $x8 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:g8rc_and_g8rc_nox0 = COPY $x8 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:g8rc_and_g8rc_nox0 = COPY $x7 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vrrc = COPY $v2 - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:f8rc = COPY $f2 - ; CHECK-NEXT: [[COPY4:%[0-9]+]]:f8rc = COPY $f1 - ; CHECK-NEXT: %5:vrrc = nofpexcept XSCVQPSWZ [[COPY2]] - ; CHECK-NEXT: [[COPY5:%[0-9]+]]:vslrc = COPY %5 - ; CHECK-NEXT: [[COPY6:%[0-9]+]]:vfrc = COPY [[COPY5]].sub_64 - ; CHECK-NEXT: [[MFVSRWZ:%[0-9]+]]:gprc = MFVSRWZ killed [[COPY6]] - ; CHECK-NEXT: STW killed [[MFVSRWZ]], 0, [[COPY1]] :: (volatile store (s32) into %ir.addr1) - ; CHECK-NEXT: %8:vrrc = nofpexcept XSCVQPUWZ [[COPY2]] - ; CHECK-NEXT: [[COPY7:%[0-9]+]]:vslrc = COPY %8 - ; CHECK-NEXT: [[COPY8:%[0-9]+]]:vfrc = COPY [[COPY7]].sub_64 - ; CHECK-NEXT: [[MFVSRWZ1:%[0-9]+]]:gprc = MFVSRWZ killed [[COPY8]] - ; CHECK-NEXT: STW killed [[MFVSRWZ1]], 0, [[COPY1]] :: (volatile store (s32) into %ir.addr1) - ; CHECK-NEXT: %11:vrrc = nofpexcept XSCVQPSDZ [[COPY2]] - ; CHECK-NEXT: %12:g8rc = nofpexcept MFVRD killed %11 - ; CHECK-NEXT: STD killed %12, 0, [[COPY]] :: (volatile store (s64) into %ir.addr2) - ; CHECK-NEXT: %13:vrrc = nofpexcept XSCVQPUDZ [[COPY2]] - ; CHECK-NEXT: %14:g8rc = nofpexcept MFVRD killed %13 - ; CHECK-NEXT: STD killed %14, 0, [[COPY]] :: (volatile store (s64) into %ir.addr2) - ; CHECK-NEXT: [[MFFS:%[0-9]+]]:f8rc = MFFS implicit $rm - ; CHECK-NEXT: MTFSB1 31, implicit-def $rm, implicit-def $rm - ; CHECK-NEXT: MTFSB0 30, implicit-def $rm, implicit-def $rm - ; CHECK-NEXT: %15:f8rc = nofpexcept FADD [[COPY3]], [[COPY4]], implicit $rm - ; CHECK-NEXT: MTFSFb 1, [[MFFS]], implicit-def $rm - ; CHECK-NEXT: %16:vsfrc = nofpexcept XSCVDPSXWS killed %15, implicit $rm - ; CHECK-NEXT: [[MFVSRWZ2:%[0-9]+]]:gprc = MFVSRWZ killed %16 - ; CHECK-NEXT: STW killed [[MFVSRWZ2]], 0, [[COPY1]] :: (volatile store (s32) into %ir.addr1) - ; CHECK-NEXT: [[ADDIStocHA8_:%[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0 - ; CHECK-NEXT: [[DFLOADf32_:%[0-9]+]]:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0, killed [[ADDIStocHA8_]] :: (load (s32) from constant-pool) - ; CHECK-NEXT: [[COPY9:%[0-9]+]]:f8rc = COPY [[DFLOADf32_]] - ; CHECK-NEXT: [[FCMPOD:%[0-9]+]]:crrc = FCMPOD [[COPY4]], [[COPY9]] - ; CHECK-NEXT: [[COPY10:%[0-9]+]]:crbitrc = COPY [[FCMPOD]].sub_eq - ; CHECK-NEXT: [[XXLXORdpz:%[0-9]+]]:f8rc = XXLXORdpz - ; CHECK-NEXT: [[FCMPOD1:%[0-9]+]]:crrc = FCMPOD [[COPY3]], [[XXLXORdpz]] - ; CHECK-NEXT: [[COPY11:%[0-9]+]]:crbitrc = COPY [[FCMPOD1]].sub_lt - ; CHECK-NEXT: [[CRAND:%[0-9]+]]:crbitrc = CRAND killed [[COPY10]], killed [[COPY11]] - ; CHECK-NEXT: [[COPY12:%[0-9]+]]:crbitrc = COPY [[FCMPOD]].sub_eq - ; CHECK-NEXT: [[COPY13:%[0-9]+]]:crbitrc = COPY [[FCMPOD]].sub_lt - ; CHECK-NEXT: [[CRANDC:%[0-9]+]]:crbitrc = CRANDC killed [[COPY13]], killed [[COPY12]] - ; CHECK-NEXT: [[CROR:%[0-9]+]]:crbitrc = CROR killed [[CRANDC]], killed [[CRAND]] - ; CHECK-NEXT: [[LIS:%[0-9]+]]:gprc_and_gprc_nor0 = LIS 32768 - ; CHECK-NEXT: [[LI:%[0-9]+]]:gprc_and_gprc_nor0 = LI 0 - ; CHECK-NEXT: [[ISEL:%[0-9]+]]:gprc = ISEL [[LI]], [[LIS]], [[CROR]] - ; CHECK-NEXT: BC [[CROR]], %bb.2 + ; CHECK-NEXT: %4:g8rc_and_g8rc_nox0 = COPY $x8 + ; CHECK-NEXT: %3:g8rc_and_g8rc_nox0 = COPY $x7 + ; CHECK-NEXT: %2:vrrc = COPY $v2 + ; CHECK-NEXT: %1:f8rc = COPY $f2 + ; CHECK-NEXT: %0:f8rc = COPY $f1 + ; CHECK-NEXT: %5:vrrc = nofpexcept XSCVQPSWZ %2 + ; CHECK-NEXT: %43:vslrc = COPY %5 + ; CHECK-NEXT: %6:vfrc = COPY %43.sub_64 + ; CHECK-NEXT: STXSIWX killed %6, $zero8, %3 + ; CHECK-NEXT: %7:vrrc = nofpexcept XSCVQPUWZ %2 + ; CHECK-NEXT: %44:vslrc = COPY %7 + ; CHECK-NEXT: %8:vfrc = COPY %44.sub_64 + ; CHECK-NEXT: STXSIWX killed %8, $zero8, %3 + ; CHECK-NEXT: %9:vrrc = nofpexcept XSCVQPSDZ %2 + ; CHECK-NEXT: %10:g8rc = nofpexcept MFVRD killed %9 + ; CHECK-NEXT: %11:vrrc = XSCVQPSDZ %2 + ; CHECK-NEXT: %45:vslrc = COPY %11 + ; CHECK-NEXT: %12:vfrc = COPY %45.sub_64 + ; CHECK-NEXT: STXSD killed %12, 0, %4 + ; CHECK-NEXT: %13:vrrc = nofpexcept XSCVQPUDZ %2 + ; CHECK-NEXT: %14:g8rc = nofpexcept MFVRD killed %13 + ; CHECK-NEXT: %15:vrrc = XSCVQPUDZ %2 + ; CHECK-NEXT: %46:vslrc = COPY %15 + ; CHECK-NEXT: %16:vfrc = COPY %46.sub_64 + ; CHECK-NEXT: STXSD killed %16, 0, %4 + ; CHECK-NEXT: %47:f8rc = MFFS implicit $rm + ; CHECK-NEXT: MTFSB1 31, implicit-def $rm, implicit-def $rm + ; CHECK-NEXT: MTFSB0 30, implicit-def $rm, implicit-def $rm + ; CHECK-NEXT: %17:f8rc = nofpexcept FADD %1, %0, implicit $rm + ; CHECK-NEXT: MTFSFb 1, %47, implicit-def $rm + ; CHECK-NEXT: %18:vsfrc = nofpexcept XSCVDPSXWS %17, implicit $rm + ; CHECK-NEXT: %19:vsfrc = XSCVDPSXWS %17, implicit $rm + ; CHECK-NEXT: STIWX killed %19, $zero8, %3 + ; CHECK-NEXT: %20:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0 + ; CHECK-NEXT: %21:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0, killed %20 :: (load (s32) from constant-pool) + ; CHECK-NEXT: %22:f8rc = COPY %21 + ; CHECK-NEXT: %23:crrc = FCMPOD %0, %22 + ; CHECK-NEXT: %24:crbitrc = COPY %23.sub_eq + ; CHECK-NEXT: %25:f8rc = XXLXORdpz + ; CHECK-NEXT: %26:crrc = FCMPOD %1, %25 + ; CHECK-NEXT: %27:crbitrc = COPY %26.sub_lt + ; CHECK-NEXT: %28:crbitrc = CRAND killed %24, killed %27 + ; CHECK-NEXT: %29:crbitrc = COPY %23.sub_eq + ; CHECK-NEXT: %30:crbitrc = COPY %23.sub_lt + ; CHECK-NEXT: %31:crbitrc = CRANDC killed %30, killed %29 + ; CHECK-NEXT: %32:crbitrc = CROR killed %31, killed %28 + ; CHECK-NEXT: %33:gprc_and_gprc_nor0 = LIS 32768 + ; CHECK-NEXT: %34:gprc_and_gprc_nor0 = LI 0 + ; CHECK-NEXT: %35:gprc = ISEL %34, %33, %32 + ; CHECK-NEXT: BC %32, %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1.entry: ; CHECK-NEXT: successors: %bb.2(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2.entry: - ; CHECK-NEXT: [[PHI:%[0-9]+]]:f8rc = PHI [[COPY9]], %bb.1, [[XXLXORdpz]], %bb.0 - ; CHECK-NEXT: ADJCALLSTACKDOWN 32, 0, implicit-def dead $r1, implicit $r1 - ; CHECK-NEXT: $f1 = COPY [[COPY4]] - ; CHECK-NEXT: $f2 = COPY [[COPY3]] - ; CHECK-NEXT: $f3 = COPY [[PHI]] - ; CHECK-NEXT: $f4 = COPY [[XXLXORdpz]] - ; CHECK-NEXT: BL8_NOP &__gcc_qsub, csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit $f2, implicit $f3, implicit $f4, implicit $x2, implicit-def $r1, implicit-def $f1, implicit-def $f2 - ; CHECK-NEXT: ADJCALLSTACKUP 32, 0, implicit-def dead $r1, implicit $r1 - ; CHECK-NEXT: [[COPY14:%[0-9]+]]:f8rc = COPY $f1 - ; CHECK-NEXT: [[COPY15:%[0-9]+]]:f8rc = COPY $f2 - ; CHECK-NEXT: [[MFFS1:%[0-9]+]]:f8rc = MFFS implicit $rm - ; CHECK-NEXT: MTFSB1 31, implicit-def $rm, implicit-def $rm - ; CHECK-NEXT: MTFSB0 30, implicit-def $rm, implicit-def $rm - ; CHECK-NEXT: %37:f8rc = nofpexcept FADD [[COPY15]], [[COPY14]], implicit $rm - ; CHECK-NEXT: MTFSFb 1, [[MFFS1]], implicit-def $rm - ; CHECK-NEXT: %38:vsfrc = nofpexcept XSCVDPSXWS killed %37, implicit $rm - ; CHECK-NEXT: [[MFVSRWZ3:%[0-9]+]]:gprc = MFVSRWZ killed %38 - ; CHECK-NEXT: [[XOR:%[0-9]+]]:gprc = XOR killed [[MFVSRWZ3]], killed [[ISEL]] - ; CHECK-NEXT: STW killed [[XOR]], 0, [[COPY1]] :: (volatile store (s32) into %ir.addr1) - ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm + ; CHECK-NEXT: %36:f8rc = PHI %22, %bb.1, %25, %bb.0 + ; CHECK-NEXT: ADJCALLSTACKDOWN 32, 0, implicit-def dead $r1, implicit $r1 + ; CHECK-NEXT: $f1 = COPY %0 + ; CHECK-NEXT: $f2 = COPY %1 + ; CHECK-NEXT: $f3 = COPY %36 + ; CHECK-NEXT: $f4 = COPY %25 + ; CHECK-NEXT: BL8_NOP &__gcc_qsub, csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit $f2, implicit $f3, implicit $f4, implicit $x2, implicit-def $r1, implicit-def $f1, implicit-def $f2 + ; CHECK-NEXT: ADJCALLSTACKUP 32, 0, implicit-def dead $r1, implicit $r1 + ; CHECK-NEXT: %37:f8rc = COPY $f1 + ; CHECK-NEXT: %38:f8rc = COPY $f2 + ; CHECK-NEXT: %48:f8rc = MFFS implicit $rm + ; CHECK-NEXT: MTFSB1 31, implicit-def $rm, implicit-def $rm + ; CHECK-NEXT: MTFSB0 30, implicit-def $rm, implicit-def $rm + ; CHECK-NEXT: %39:f8rc = nofpexcept FADD %38, %37, implicit $rm + ; CHECK-NEXT: MTFSFb 1, %48, implicit-def $rm + ; CHECK-NEXT: %40:vsfrc = nofpexcept XSCVDPSXWS killed %39, implicit $rm + ; CHECK-NEXT: %41:gprc = MFVSRWZ killed %40 + ; CHECK-NEXT: %42:gprc = XOR killed %41, killed %35 + ; CHECK-NEXT: STW killed %42, 0, %3 :: (volatile store (s32) into %ir.addr1) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm entry: %conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128 %m, metadata !"fpexcept.ignore") #0 store volatile i32 %conv1, ptr %addr1, align 4