[llvm] [SDAG] Fix llvm.modf for ppc_fp128 (attempt two) (PR #127976)
Benjamin Maxwell via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 20 04:21:15 PST 2025
https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/127976
>From be65788b0b8440d4a731374f04ee97a94caf9a47 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 20 Feb 2025 09:16:42 +0000
Subject: [PATCH 1/2] [SDAG] Fix llvm.modf for ppc_fp128 (attempt two)
Apparently `DAG.getRoot()` can return null, so we need to check that
case. Hopefully fixes: https://lab.llvm.org/buildbot/#/builders/72/builds/8406
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 +++-
llvm/test/CodeGen/PowerPC/llvm.modf.ll | 22 +++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0a3210a10d394..8fd0de8d2fc44 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2644,8 +2644,10 @@ bool SelectionDAG::expandMultipleResultFPLibCall(
// optimized out. This prevents an FP stack pop from being emitted for it.
// Setting the root like this ensures there will be a use of the
// `CopyFromReg` chain, and ensures the FP pop will be emitted.
+ SDValue OldRoot = getRoot();
SDValue NewRoot =
- getNode(ISD::TokenFactor, DL, MVT::Other, getRoot(), CallChain);
+ OldRoot ? getNode(ISD::TokenFactor, DL, MVT::Other, OldRoot, CallChain)
+ : CallChain;
setRoot(NewRoot);
// Ensure the new root is reachable from the results.
Results[0] = getMergeValues({Results[0], NewRoot}, DL);
diff --git a/llvm/test/CodeGen/PowerPC/llvm.modf.ll b/llvm/test/CodeGen/PowerPC/llvm.modf.ll
index 69e3b22c7352c..a3f8a9907a46a 100644
--- a/llvm/test/CodeGen/PowerPC/llvm.modf.ll
+++ b/llvm/test/CodeGen/PowerPC/llvm.modf.ll
@@ -328,3 +328,25 @@ define { ppc_fp128, ppc_fp128 } @test_modf_ppcf128(ppc_fp128 %a) {
%result = call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %a)
ret { ppc_fp128, ppc_fp128 } %result
}
+
+define ppc_fp128 @test_modf_ppcf128_only_use_intergral(ppc_fp128 %a) {
+; CHECK-LABEL: test_modf_ppcf128_only_use_intergral:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mflr r0
+; CHECK-NEXT: stdu r1, -48(r1)
+; CHECK-NEXT: std r0, 64(r1)
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: addi r5, r1, 32
+; CHECK-NEXT: bl modfl
+; CHECK-NEXT: nop
+; CHECK-NEXT: lfd f1, 32(r1)
+; CHECK-NEXT: lfd f2, 40(r1)
+; CHECK-NEXT: addi r1, r1, 48
+; CHECK-NEXT: ld r0, 16(r1)
+; CHECK-NEXT: mtlr r0
+; CHECK-NEXT: blr
+ %result = call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %a)
+ %result.1 = extractvalue { ppc_fp128, ppc_fp128 } %result, 1
+ ret ppc_fp128 %result.1
+}
>From ae1d93f2e51fd76b0eb20b2bb4a2a810180b639c Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Thu, 20 Feb 2025 12:19:46 +0000
Subject: [PATCH 2/2] Fixups
---
.../CodeGen/SelectionDAG/LegalizeTypes.cpp | 17 +++-
llvm/test/CodeGen/PowerPC/llvm.modf.ll | 83 +++++++++++++++++++
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index b6abad830c371..3a2d69d8a8eca 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -435,8 +435,21 @@ bool DAGTypeLegalizer::run() {
#endif
PerformExpensiveChecks();
- // If the root changed (e.g. it was a dead load) update the root.
- DAG.setRoot(Dummy.getValue());
+ // Get the value of the original root after type legalization.
+ SDValue Root = Dummy.getValue();
+
+ // Get the current root value, if it's not null combine it with the original
+ // root to prevent it being removed as a dead node.
+ if (SDValue LegalRoot = DAG.getRoot()) {
+ Root = DAG.getNode(ISD::TokenFactor, SDLoc(LegalRoot), MVT::Other, Root,
+ LegalRoot);
+ // The token_factor should not need any legalization (as both inputs have
+ // already been legalized).
+ Root->setNodeId(Processed);
+ }
+
+ // Restore the root.
+ DAG.setRoot(Root);
// Remove dead nodes. This is important to do for cleanliness but also before
// the checking loop below. Implicit folding by the DAG.getNode operators and
diff --git a/llvm/test/CodeGen/PowerPC/llvm.modf.ll b/llvm/test/CodeGen/PowerPC/llvm.modf.ll
index a3f8a9907a46a..1b137c786cc91 100644
--- a/llvm/test/CodeGen/PowerPC/llvm.modf.ll
+++ b/llvm/test/CodeGen/PowerPC/llvm.modf.ll
@@ -350,3 +350,86 @@ define ppc_fp128 @test_modf_ppcf128_only_use_intergral(ppc_fp128 %a) {
%result.1 = extractvalue { ppc_fp128, ppc_fp128 } %result, 1
ret ppc_fp128 %result.1
}
+
+define ppc_fp128 @test_modf_ppcf128_only_use_fractional(ppc_fp128 %a) {
+; CHECK-LABEL: test_modf_ppcf128_only_use_fractional:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mflr r0
+; CHECK-NEXT: stdu r1, -48(r1)
+; CHECK-NEXT: std r0, 64(r1)
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: addi r5, r1, 32
+; CHECK-NEXT: bl modfl
+; CHECK-NEXT: nop
+; CHECK-NEXT: addi r1, r1, 48
+; CHECK-NEXT: ld r0, 16(r1)
+; CHECK-NEXT: mtlr r0
+; CHECK-NEXT: blr
+ %result = call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %a)
+ %result.1 = extractvalue { ppc_fp128, ppc_fp128 } %result, 0
+ ret ppc_fp128 %result.1
+}
+
+define { ppc_fp128, ppc_fp128 } @test_modf_ppcf128_tail_call(ppc_fp128 %a) {
+; CHECK-LABEL: test_modf_ppcf128_tail_call:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mflr r0
+; CHECK-NEXT: stdu r1, -48(r1)
+; CHECK-NEXT: std r0, 64(r1)
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: addi r5, r1, 32
+; CHECK-NEXT: bl modfl
+; CHECK-NEXT: nop
+; CHECK-NEXT: lfd f3, 32(r1)
+; CHECK-NEXT: lfd f4, 40(r1)
+; CHECK-NEXT: addi r1, r1, 48
+; CHECK-NEXT: ld r0, 16(r1)
+; CHECK-NEXT: mtlr r0
+; CHECK-NEXT: blr
+ %result = tail call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %a)
+ ret { ppc_fp128, ppc_fp128 } %result
+}
+
+define ppc_fp128 @test_modf_ppcf128_only_use_intergral_tail_call(ppc_fp128 %a) {
+; CHECK-LABEL: test_modf_ppcf128_only_use_intergral_tail_call:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mflr r0
+; CHECK-NEXT: stdu r1, -48(r1)
+; CHECK-NEXT: std r0, 64(r1)
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: addi r5, r1, 32
+; CHECK-NEXT: bl modfl
+; CHECK-NEXT: nop
+; CHECK-NEXT: lfd f1, 32(r1)
+; CHECK-NEXT: lfd f2, 40(r1)
+; CHECK-NEXT: addi r1, r1, 48
+; CHECK-NEXT: ld r0, 16(r1)
+; CHECK-NEXT: mtlr r0
+; CHECK-NEXT: blr
+ %result = tail call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %a)
+ %result.1 = extractvalue { ppc_fp128, ppc_fp128 } %result, 1
+ ret ppc_fp128 %result.1
+}
+
+define ppc_fp128 @test_modf_ppcf128_only_use_fractional_tail_call(ppc_fp128 %a) {
+; CHECK-LABEL: test_modf_ppcf128_only_use_fractional_tail_call:
+; CHECK: # %bb.0:
+; CHECK-NEXT: mflr r0
+; CHECK-NEXT: stdu r1, -48(r1)
+; CHECK-NEXT: std r0, 64(r1)
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: addi r5, r1, 32
+; CHECK-NEXT: bl modfl
+; CHECK-NEXT: nop
+; CHECK-NEXT: addi r1, r1, 48
+; CHECK-NEXT: ld r0, 16(r1)
+; CHECK-NEXT: mtlr r0
+; CHECK-NEXT: blr
+ %result = tail call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %a)
+ %result.1 = extractvalue { ppc_fp128, ppc_fp128 } %result, 0
+ ret ppc_fp128 %result.1
+}
More information about the llvm-commits
mailing list