[llvm] 71eda17 - [Legalizer] Soften EXTRACT_ELEMENT on ppcf128 (#77412)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 8 19:26:27 PDT 2024


Author: Qiu Chaofan
Date: 2024-04-09T10:26:24+08:00
New Revision: 71eda17a0674317b05975be79ed4a2c8ee99c43c

URL: https://github.com/llvm/llvm-project/commit/71eda17a0674317b05975be79ed4a2c8ee99c43c
DIFF: https://github.com/llvm/llvm-project/commit/71eda17a0674317b05975be79ed4a2c8ee99c43c.diff

LOG: [Legalizer] Soften EXTRACT_ELEMENT on ppcf128 (#77412)

ppc_fp128 values are always split into two f64. Implement soften
operation in soft-float mode to handle output f64 correctly.

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/test/CodeGen/PowerPC/ppcsoftops.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index a8b1f41ee40d9a..7685bc73cf9652 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -61,7 +61,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;
@@ -258,6 +258,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) }


        


More information about the llvm-commits mailing list