diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 3332c02ec72358..ede95557b9e745 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -60,7 +60,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { #endif report_fatal_error("Do not know how to soften the result of this " "operator!"); - + case ISD::EXTRACT_ELEMENT: R = SoftenFloatRes_EXTRACT_ELEMENT(N); break; case ISD::ARITH_FENCE: R = SoftenFloatRes_ARITH_FENCE(N); break; case ISD::MERGE_VALUES:R = SoftenFloatRes_MERGE_VALUES(N, ResNo); break; case ISD::BITCAST: R = SoftenFloatRes_BITCAST(N); break; @@ -262,6 +262,15 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N) { } } +SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N) { + SDValue Src = N->getOperand(0); + assert(Src.getValueType() == MVT::ppcf128 && + "In floats only ppcf128 can be extracted by element!"); + return DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(N), + N->getValueType(0).changeTypeToInteger(), + DAG.getBitcast(MVT::i128, Src), N->getOperand(1)); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) { SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0)); return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index e08acd36b41d4e..919c0d4fd2007c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -530,6 +530,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue SoftenFloatRes_BITCAST(SDNode *N); SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N); SDValue SoftenFloatRes_ConstantFP(SDNode *N); + SDValue SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N); SDValue SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo); SDValue SoftenFloatRes_FABS(SDNode *N); SDValue SoftenFloatRes_FMINNUM(SDNode *N); diff --git a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll index dee2701bf6dc11..fcb7ce6db52952 100644 --- a/llvm/test/CodeGen/PowerPC/ppcsoftops.ll +++ b/llvm/test/CodeGen/PowerPC/ppcsoftops.ll @@ -312,8 +312,68 @@ define dso_local zeroext i32 @func(double noundef %0, double noundef %1) #0 { ret i32 %9 } +; To check ppc_fp128 soften without crash +define zeroext i1 @ppcf128_soften(ppc_fp128 %a) #0 { +; PPC-LABEL: ppcf128_soften: +; PPC: # %bb.0: # %entry +; PPC-NEXT: stwu 1, -16(1) +; PPC-NEXT: stw 5, 8(1) # 4-byte Folded Spill +; PPC-NEXT: mr 5, 4 +; PPC-NEXT: lwz 4, 8(1) # 4-byte Folded Reload +; PPC-NEXT: stw 5, 12(1) # 4-byte Folded Spill +; PPC-NEXT: mr 5, 3 +; PPC-NEXT: lwz 3, 12(1) # 4-byte Folded Reload +; PPC-NEXT: # kill: def $r4 killed $r3 +; PPC-NEXT: # kill: def $r4 killed $r5 +; PPC-NEXT: xoris 4, 5, 65520 +; PPC-NEXT: or 4, 3, 4 +; PPC-NEXT: cntlzw 4, 4 +; PPC-NEXT: clrlwi 5, 5, 1 +; PPC-NEXT: or 3, 3, 5 +; PPC-NEXT: cntlzw 3, 3 +; PPC-NEXT: or 3, 3, 4 +; PPC-NEXT: srwi 3, 3, 5 +; PPC-NEXT: addi 1, 1, 16 +; PPC-NEXT: blr +; +; PPC64-LABEL: ppcf128_soften: +; PPC64: # %bb.0: # %entry +; PPC64-NEXT: li 4, 4095 +; PPC64-NEXT: rldic 4, 4, 52, 0 +; PPC64-NEXT: cmpld 7, 3, 4 +; PPC64-NEXT: mfcr 4 # cr7 +; PPC64-NEXT: rlwinm 4, 4, 31, 31, 31 +; PPC64-NEXT: clrldi 3, 3, 1 +; PPC64-NEXT: cmpldi 7, 3, 0 +; PPC64-NEXT: mfcr 3 # cr7 +; PPC64-NEXT: rlwinm 3, 3, 31, 31, 31 +; PPC64-NEXT: or 4, 3, 4 +; PPC64-NEXT: # implicit-def: $x3 +; PPC64-NEXT: mr 3, 4 +; PPC64-NEXT: clrldi 3, 3, 32 +; PPC64-NEXT: blr +; +; PPC64LE-LABEL: ppcf128_soften: +; PPC64LE: # %bb.0: # %entry +; PPC64LE-NEXT: li 3, 4095 +; PPC64LE-NEXT: rldic 3, 3, 52, 0 +; PPC64LE-NEXT: cmpd 4, 3 +; PPC64LE-NEXT: crmove 21, 2 +; PPC64LE-NEXT: clrldi. 3, 4, 1 +; PPC64LE-NEXT: crmove 20, 2 +; PPC64LE-NEXT: cror 20, 20, 21 +; PPC64LE-NEXT: li 4, 0 +; PPC64LE-NEXT: li 3, 1 +; PPC64LE-NEXT: isel 3, 3, 4, 20 +; PPC64LE-NEXT: blr +entry: + %fpclass = tail call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %a, i32 100) + ret i1 %fpclass +} + ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) declare double @llvm.fmuladd.f64(double, double, double) #1 +declare i1 @llvm.is.fpclass.ppcf128(ppc_fp128, i32 immarg) #1 attributes #0 = {"use-soft-float"="true" nounwind } attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }