[llvm] SelectionDAG store merging default implementations are unreasonable #90714 (PR #131424)

Devesh Yadav via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 15 07:23:28 PDT 2025


https://github.com/Devesh-Yadav10 updated https://github.com/llvm/llvm-project/pull/131424

>From 452a6e136c601196ba55bca5a512ab85f2ddcf07 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 08:44:11 +0530
Subject: [PATCH 1/6] Updated unconditional true in
 mergeStoresAfterLegalization to checking isOperationLegal(ISD::STORE, MemVT)

---
 llvm/include/llvm/CodeGen/TargetLowering.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index a3fb4e9a8513b..a52dcf68dd243 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -695,7 +695,7 @@ class TargetLoweringBase {
   /// to before legalization. This may transform stores that do not exist
   /// earlier (for example, stores created from intrinsics).
   virtual bool mergeStoresAfterLegalization(EVT MemVT) const {
-    return true;
+    return isOperationLegal(ISD::STORE, MemVT);
   }
 
   /// Returns if it's reasonable to merge stores to MemVT size.

>From 24c8a57695adecbcb2036773f98827dea050c08f Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:27:02 +0530
Subject: [PATCH 2/6] [GlobalISel] Introduce G_POISON to distinguish poison
 from undef

This patch adds G_POISON as a new opcode in GlobalISel to represent poison values separately from G_IMPLICIT_DEF. This distinction is necessary to mirror LLVM IR semantics more accurately and enable better optimizations, particularly when legalization introduces padding vector elements.
---
 llvm/include/llvm/Support/TargetOpcodes.def | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index 5ef3707b81fe9..b9f7c57c91c6b 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -297,6 +297,8 @@ HANDLE_TARGET_OPCODE(G_ABDU)
 
 
 HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF)
+HANDLE_TARGET_OPCODE(G_POISON)
+
 
 /// Generic PHI instruction with types.
 HANDLE_TARGET_OPCODE(G_PHI)

>From f88a6b67976b725f0a41710b843159320d3d4e06 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:36:27 +0530
Subject: [PATCH 3/6] [GlobalISel] Handle G_POISON in isLegalOrBeforeLegalizer

This patch ensures that G_POISON is treated similarly to G_IMPLICIT_DEF in isLegalOrBeforeLegalizer.
This change is necessary to correctly distinguish poison values from undef in GlobalISel.
---
 llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 0dfbb91f2ac54..3b1f40e275ae9 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -328,8 +328,9 @@ bool CombinerHelper::matchCombineConcatVectors(
       for (const MachineOperand &BuildVecMO : Def->uses())
         Ops.push_back(BuildVecMO.getReg());
       break;
-    case TargetOpcode::G_IMPLICIT_DEF: {
-      LLT OpType = MRI.getType(Reg);
+    case TargetOpcode::G_IMPLICIT_DEF:
+    case TargetOpcode::G_POISON: {
+    LLT OpType = MRI.getType(Reg);
       // Keep one undef value for all the undef operands.
       if (!Undef) {
         Builder.setInsertPt(*MI.getParent(), MI);
@@ -353,9 +354,9 @@ bool CombinerHelper::matchCombineConcatVectors(
   // Check if the combine is illegal
   LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
   if (!isLegalOrBeforeLegalizer(
-          {TargetOpcode::G_BUILD_VECTOR, {DstTy, MRI.getType(Ops[0])}})) {
+        {TargetOpcode::G_IMPLICIT_DEF, TargetOpcode::G_POISON, {ConcatSrcTy}}))
     return false;
-  }
+
 
   if (IsUndef)
     Ops.clear();

>From f0a216306359704385997d499352c72c618298ad Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:44:34 +0530
Subject: [PATCH 4/6] [GlobalISel] Add support for G_POISON in MachineIRBuilder

This patch introduces G_POISON as a distinct opcode from G_IMPLICIT_DEF in
MachineIRBuilder, allowing better handling of poison values in GlobalISel.
---
 llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 77a1a70d976d6..f903510fc860f 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -642,6 +642,11 @@ MachineInstrBuilder MachineIRBuilder::buildUndef(const DstOp &Res) {
   return buildInstr(TargetOpcode::G_IMPLICIT_DEF, {Res}, {});
 }
 
+MachineInstrBuilder MachineIRBuilder::buildPoison(const DstOp &Res) {
+    return buildInstr(TargetOpcode::G_POISON, {Res}, {});
+}
+
+
 MachineInstrBuilder MachineIRBuilder::buildMergeValues(const DstOp &Res,
                                                        ArrayRef<Register> Ops) {
   // Unfortunately to convert from ArrayRef<LLT> to ArrayRef<SrcOp>,

>From c0b87be9cf9a8c3d00edc5740ea80179e122a3c7 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:49:18 +0530
Subject: [PATCH 5/6] [X86][GlobalISel] Add support for G_POISON in instruction
 selection

This patch updates the X86 GlobalISel instruction selector to handle G_POISON
alongside G_IMPLICIT_DEF. The changes ensure proper instruction selection and
validation for G_POISON.

- Added case for G_POISON in instruction selection.
- Updated assertions to include G_POISON.
- Ensured all relevant checks now consider G_POISON.
---
 llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index 64a1fa1780a77..c10d56b5788fc 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -428,6 +428,8 @@ bool X86InstructionSelector::select(MachineInstr &I) {
   case TargetOpcode::G_BRCOND:
     return selectCondBranch(I, MRI, MF);
   case TargetOpcode::G_IMPLICIT_DEF:
+  case TargetOpcode::G_POISON:
+
   case TargetOpcode::G_PHI:
     return selectImplicitDefOrPHI(I, MRI);
   case TargetOpcode::G_MUL:
@@ -1588,6 +1590,7 @@ bool X86InstructionSelector::materializeFP(MachineInstr &I,
 bool X86InstructionSelector::selectImplicitDefOrPHI(
     MachineInstr &I, MachineRegisterInfo &MRI) const {
   assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
+          I.getOpcode() == TargetOpcode::G_POISON ||
           I.getOpcode() == TargetOpcode::G_PHI) &&
          "unexpected instruction");
 
@@ -1604,7 +1607,8 @@ bool X86InstructionSelector::selectImplicitDefOrPHI(
     }
   }
 
-  if (I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
+  if (I.getOpcode() == TargetOpcode::G_POISON ||
+    I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
     I.setDesc(TII.get(X86::IMPLICIT_DEF));
   else
     I.setDesc(TII.get(X86::PHI));

>From 9a2d5b96647cc41029cbdb3f6598e4eabd59441f Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:53:17 +0530
Subject: [PATCH 6/6] [GlobalISel] Extend MIPatternMatch to support G_POISON

---
 llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index 72483fbea5805..a2a5dcb5b19f6 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -428,7 +428,9 @@ struct ImplicitDefMatch {
   bool match(const MachineRegisterInfo &MRI, Register Reg) {
     MachineInstr *TmpMI;
     if (mi_match(Reg, MRI, m_MInstr(TmpMI)))
-      return TmpMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
+      return TmpMI->getOpcode() == TargetOpcode::G_POISON ||
+       TmpMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
+
     return false;
   }
 };



More information about the llvm-commits mailing list