[llvm] [Legalizer] Soften EXTRACT_ELEMENT on ppcf128 (PR #77412)
Qiu Chaofan via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 5 03:45:45 PDT 2024
https://github.com/ecnelises updated https://github.com/llvm/llvm-project/pull/77412
>From 1bdce09d4e60ac22a0aeeb815f2f8458615d43ab Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Tue, 9 Jan 2024 13:33:56 +0800
Subject: [PATCH 1/3] [Legalizer] Soften EXTRACT_ELEMENT on ppcf128
ppc_fp128 values are always split into two f64. Implement soften
operation in soft-float mode to handle output f64 correctly.
---
.../SelectionDAG/LegalizeFloatTypes.cpp | 13 +++-
llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 +
llvm/test/CodeGen/PowerPC/ppcsoftops.ll | 60 +++++++++++++++++++
3 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 3332c02ec72358..7238e81cd78a45 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -60,7 +60,9 @@ 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 +264,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(),
+ Src.getOperand(0), 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) }
>From 83cf5d1fc09f05892b131ad0917396e813c06998 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Thu, 4 Apr 2024 11:26:33 +0800
Subject: [PATCH 2/3] Use bitcast
---
llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 7238e81cd78a45..bc23c957919ddf 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -270,7 +270,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_ELEMENT(SDNode *N) {
"In floats only ppcf128 can be extracted by element!");
return DAG.getNode(ISD::EXTRACT_ELEMENT, SDLoc(N),
N->getValueType(0).changeTypeToInteger(),
- Src.getOperand(0), N->getOperand(1));
+ DAG.getBitcast(MVT::i128, Src), N->getOperand(1));
}
SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) {
>From caafabc59f8a4f48774837b953e865aed2ec710b Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Fri, 5 Apr 2024 18:45:29 +0800
Subject: [PATCH 3/3] Change formatting
---
llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index bc23c957919ddf..ede95557b9e745 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -60,9 +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::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;
More information about the llvm-commits
mailing list