[llvm] [DAGTypeLegalize] Legalize ISD::POISON as ISD::UNDEF for Float Type Legalization (PR #135056)

zhijian lin via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 10 06:58:33 PDT 2025


https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/135056

>From 2d9bdc654a99b68c69879d3cec4137a9c4e0716c Mon Sep 17 00:00:00 2001
From: zhijian lin <zhijian at ca.ibm.com>
Date: Mon, 7 Apr 2025 10:03:05 -0400
Subject: [PATCH 1/2] [SelectionDAG] Introducing a new ISD::POISON SDNode to
 represent the poison value in the IR. (#125883)

A new ISD::POISON SDNode is introduced to represent the `poison value`
in the IR, replacing the previous use of ISD::UNDEF.
---
 llvm/include/llvm/CodeGen/ISDOpcodes.h        |  3 ++
 llvm/include/llvm/CodeGen/SelectionDAG.h      |  3 ++
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h |  6 ++-
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  3 +-
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 14 +++++++
 .../SelectionDAG/LegalizeFloatTypes.cpp       |  1 +
 .../SelectionDAG/LegalizeIntegerTypes.cpp     |  2 +
 .../SelectionDAG/LegalizeVectorTypes.cpp      |  3 ++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  3 ++
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  2 +-
 .../SelectionDAG/SelectionDAGDumper.cpp       |  1 +
 .../CodeGen/SelectionDAG/SelectionDAGISel.cpp |  1 +
 .../AArch64/vector-insert-dag-combines.ll     | 38 +++++++++----------
 llvm/test/CodeGen/X86/half.ll                 | 24 ++++++------
 llvm/test/CodeGen/X86/pr119158.ll             |  7 ++--
 15 files changed, 73 insertions(+), 38 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 59f31f8443947..ad8a95a353b56 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -217,6 +217,9 @@ enum NodeType {
   /// UNDEF - An undefined node.
   UNDEF,
 
+  /// POISON - A poison node.
+  POISON,
+
   /// FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or
   /// is evaluated to UNDEF), or returns VAL otherwise. Note that each
   /// read of UNDEF can yield different value, but FREEZE(UNDEF) cannot.
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index d06e2b19fa0b5..63423463eeee2 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -1130,6 +1130,9 @@ class SelectionDAG {
     return getNode(ISD::UNDEF, SDLoc(), VT);
   }
 
+  /// Return a POISON node. POISON does not have a useful SDLoc.
+  SDValue getPOISON(EVT VT) { return getNode(ISD::POISON, SDLoc(), VT); }
+
   /// Return a node that represents the runtime scaling 'MulImm * RuntimeVL'.
   SDValue getVScale(const SDLoc &DL, EVT VT, APInt MulImm,
                     bool ConstantFold = true);
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 2283f99202e2f..b62cf08693f63 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -692,8 +692,10 @@ END_TWO_BYTE_PACK()
   /// \<target\>ISD namespace).
   bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
 
-  /// Return true if the type of the node type undefined.
-  bool isUndef() const { return NodeType == ISD::UNDEF; }
+  /// Returns true if the node type is UNDEF or POISON.
+  bool isUndef() const {
+    return NodeType == ISD::UNDEF || NodeType == ISD::POISON;
+  }
 
   /// Test if this node is a memory intrinsic (with valid pointer information).
   bool isMemIntrinsic() const { return SDNodeBits.IsMemIntrinsic; }
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 9a28caa758659..967284944c658 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16304,7 +16304,8 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
   // Finally, recreate the node, it's operands were updated to use
   // frozen operands, so we just need to use it's "original" operands.
   SmallVector<SDValue> Ops(N0->ops());
-  // Special-handle ISD::UNDEF, each single one of them can be it's own thing.
+  // TODO: ISD::UNDEF and ISD::POISON should get separate handling, but best
+  // leave for a future patch.
   for (SDValue &Op : Ops) {
     if (Op.isUndef())
       Op = DAG.getFreeze(Op);
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 754c29b6ba868..b8af281e1c24b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -986,6 +986,19 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
   TargetLowering::LegalizeAction Action = TargetLowering::Legal;
   bool SimpleFinishLegalizing = true;
   switch (Node->getOpcode()) {
+  // TODO: Currently, POISON is being lowered to UNDEF here. However, there is
+  // an open concern that this transformation may not be ideal, as targets
+  // should ideally handle POISON directly. Changing this behavior would require
+  // adding support for POISON in TableGen, which is a large change.
+  // Additionally, many existing test cases rely on the current behavior (e.g.,
+  // llvm/test/CodeGen/PowerPC/vec_shuffle.ll). A broader discussion and
+  // incremental changes might be needed to properly
+  // support POISON without breaking existing targets and tests.
+  case ISD::POISON: {
+    SDValue UndefNode = DAG.getUNDEF(Node->getValueType(0));
+    ReplaceNode(Node, UndefNode.getNode());
+    break;
+  }
   case ISD::INTRINSIC_W_CHAIN:
   case ISD::INTRINSIC_WO_CHAIN:
   case ISD::INTRINSIC_VOID:
@@ -3169,6 +3182,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
     for (unsigned i = 0; i < Node->getNumValues(); i++)
       Results.push_back(Node->getOperand(i));
     break;
+  case ISD::POISON:
   case ISD::UNDEF: {
     EVT VT = Node->getValueType(0);
     if (VT.isInteger())
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 01751dfe9eb62..5ed83060e150e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -2845,6 +2845,7 @@ void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
 
     case ISD::SINT_TO_FP:
     case ISD::UINT_TO_FP: R = PromoteFloatRes_XINT_TO_FP(N); break;
+    case ISD::POISON:
     case ISD::UNDEF:      R = PromoteFloatRes_UNDEF(N); break;
     case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
     case ISD::VECREDUCE_FADD:
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index d4b7283d0b0bd..4685330c5aa14 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -118,6 +118,7 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::VP_SRL:      Res = PromoteIntRes_SRL(N); break;
   case ISD::VP_TRUNCATE:
   case ISD::TRUNCATE:    Res = PromoteIntRes_TRUNCATE(N); break;
+  case ISD::POISON:
   case ISD::UNDEF:       Res = PromoteIntRes_UNDEF(N); break;
   case ISD::VAARG:       Res = PromoteIntRes_VAARG(N); break;
   case ISD::VSCALE:      Res = PromoteIntRes_VSCALE(N); break;
@@ -2914,6 +2915,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
   case ISD::SELECT:       SplitRes_Select(N, Lo, Hi); break;
   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
+  case ISD::POISON:
   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
   case ISD::FREEZE:       SplitRes_FREEZE(N, Lo, Hi); break;
   case ISD::SETCC:        ExpandIntRes_SETCC(N, Lo, Hi); break;
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 9d42ec2fdf859..f934d8b37561e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -71,6 +71,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::SELECT:            R = ScalarizeVecRes_SELECT(N); break;
   case ISD::SELECT_CC:         R = ScalarizeVecRes_SELECT_CC(N); break;
   case ISD::SETCC:             R = ScalarizeVecRes_SETCC(N); break;
+  case ISD::POISON:
   case ISD::UNDEF:             R = ScalarizeVecRes_UNDEF(N); break;
   case ISD::VECTOR_SHUFFLE:    R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break;
   case ISD::IS_FPCLASS:        R = ScalarizeVecRes_IS_FPCLASS(N); break;
@@ -1137,6 +1138,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::VP_MERGE:
   case ISD::VP_SELECT:    SplitRes_Select(N, Lo, Hi); break;
   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
+  case ISD::POISON:
   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
   case ISD::BITCAST:           SplitVecRes_BITCAST(N, Lo, Hi); break;
   case ISD::BUILD_VECTOR:      SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break;
@@ -4592,6 +4594,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::SELECT_CC:         Res = WidenVecRes_SELECT_CC(N); break;
   case ISD::VP_SETCC:
   case ISD::SETCC:             Res = WidenVecRes_SETCC(N); break;
+  case ISD::POISON:
   case ISD::UNDEF:             Res = WidenVecRes_UNDEF(N); break;
   case ISD::VECTOR_SHUFFLE:
     Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N));
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index f2777bbf247b0..d6dcb3f15ae7c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5387,6 +5387,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
   case ISD::CopyFromReg:
     return true;
 
+  case ISD::POISON:
+    return false;
+
   case ISD::UNDEF:
     return PoisonOnly;
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 89793c30f3710..8cae34d06c8ba 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1817,7 +1817,7 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
       return DAG.getConstantFP(*CFP, getCurSDLoc(), VT);
 
     if (isa<UndefValue>(C) && !V->getType()->isAggregateType())
-      return DAG.getUNDEF(VT);
+      return isa<PoisonValue>(C) ? DAG.getPOISON(VT) : DAG.getUNDEF(VT);
 
     if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
       visit(CE->getOpcode(), *CE);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 958c070ed50de..8fcec6c6cd7c6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -189,6 +189,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
   case ISD::CopyToReg:                  return "CopyToReg";
   case ISD::CopyFromReg:                return "CopyFromReg";
   case ISD::UNDEF:                      return "undef";
+  case ISD::POISON:                     return "poison";
   case ISD::VSCALE:                     return "vscale";
   case ISD::MERGE_VALUES:               return "merge_values";
   case ISD::INLINEASM:                  return "inlineasm";
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 7e3f8a9dbff9e..083b984444bcb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3279,6 +3279,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
   case ISD::WRITE_REGISTER:
     Select_WRITE_REGISTER(NodeToMatch);
     return;
+  case ISD::POISON:
   case ISD::UNDEF:
     Select_UNDEF(NodeToMatch);
     return;
diff --git a/llvm/test/CodeGen/AArch64/vector-insert-dag-combines.ll b/llvm/test/CodeGen/AArch64/vector-insert-dag-combines.ll
index 0e05a63ef86de..5207d5cbf21a2 100644
--- a/llvm/test/CodeGen/AArch64/vector-insert-dag-combines.ll
+++ b/llvm/test/CodeGen/AArch64/vector-insert-dag-combines.ll
@@ -12,7 +12,7 @@ target triple = "aarch64-unknown-linux-gnu"
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %0
 ; CHECK:       t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:     t6: v16i8 = insert_subvector undef:v16i8, t4, Constant:i64<0>
+; CHECK:     t6: v16i8 = insert_subvector poison:v16i8, t4, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:v16i8 $q0, t6
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:v16i8 $q0, t8:1
 
@@ -20,7 +20,7 @@ target triple = "aarch64-unknown-linux-gnu"
 ; CHECK: SelectionDAG has 9 nodes:
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:       t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %0
-; CHECK:     t10: v16i8 = insert_subvector undef:v16i8, t2, Constant:i64<0>
+; CHECK:     t10: v16i8 = insert_subvector poison:v16i8, t2, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:v16i8 $q0, t10
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:v16i8 $q0, t8:1
 
@@ -35,7 +35,7 @@ define <16 x i8> @insert_small_fixed_into_big_fixed(<8 x i8> %a) #0 {
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %0
 ; CHECK:       t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:     t6: nxv16i8 = insert_subvector undef:nxv16i8, t4, Constant:i64<0>
+; CHECK:     t6: nxv16i8 = insert_subvector poison:nxv16i8, t4, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t6
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:1
 
@@ -43,7 +43,7 @@ define <16 x i8> @insert_small_fixed_into_big_fixed(<8 x i8> %a) #0 {
 ; CHECK: SelectionDAG has 9 nodes:
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:       t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %0
-; CHECK:     t10: nxv16i8 = insert_subvector undef:nxv16i8, t2, Constant:i64<0>
+; CHECK:     t10: nxv16i8 = insert_subvector poison:nxv16i8, t2, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t10
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:1
 
@@ -59,7 +59,7 @@ define <vscale x 16 x i8> @insert_small_fixed_into_big_scalable(<8 x i8> %a) #0
 ; CHECK:           t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0
 ; CHECK:         t3: nxv8i8 = truncate t2
 ; CHECK:       t5: v4i8 = extract_subvector t3, Constant:i64<0>
-; CHECK:     t7: v16i8 = insert_subvector undef:v16i8, t5, Constant:i64<0>
+; CHECK:     t7: v16i8 = insert_subvector poison:v16i8, t5, Constant:i64<0>
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:v16i8 $q0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:v16i8 $q0, t9:1
 
@@ -69,7 +69,7 @@ define <vscale x 16 x i8> @insert_small_fixed_into_big_scalable(<8 x i8> %a) #0
 ; CHECK:           t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0
 ; CHECK:         t3: nxv8i8 = truncate t2
 ; CHECK:       t5: v4i8 = extract_subvector t3, Constant:i64<0>
-; CHECK:     t7: v16i8 = insert_subvector undef:v16i8, t5, Constant:i64<0>
+; CHECK:     t7: v16i8 = insert_subvector poison:v16i8, t5, Constant:i64<0>
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:v16i8 $q0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:v16i8 $q0, t9:1
 
@@ -86,7 +86,7 @@ define <16 x i8> @insert_small_scalable_into_big_fixed(<vscale x 8 x i8> %a) #0
 ; CHECK:           t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0
 ; CHECK:         t3: nxv8i8 = truncate t2
 ; CHECK:       t5: v4i8 = extract_subvector t3, Constant:i64<0>
-; CHECK:     t7: nxv16i8 = insert_subvector undef:nxv16i8, t5, Constant:i64<0>
+; CHECK:     t7: nxv16i8 = insert_subvector poison:nxv16i8, t5, Constant:i64<0>
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:1
 
@@ -95,7 +95,7 @@ define <16 x i8> @insert_small_scalable_into_big_fixed(<vscale x 8 x i8> %a) #0
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0
 ; CHECK:       t3: nxv8i8 = truncate t2
-; CHECK:     t11: nxv16i8 = insert_subvector undef:nxv16i8, t3, Constant:i64<0>
+; CHECK:     t11: nxv16i8 = insert_subvector poison:nxv16i8, t3, Constant:i64<0>
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t11
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:1
 
@@ -111,7 +111,7 @@ define <vscale x 16 x i8> @insert_small_scalable_into_big_scalable_1(<vscale x 8
 ; CHECK:           t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0
 ; CHECK:         t3: nxv8i8 = truncate t2
 ; CHECK:       t5: nxv4i8 = extract_subvector t3, Constant:i64<0>
-; CHECK:     t7: nxv16i8 = insert_subvector undef:nxv16i8, t5, Constant:i64<0>
+; CHECK:     t7: nxv16i8 = insert_subvector poison:nxv16i8, t5, Constant:i64<0>
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:1
 
@@ -120,7 +120,7 @@ define <vscale x 16 x i8> @insert_small_scalable_into_big_scalable_1(<vscale x 8
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0
 ; CHECK:       t3: nxv8i8 = truncate t2
-; CHECK:     t11: nxv16i8 = insert_subvector undef:nxv16i8, t3, Constant:i64<0>
+; CHECK:     t11: nxv16i8 = insert_subvector poison:nxv16i8, t3, Constant:i64<0>
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t11
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:1
 
@@ -135,7 +135,7 @@ define <vscale x 16 x i8> @insert_small_scalable_into_big_scalable_2(<vscale x 8
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0
 ; CHECK:       t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:     t6: v8i8 = insert_subvector undef:v8i8, t4, Constant:i64<0>
+; CHECK:     t6: v8i8 = insert_subvector poison:v8i8, t4, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:v8i8 $d0, t6
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:v8i8 $d0, t8:1
 
@@ -158,7 +158,7 @@ define <8 x i8> @extract_small_fixed_from_big_fixed(<16 x i8> %a) #0 {
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:           t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0
 ; CHECK:         t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:       t6: nxv8i8 = insert_subvector undef:nxv8i8, t4, Constant:i64<0>
+; CHECK:       t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>
 ; CHECK:     t7: nxv8i16 = any_extend t6
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1
@@ -168,7 +168,7 @@ define <8 x i8> @extract_small_fixed_from_big_fixed(<16 x i8> %a) #0 {
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:           t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0
 ; CHECK:         t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:       t6: nxv8i8 = insert_subvector undef:nxv8i8, t4, Constant:i64<0>
+; CHECK:       t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>
 ; CHECK:     t7: nxv8i16 = any_extend t6
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1
@@ -185,7 +185,7 @@ define <vscale x 8 x i8> @extract_small_scalable_from_big_fixed(<16 x i8> %a) #0
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0
 ; CHECK:       t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:     t6: v8i8 = insert_subvector undef:v8i8, t4, Constant:i64<0>
+; CHECK:     t6: v8i8 = insert_subvector poison:v8i8, t4, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:v8i8 $d0, t6
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:v8i8 $d0, t8:1
 
@@ -208,7 +208,7 @@ define <8 x i8> @extract_small_fixed_from_big_scalable(<vscale x 16 x i8> %a) #0
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:           t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0
 ; CHECK:         t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:       t6: nxv8i8 = insert_subvector undef:nxv8i8, t4, Constant:i64<0>
+; CHECK:       t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>
 ; CHECK:     t7: nxv8i16 = any_extend t6
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1
@@ -233,7 +233,7 @@ define <vscale x 8 x i8> @extract_small_scalable_from_big_scalable_1(<vscale x 1
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:           t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0
 ; CHECK:         t4: nxv4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:       t6: nxv8i8 = insert_subvector undef:nxv8i8, t4, Constant:i64<0>
+; CHECK:       t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>
 ; CHECK:     t7: nxv8i16 = any_extend t6
 ; CHECK:   t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7
 ; CHECK:   t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1
@@ -258,7 +258,7 @@ define <vscale x 8 x i8> @extract_small_scalable_from_big_scalable_2(<vscale x 1
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0
 ; CHECK:       t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:     t6: v16i8 = insert_subvector undef:v16i8, t4, Constant:i64<0>
+; CHECK:     t6: v16i8 = insert_subvector poison:v16i8, t4, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:v16i8 $q0, t6
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:v16i8 $q0, t8:1
 
@@ -285,7 +285,7 @@ define <16 x i8> @extract_fixed_from_scalable(<vscale x 16 x i8> %a) #0 {
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:         t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0
 ; CHECK:       t4: v4i8 = extract_subvector t2, Constant:i64<0>
-; CHECK:     t6: nxv16i8 = insert_subvector undef:nxv16i8, t4, Constant:i64<0>
+; CHECK:     t6: nxv16i8 = insert_subvector poison:nxv16i8, t4, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t6
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:1
 
@@ -293,7 +293,7 @@ define <16 x i8> @extract_fixed_from_scalable(<vscale x 16 x i8> %a) #0 {
 ; CHECK: SelectionDAG has 9 nodes:
 ; CHECK:   t0: ch,glue = EntryToken
 ; CHECK:       t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0
-; CHECK:     t10: nxv16i8 = insert_subvector undef:nxv16i8, t2, Constant:i64<0>
+; CHECK:     t10: nxv16i8 = insert_subvector poison:nxv16i8, t2, Constant:i64<0>
 ; CHECK:   t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t10
 ; CHECK:   t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:1
 
diff --git a/llvm/test/CodeGen/X86/half.ll b/llvm/test/CodeGen/X86/half.ll
index 1b98886ba24e7..a64238170cef9 100644
--- a/llvm/test/CodeGen/X86/half.ll
+++ b/llvm/test/CodeGen/X86/half.ll
@@ -1991,8 +1991,8 @@ define void @pr63114() {
 ; CHECK-LIBCALL-LABEL: pr63114:
 ; CHECK-LIBCALL:       # %bb.0:
 ; CHECK-LIBCALL-NEXT:    movdqu (%rax), %xmm4
-; CHECK-LIBCALL-NEXT:    pshuflw {{.*#+}} xmm0 = xmm4[0,1,3,3,4,5,6,7]
-; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,2,1]
+; CHECK-LIBCALL-NEXT:    pshufhw {{.*#+}} xmm0 = xmm4[0,1,2,3,4,5,7,7]
+; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
 ; CHECK-LIBCALL-NEXT:    movdqa {{.*#+}} xmm1 = [65535,65535,65535,0,65535,65535,65535,65535]
 ; CHECK-LIBCALL-NEXT:    pand %xmm1, %xmm0
 ; CHECK-LIBCALL-NEXT:    movq {{.*#+}} xmm2 = [0,0,0,15360,0,0,0,0]
@@ -2001,8 +2001,8 @@ define void @pr63114() {
 ; CHECK-LIBCALL-NEXT:    pand %xmm3, %xmm0
 ; CHECK-LIBCALL-NEXT:    movdqa {{.*#+}} xmm5 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60]
 ; CHECK-LIBCALL-NEXT:    por %xmm5, %xmm0
-; CHECK-LIBCALL-NEXT:    pshufhw {{.*#+}} xmm6 = xmm4[0,1,2,3,4,5,7,7]
-; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,2,2,3]
+; CHECK-LIBCALL-NEXT:    pshuflw {{.*#+}} xmm6 = xmm4[0,1,3,3,4,5,6,7]
+; CHECK-LIBCALL-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,0,2,1]
 ; CHECK-LIBCALL-NEXT:    pand %xmm1, %xmm6
 ; CHECK-LIBCALL-NEXT:    por %xmm2, %xmm6
 ; CHECK-LIBCALL-NEXT:    pand %xmm3, %xmm6
@@ -2020,8 +2020,8 @@ define void @pr63114() {
 ; CHECK-LIBCALL-NEXT:    por %xmm5, %xmm7
 ; CHECK-LIBCALL-NEXT:    movdqu %xmm7, 0
 ; CHECK-LIBCALL-NEXT:    movdqu %xmm4, 32
-; CHECK-LIBCALL-NEXT:    movdqu %xmm6, 48
-; CHECK-LIBCALL-NEXT:    movdqu %xmm0, 16
+; CHECK-LIBCALL-NEXT:    movdqu %xmm6, 16
+; CHECK-LIBCALL-NEXT:    movdqu %xmm0, 48
 ; CHECK-LIBCALL-NEXT:    retq
 ;
 ; BWON-F16C-LABEL: pr63114:
@@ -2056,8 +2056,8 @@ define void @pr63114() {
 ; CHECK-I686-LABEL: pr63114:
 ; CHECK-I686:       # %bb.0:
 ; CHECK-I686-NEXT:    movdqu (%eax), %xmm6
-; CHECK-I686-NEXT:    pshuflw {{.*#+}} xmm0 = xmm6[0,1,3,3,4,5,6,7]
-; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,0,2,1]
+; CHECK-I686-NEXT:    pshufhw {{.*#+}} xmm0 = xmm6[0,1,2,3,4,5,7,7]
+; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
 ; CHECK-I686-NEXT:    movdqa {{.*#+}} xmm1 = [65535,65535,65535,0,65535,65535,65535,65535]
 ; CHECK-I686-NEXT:    pand %xmm1, %xmm0
 ; CHECK-I686-NEXT:    movq {{.*#+}} xmm2 = [0,0,0,15360,0,0,0,0]
@@ -2066,8 +2066,8 @@ define void @pr63114() {
 ; CHECK-I686-NEXT:    pand %xmm3, %xmm0
 ; CHECK-I686-NEXT:    movdqa {{.*#+}} xmm4 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60]
 ; CHECK-I686-NEXT:    por %xmm4, %xmm0
-; CHECK-I686-NEXT:    pshufhw {{.*#+}} xmm5 = xmm6[0,1,2,3,4,5,7,7]
-; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3]
+; CHECK-I686-NEXT:    pshuflw {{.*#+}} xmm5 = xmm6[0,1,3,3,4,5,6,7]
+; CHECK-I686-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,0,2,1]
 ; CHECK-I686-NEXT:    pand %xmm1, %xmm5
 ; CHECK-I686-NEXT:    por %xmm2, %xmm5
 ; CHECK-I686-NEXT:    pand %xmm3, %xmm5
@@ -2085,8 +2085,8 @@ define void @pr63114() {
 ; CHECK-I686-NEXT:    por %xmm4, %xmm7
 ; CHECK-I686-NEXT:    movdqu %xmm7, 0
 ; CHECK-I686-NEXT:    movdqu %xmm6, 32
-; CHECK-I686-NEXT:    movdqu %xmm5, 48
-; CHECK-I686-NEXT:    movdqu %xmm0, 16
+; CHECK-I686-NEXT:    movdqu %xmm5, 16
+; CHECK-I686-NEXT:    movdqu %xmm0, 48
 ; CHECK-I686-NEXT:    retl
   %1 = load <24 x half>, ptr poison, align 2
   %2 = shufflevector <24 x half> %1, <24 x half> poison, <8 x i32> <i32 2, i32 5, i32 8, i32 11, i32 14, i32 17, i32 20, i32 23>
diff --git a/llvm/test/CodeGen/X86/pr119158.ll b/llvm/test/CodeGen/X86/pr119158.ll
index ca31df802c913..4a1da30ca6c25 100644
--- a/llvm/test/CodeGen/X86/pr119158.ll
+++ b/llvm/test/CodeGen/X86/pr119158.ll
@@ -5,9 +5,10 @@ define dso_local void @foo() #1 {
 ; CHECK-LABEL: foo:
 ; CHECK:       # %bb.0: # %newFuncRoot
 ; CHECK-NEXT:    vpmovzxbd {{.*#+}} ymm0 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero,mem[4],zero,zero,zero,mem[5],zero,zero,zero,mem[6],zero,zero,zero,mem[7],zero,zero,zero
-; CHECK-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [64,64,64,64,64,64,64,64]
-; CHECK-NEXT:    vpdpwssd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %ymm1
-; CHECK-NEXT:    vpsrld $7, %ymm1, %ymm0
+; CHECK-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [18,0,18,0,18,0,18,0,18,0,18,0,18,0,18,0]
+; CHECK-NEXT:    vpmaddwd        %ymm1, %ymm0, %ymm0
+; CHECK-NEXT:    vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %ymm0
+; CHECK-NEXT:    vpsrld $7, %ymm0, %ymm0
 ; CHECK-NEXT:    vpackusdw %ymm0, %ymm0, %ymm0
 ; CHECK-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
 ; CHECK-NEXT:    vmovdqu %ymm0, (%rax)

>From 781c794614ddceb884c3274116492217444b5ace Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Wed, 9 Apr 2025 17:31:36 +0000
Subject: [PATCH 2/2] [DAGTypeLegalize] Legalize ISD::POISON as ISD::UNDEF for
 Float Type Legalization

---
 .../SelectionDAG/LegalizeFloatTypes.cpp       |  3 +++
 .../CodeGen/PowerPC/poison-legalization.ll    | 11 +++++++++
 .../test/CodeGen/RISCV/poison-legalization.ll | 24 +++++++++++++++++++
 3 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/PowerPC/poison-legalization.ll
 create mode 100644 llvm/test/CodeGen/RISCV/poison-legalization.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index 5ed83060e150e..432209e8ecb0a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -165,6 +165,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
     case ISD::STRICT_UINT_TO_FP:
     case ISD::SINT_TO_FP:
     case ISD::UINT_TO_FP:  R = SoftenFloatRes_XINT_TO_FP(N); break;
+    case ISD::POISON:
     case ISD::UNDEF:       R = SoftenFloatRes_UNDEF(N); break;
     case ISD::VAARG:       R = SoftenFloatRes_VAARG(N); break;
     case ISD::VECREDUCE_FADD:
@@ -1501,6 +1502,7 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
     report_fatal_error("Do not know how to expand the result of this "
                        "operator!");
     // clang-format off
+  case ISD::POISON:
   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
   case ISD::SELECT:       SplitRes_Select(N, Lo, Hi); break;
   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
@@ -3319,6 +3321,7 @@ void DAGTypeLegalizer::SoftPromoteHalfResult(SDNode *N, unsigned ResNo) {
   case ISD::STRICT_UINT_TO_FP:
   case ISD::SINT_TO_FP:
   case ISD::UINT_TO_FP:  R = SoftPromoteHalfRes_XINT_TO_FP(N); break;
+  case ISD::POISON:
   case ISD::UNDEF:       R = SoftPromoteHalfRes_UNDEF(N); break;
   case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
   case ISD::VECREDUCE_FADD:
diff --git a/llvm/test/CodeGen/PowerPC/poison-legalization.ll b/llvm/test/CodeGen/PowerPC/poison-legalization.ll
new file mode 100644
index 0000000000000..4090779a984fb
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/poison-legalization.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu  | FileCheck %s
+
+define void @ExpandFloat(ptr %p1 )  {
+; CHECK:      stfd 0, 8(3) 
+; CHECK-NEXT: stfd 0, 0(3)
+; CHECK-NEXT: blr
+entry:
+   store volatile ppc_fp128 poison, ptr %p1
+   ret void
+}
+
diff --git a/llvm/test/CodeGen/RISCV/poison-legalization.ll b/llvm/test/CodeGen/RISCV/poison-legalization.ll
new file mode 100644
index 0000000000000..f0954b74e9377
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/poison-legalization.ll
@@ -0,0 +1,24 @@
+; RUN: llc < %s -mtriple=riscv32  | FileCheck %s
+
+define void @SoftenFloat(ptr %p1)  {
+; CHECK-LABEL: SoftenFloat:
+; CHECK:       # %bb.0:                                # %entry
+; CHECK-NEXT:     sw      a0, 4(a0)
+; CHECK-NEXT:     sw      a0, 0(a0)
+; CHECK-NEXT:     ret
+
+entry:
+  store volatile double poison, ptr %p1
+  ret void
+}
+
+define void @PromoteHalf(ptr %p1 )  {
+; CHECK-LABEL: PromoteHalf:
+; CHECK:       # %bb.0:                                # %entry
+; CHECK-NEXT:     sh      a0, 0(a0)
+; CHECK-NEXT:     ret
+entry:
+   store volatile half poison, ptr %p1
+   ret void
+}
+



More information about the llvm-commits mailing list