[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:49:54 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 01/15] 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 02/15] [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 03/15] [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 04/15] [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 05/15] [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 06/15] [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;
   }
 };

>From a20dc8807bec8b65a4cbcfe490dc512c89dc78b4 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 19:58:18 +0530
Subject: [PATCH 07/15] [AArch64][GISel] Add G_POISON to LegalizerInfo

---
 llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index fdedf44e0ba1b..49579a6184e1a 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -92,7 +92,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
   const bool HasSVE = ST.hasSVE();
 
   getActionDefinitionsBuilder(
-      {G_IMPLICIT_DEF, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
+      {G_IMPLICIT_DEF, G_POISON, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
       .legalFor({p0, s8, s16, s32, s64})
       .legalFor({v16s8, v8s16, v4s32, v2s64, v2p0, v8s8, v4s16, v2s32, v4s8,
                  v2s16, v2s8})

>From 4a3a02fbc9141e24e9387a9fcc504e267ab22044 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:01:00 +0530
Subject: [PATCH 08/15] [AArch64][GISel] Extend Instruction Selection to Handle
 G_POISON

Add support for G_POISON in AArch64 instruction selection, treating it similarly
to G_IMPLICIT_DEF. This ensures that poisoned values are correctly recognized
and handled during GlobalISel processing.
---
 .../lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 67a08e39fe879..987ee9f98b62c 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -3594,7 +3594,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
     return selectIntrinsic(I, MRI);
   case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
     return selectIntrinsicWithSideEffects(I, MRI);
-  case TargetOpcode::G_IMPLICIT_DEF: {
+  case TargetOpcode::G_IMPLICIT_DEF:
+  case TargetOpcode::G_POISON:{
     I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
     const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
     const Register DstReg = I.getOperand(0).getReg();
@@ -5861,7 +5862,8 @@ bool AArch64InstructionSelector::tryOptBuildVecToSubregToReg(
   if (EltRB != DstRB)
     return false;
   if (any_of(drop_begin(I.operands(), 2), [&MRI](const MachineOperand &Op) {
-        return !getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, Op.getReg(), MRI);
+        return !getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, Op.getReg(), MRI)  &&
+       !getOpcodeDef(TargetOpcode::G_POISON, Op.getReg(), MRI);
       }))
     return false;
   unsigned SubReg;

>From 8f7c5e25a6f62a4d6194c3511874faae97416de9 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:02:49 +0530
Subject: [PATCH 09/15] [GlobalISel] Add G_POISON Mapping in
 SelectionDAGCompat.td

Extend SelectionDAG compatibility by adding G_POISON alongside G_IMPLICIT_DEF.
This ensures correct handling of poison values in GlobalISel transformations.
---
 llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index c8c0eeb57099a..fb67e7a6b5231 100644
--- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -58,6 +58,7 @@ def : GINodeEquiv<G_CONSTANT, imm>;
 // timm must not be materialized and therefore has no GlobalISel equivalent
 def : GINodeEquiv<G_FCONSTANT, fpimm>;
 def : GINodeEquiv<G_IMPLICIT_DEF, undef>;
+def : GINodeEquiv<G_POISON, undef>;
 def : GINodeEquiv<G_FRAME_INDEX, frameindex>;
 def : GINodeEquiv<G_BLOCK_ADDR, blockaddress>;
 def : GINodeEquiv<G_PTR_ADD, ptradd>;

>From 9c79e1c40550e79b61d8063467118dd3b04ae016 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:04:16 +0530
Subject: [PATCH 10/15] [GlobalISel] Include G_POISON in LostDebugLocObserver

Extend LostDebugLocObserver to track G_POISON, ensuring consistent handling
of poison values in debug location tracking.
---
 llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp b/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp
index 6d606e5550f1a..8c19dd39a4aa8 100644
--- a/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LostDebugLocObserver.cpp
@@ -85,6 +85,7 @@ static bool irTranslatorNeverAddsLocations(unsigned Opcode) {
   case TargetOpcode::G_CONSTANT:
   case TargetOpcode::G_FCONSTANT:
   case TargetOpcode::G_IMPLICIT_DEF:
+  case TargetOpcode::G_POISON:
   case TargetOpcode::G_GLOBAL_VALUE:
     return true;
   }

>From a19c542227f747323c21f7f97c88c107b253c542 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:07:39 +0530
Subject: [PATCH 11/15] [GlobalISel] Add G_POISON support in
 CombinerHelperVectorOps

Extend vector operation legalization to handle G_POISON alongside G_IMPLICIT_DEF.
This ensures poison values are properly considered during vector transformations.
---
 .../CodeGen/GlobalISel/CombinerHelperVectorOps.cpp | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
index 229076bbdeaa5..820b411549c76 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
@@ -84,6 +84,11 @@ bool CombinerHelper::matchExtractVectorElement(MachineInstr &MI,
     MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); };
     return true;
   }
+      isLegalOrBeforeLegalizer({TargetOpcode::G_POISON, {DstTy}})) {
+    // For fixed-length vectors, it's invalid to extract out-of-range elements.
+    MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); };
+    return true;
+  }
 
   return false;
 }
@@ -305,7 +310,10 @@ bool CombinerHelper::matchExtractVectorElementWithShuffleVector(
     MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); };
     return true;
   }
-
+      isLegalOrBeforeLegalizer({TargetOpcode::G_POISON, {DstTy}})) {
+    MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); };
+    return true;
+  }
   // If the legality check failed, then we still have to abort.
   if (SrcIdx < 0)
     return false;
@@ -358,6 +366,10 @@ bool CombinerHelper::matchInsertVectorElementOOB(MachineInstr &MI,
     MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); };
     return true;
   }
+      isLegalOrBeforeLegalizer({TargetOpcode::G_POISON, {DstTy}})) {
+    MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); };
+    return true;
+  }
 
   return false;
 }

>From 3db2f2e5a92c0ed21e2af783f0ceb716b1408093 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:13:56 +0530
Subject: [PATCH 12/15] [GlobalISel] Add test coverage for G_POISON in
 LegalizerHelperTest

Extended test cases to verify G_POISON handling alongside G_IMPLICIT_DEF.
This ensures correctness of legalization behavior for poison values.
---
 .../GlobalISel/LegalizerHelperTest.cpp        | 51 +++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index 22181ce33f0da..c333a2670372e 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -904,6 +904,7 @@ TEST_F(AArch64GISelMITest, WidenUADDE) {
   const char *CheckStr = R"(
   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
   CHECK: [[UADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
@@ -944,6 +945,9 @@ TEST_F(AArch64GISelMITest, WidenUSUBE) {
   const char *CheckStr = R"(
   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_POISON
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
   CHECK: [[USUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
@@ -984,6 +988,7 @@ TEST_F(AArch64GISelMITest, WidenSADDE) {
   const char *CheckStr = R"(
   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
   CHECK: [[SADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
@@ -1024,6 +1029,7 @@ TEST_F(AArch64GISelMITest, WidenSSUBE) {
   const char *CheckStr = R"(
   CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
   CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
   CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
   CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
@@ -1097,7 +1103,9 @@ TEST_F(AArch64GISelMITest, NarrowUADDO) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[UADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
@@ -1134,7 +1142,9 @@ TEST_F(AArch64GISelMITest, NarrowUSUBO) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[USUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
@@ -1171,7 +1181,9 @@ TEST_F(AArch64GISelMITest, NarrowSADDO) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[SADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_
@@ -1208,7 +1220,9 @@ TEST_F(AArch64GISelMITest, NarrowSSUBO) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[SSUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_
@@ -1246,8 +1260,11 @@ TEST_F(AArch64GISelMITest, NarrowUADDE) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[UADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
@@ -1285,8 +1302,11 @@ TEST_F(AArch64GISelMITest, NarrowUSUBE) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[USUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
@@ -1324,8 +1344,11 @@ TEST_F(AArch64GISelMITest, NarrowSADDE) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[SADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
@@ -1363,8 +1386,11 @@ TEST_F(AArch64GISelMITest, NarrowSSUBE) {
 
   const char *CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_POISON
   CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_POISON
   CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]
   CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]
   CHECK: [[SSUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_
@@ -1403,7 +1429,9 @@ TEST_F(AArch64GISelMITest, FewerElementsAnd) {
 
   auto CheckStr = R"(
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_POISON
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_POISON
   CHECK: [[VALUE0:%[0-9]+]]:_(s32), [[VALUE1:%[0-9]+]]:_(s32), [[VALUE2:%[0-9]+]]:_(s32), [[VALUE3:%[0-9]+]]:_(s32), [[VALUE4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]:_(<5 x s32>)
   CHECK: [[VECTOR0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE0]]:_(s32), [[VALUE1]]:_(s32)
   CHECK: [[VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE2]]:_(s32), [[VALUE3]]:_(s32)
@@ -1457,10 +1485,12 @@ TEST_F(AArch64GISelMITest, MoreElementsAnd) {
 
   CHECK: [[BITCAST0_E0:%[0-9]+]]:_(s32), [[BITCAST0_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST0]]:_(<2 x s32>)
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[BITCAST0_LARGE:%[0-9]+]]:_(<6 x s32>) = G_BUILD_VECTOR [[BITCAST0_E0]]:_(s32), [[BITCAST0_E1]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32)
 
   CHECK: [[BITCAST1_E0:%[0-9]+]]:_(s32), [[BITCAST1_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST1]]:_(<2 x s32>)
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[BITCAST1_LARGE:%[0-9]+]]:_(<6 x s32>) = G_BUILD_VECTOR [[BITCAST1_E0]]:_(s32), [[BITCAST1_E1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32)
 
   CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[BITCAST0_LARGE]]:_, [[BITCAST1_LARGE]]:_
@@ -1542,12 +1572,14 @@ TEST_F(AArch64GISelMITest, FewerElementsPhi) {
 
   auto CheckStr = R"(
   CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_POISON
   CHECK: [[INITVAL_E0:%[0-9]+]]:_(s32), [[INITVAL_E1:%[0-9]+]]:_(s32), [[INITVAL_E2:%[0-9]+]]:_(s32), [[INITVAL_E3:%[0-9]+]]:_(s32), [[INITVAL_E4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INITVAL]]:_(<5 x s32>)
   CHECK: [[INITVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E0]]:_(s32), [[INITVAL_E1]]:_(s32)
   CHECK: [[INITVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E2]]:_(s32), [[INITVAL_E3]]:_(s32)
   CHECK: G_BRCOND
 
   CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_POISON
   CHECK: [[MIDVAL_E0:%[0-9]+]]:_(s32), [[MIDVAL_E1:%[0-9]+]]:_(s32), [[MIDVAL_E2:%[0-9]+]]:_(s32), [[MIDVAL_E3:%[0-9]+]]:_(s32), [[MIDVAL_E4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MIDVAL]]:_(<5 x s32>)
   CHECK: [[MIDVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E0]]:_(s32), [[MIDVAL_E1]]:_(s32)
   CHECK: [[MIDVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E2]]:_(s32), [[MIDVAL_E3]]:_(s32)
@@ -1823,6 +1855,7 @@ TEST_F(AArch64GISelMITest, LowerMergeValues) {
   CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
   CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1
   CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
+  CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_POISON
   CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)
   CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)
   CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)
@@ -1838,6 +1871,7 @@ TEST_F(AArch64GISelMITest, LowerMergeValues) {
   CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
   CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
   CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
+  CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_POISON
   CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)
   CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)
   CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)
@@ -3546,6 +3580,7 @@ TEST_F(AArch64GISelMITest, BitcastLoad) {
 
   auto CheckStr = R"(
   CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
+  CHECK: [[PTR:%[0-9]+]]:_(p0) = G_POISON
   CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD
   CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]]
 
@@ -3581,6 +3616,7 @@ TEST_F(AArch64GISelMITest, BitcastStore) {
 
   auto CheckStr = R"(
   CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF
+  CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_POISON
   CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]]
   CHECK: G_STORE [[CAST]]
   )";
@@ -3760,19 +3796,27 @@ TEST_F(AArch64GISelMITest, NarrowImplicitDef) {
 
   const auto *CheckStr = R"(
   CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF
+  CHECK: [[DEF:%[0-9]+]]:_(s48) = G_POISON
   CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]]
 
   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[DEF:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]]
 
   CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF
+  CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_POISON
   CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]]
 
   CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[DEF:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32)
   )";
 
@@ -3904,6 +3948,7 @@ TEST_F(AArch64GISelMITest, NarrowFreeze) {
 
   CHECK: [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]
   CHECK: [[IMP_DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF:%[0-9]+]]:_(s16) = G_POISON
   CHECK: [[BV1:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UV5]]:_(s16), [[UV6]]:_(s16), [[UV7]]:_(s16), [[IMP_DEF]]:_(s16)
   CHECK: [[FREEZE5:%[0-9]+]]:_(<4 x s16>) = G_FREEZE [[BV1]]
   CHECK: [[FREEZE5_E0:%[0-9]+]]:_(s16), [[FREEZE5_E1:%[0-9]+]]:_(s16), [[FREEZE5_E2:%[0-9]+]]:_(s16), [[FREEZE5_E3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FREEZE5]]
@@ -3995,6 +4040,7 @@ TEST_F(AArch64GISelMITest, MoreElementsFreeze) {
   CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]
   CHECK: [[BITCAST_E0:%[0-9]+]]:_(s32), [[BITCAST_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]:_(<2 x s32>)
   CHECK: [[IMP_DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF:%[0-9]+]]:_(s32) = G_POISON
   CHECK: [[BITCAST_LARGE:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[BITCAST_E0]]:_(s32), [[BITCAST_E1]]:_(s32), [[IMP_DEF]]:_(s32), [[IMP_DEF]]:_(s32)
   CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[BITCAST_LARGE]]
   CHECK: [[FREEZE_E0:%[0-9]+]]:_(s32), [[FREEZE_E1:%[0-9]+]]:_(s32), [[FREEZE_E2:%[0-9]+]]:_(s32), [[FREEZE_E3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[FREEZE]]:_(<4 x s32>)
@@ -4069,10 +4115,12 @@ TEST_F(AArch64GISelMITest, FewerElementsInsertVectorElt) {
 
   CHECK: [[UNMERGE1_0:%[0-9]+]]:_(s16), [[UNMERGE1_1:%[0-9]+]]:_(s16), [[UNMERGE1_2:%[0-9]+]]:_(s16), [[UNMERGE1_3:%[0-9]+]]:_(s16), [[UNMERGE1_4:%[0-9]+]]:_(s16), [[UNMERGE1_5:%[0-9]+]]:_(s16), [[UNMERGE1_6:%[0-9]+]]:_(s16), [[UNMERGE1_7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[VEC8]]:_(<8 x s16>)
   CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
+  CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_POISON
   CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16)
   CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16)
   CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16)
   CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF
+  CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_POISON
   CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
   CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]]
 
@@ -4169,10 +4217,12 @@ TEST_F(AArch64GISelMITest, moreElementsShuffle) {
 
   CHECK: [[BV1_E0:%[0-9]+]]:_(s64), [[BV1_E1:%[0-9]+]]:_(s64), [[BV1_E2:%[0-9]+]]:_(s64), [[BV1_E3:%[0-9]+]]:_(s64), [[BV1_E4:%[0-9]+]]:_(s64), [[BV1_E5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[BV1]]:_(<6 x s64>)
   CHECK: [[IMP_DEF0:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(s64) = G_POISON
   CHECK: [[BV1_LARGE:%[0-9]+]]:_(<8 x s64>) = G_BUILD_VECTOR [[BV1_E0]]:_(s64), [[BV1_E1]]:_(s64), [[BV1_E2]]:_(s64), [[BV1_E3]]:_(s64), [[BV1_E4]]:_(s64), [[BV1_E5]]:_(s64), [[IMP_DEF0]]:_(s64), [[IMP_DEF0]]:_(s64)
 
   CHECK: [[BV2_E0:%[0-9]+]]:_(s64), [[BV2_E1:%[0-9]+]]:_(s64), [[BV2_E2:%[0-9]+]]:_(s64), [[BV2_E3:%[0-9]+]]:_(s64), [[BV2_E4:%[0-9]+]]:_(s64), [[BV2_E5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[BV2]]:_(<6 x s64>)
   CHECK: [[IMP_DEF1:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(s64) = G_POISON
   CHECK: [[BV2_LARGE:%[0-9]+]]:_(<8 x s64>) = G_BUILD_VECTOR [[BV2_E0]]:_(s64), [[BV2_E1]]:_(s64), [[BV2_E2]]:_(s64), [[BV2_E3]]:_(s64), [[BV2_E4]]:_(s64), [[BV2_E5]]:_(s64), [[IMP_DEF1]]:_(s64), [[IMP_DEF1]]:_(s64)
 
   CHECK: [[SHUF:%[0-9]+]]:_(<8 x s64>) = G_SHUFFLE_VECTOR [[BV1_LARGE]]:_(<8 x s64>), [[BV2_LARGE]]:_, shufflemask(3, 4, 9, 0, 1, 13, undef, undef)
@@ -4266,6 +4316,7 @@ TEST_F(AArch64GISelMITest, MoreElementsSelect) {
   CHECK: [[ZERO0:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
   CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %{{[0-9]+}}:_(s64), [[ZERO0]]
   CHECK: [[IMPDEF:%[0-9]+]]:_(<2 x s1>) = G_IMPLICIT_DEF
+  CHECK: [[IMPDEF:%[0-9]+]]:_(<2 x s1>) = G_POISON
   CHECK: [[ZERO1:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
   CHECK: [[INSERT:%[0-9]+]]:_(<2 x s1>) = G_INSERT_VECTOR_ELT [[IMPDEF]]:_, [[CMP]]:_(s1), [[ZERO1]]
   CHECK: [[SHUFFLE:%[0-9]+]]:_(<2 x s1>) = G_SHUFFLE_VECTOR [[INSERT]]:_(<2 x s1>), [[IMPDEF]]:_, shufflemask(0, 0)

>From a14cdca7adbb9f752ab03be0a6eec53d256521d1 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:16:06 +0530
Subject: [PATCH 13/15] [RISCV][GlobalISel] Add handling for G_POISON in
 RegisterBankInfo

Extended register bank handling to include G_POISON alongside G_IMPLICIT_DEF.
This improves correctness in instruction selection and register assignment.
---
 llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
index a082b18867666..c7a630c3a1b1f 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVRegisterBankInfo.cpp
@@ -288,7 +288,8 @@ RISCVRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
   case TargetOpcode::G_ZEXTLOAD:
     return getInstructionMapping(DefaultMappingID, /*Cost=*/1, GPRValueMapping,
                                  NumOperands);
-  case TargetOpcode::G_IMPLICIT_DEF: {
+  case TargetOpcode::G_IMPLICIT_DEF: 
+  case TargetOpcode::G_POISON: {
     Register Dst = MI.getOperand(0).getReg();
     LLT DstTy = MRI.getType(Dst);
     unsigned DstMinSize = DstTy.getSizeInBits().getKnownMinValue();

>From 7640facce6a0017faa9195114f34fae85f7f45a9 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:17:21 +0530
Subject: [PATCH 14/15] [AArch64][GlobalISel] Extend G_IMPLICIT_DEF handling to
 include G_POISON

Modified AArch64PostLegalizerLowering to treat G_POISON equivalently to G_IMPLICIT_DEF.
This ensures correct handling of undefined values in instruction legalization.
---
 .../lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 6bba70d45a61d..cf896994e6dce 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -267,8 +267,8 @@ bool matchDupFromInsertVectorElt(int Lane, MachineInstr &MI,
   if (!InsMI)
     return false;
   // Match the undef vector operand.
-  if (!getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, InsMI->getOperand(1).getReg(),
-                    MRI))
+  if (!getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF, InsMI->getOperand(1).getReg(), MRI) &&
+    !getOpcodeDef(TargetOpcode::G_POISON, InsMI->getOperand(1).getReg(), MRI)
     return false;
 
   // Match the index constant 0.

>From bb695bba63217219c0829370b638a703a6f174a4 Mon Sep 17 00:00:00 2001
From: Devesh Yadav <160987201+Devesh-Yadav10 at users.noreply.github.com>
Date: Sat, 15 Mar 2025 20:19:39 +0530
Subject: [PATCH 15/15] [GlobalISel][CSE] Extend tests to include G_POISON
 alongside G_IMPLICIT_DEF

Updated CSETest.cpp to check for G_POISON, ensuring proper handling of undefined values
in GlobalISel's common subexpression elimination.
---
 llvm/unittests/CodeGen/GlobalISel/CSETest.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp b/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
index cd6e32311a9ee..e5c94b129be93 100644
--- a/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
@@ -230,6 +230,8 @@ TEST_F(AArch64GISelMITest, TestCSE) {
   // Check G_IMPLICIT_DEF
   auto Undef0 = CSEB.buildUndef(s32);
   auto Undef1 = CSEB.buildUndef(s32);
+  auto Poison0 = CSEB.buildUndef(s32);
+  auto Poison1 = CSEB.buildUndef(s32);
   EXPECT_EQ(&*Undef0, &*Undef1);
 
   // If the observer is installed to the MF, CSE can also
@@ -294,6 +296,8 @@ TEST_F(AArch64GISelMITest, TestCSEConstantConfig) {
 
   // Check G_IMPLICIT_DEF
   auto Undef0 = CSEB.buildUndef(s16);
+  auto Poison0 = CSEB.buildUndef(s16);
+  auto Poison1 = CSEB.buildUndef(s16);
   auto Undef1 = CSEB.buildUndef(s16);
   EXPECT_EQ(&*Undef0, &*Undef1);
 }



More information about the llvm-commits mailing list