[llvm] Eliminating `li of 0 into arg registers` instruction of unused arguments (PR #122741)

zhijian lin via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 3 11:36:14 PST 2025


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

>From 4e80a929d5ef7c1c257f32f38cdd0df5c03586e5 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 3 Feb 2025 19:25:18 +0000
Subject: [PATCH 1/2] introduce a ISD::POISON SDNode

---
 llvm/include/llvm/CodeGen/ISDOpcodes.h        |  3 ++
 llvm/include/llvm/CodeGen/SelectionDAG.h      |  7 ++--
 llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 13 ++++++--
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 ++++----
 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 13 ++++++++
 .../SelectionDAG/LegalizeFloatTypes.cpp       |  4 +++
 .../SelectionDAG/LegalizeIntegerTypes.cpp     |  2 ++
 .../SelectionDAG/LegalizeVectorTypes.cpp      |  3 ++
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 33 ++++++++++++++++++-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  2 +-
 .../SelectionDAG/SelectionDAGDumper.cpp       |  1 +
 .../CodeGen/SelectionDAG/SelectionDAGISel.cpp |  1 +
 llvm/test/CodeGen/RISCV/miss-sp-restore-eh.ll |  8 -----
 13 files changed, 83 insertions(+), 20 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 604dc9419025b0..cdb0d4b92bbf70 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 b31ad11c3ee0ee..73d790f71f0cb7 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -871,7 +871,7 @@ class SelectionDAG {
   /// for integers, a type wider than) VT's element type.
   SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op) {
     // VerifySDNode (via InsertNode) checks BUILD_VECTOR later.
-    if (Op.getOpcode() == ISD::UNDEF) {
+    if (Op.isUndef()) {
       assert((VT.getVectorElementType() == Op.getValueType() ||
               (VT.isInteger() &&
                VT.getVectorElementType().bitsLE(Op.getValueType()))) &&
@@ -887,7 +887,7 @@ class SelectionDAG {
   // Return a splat ISD::SPLAT_VECTOR node, consisting of Op splatted to all
   // elements.
   SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op) {
-    if (Op.getOpcode() == ISD::UNDEF) {
+    if (Op.isUndef()) {
       assert((VT.getVectorElementType() == Op.getValueType() ||
               (VT.isInteger() &&
                VT.getVectorElementType().bitsLE(Op.getValueType()))) &&
@@ -1128,6 +1128,9 @@ class SelectionDAG {
     return getNode(ISD::UNDEF, SDLoc(), VT);
   }
 
+  /// Return an 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 03899493847b39..c98c9da43a3080 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -690,8 +690,17 @@ 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, when UndefOnly is false,
+  /// POISON.
+  /// - When UndefOnly is true, returns true only for UNDEF.
+  /// - When UndefOnly is false, returns true for both UNDEF and POISON.
+  /// @param UndefOnly Determines whether to check only for UNDEF.
+  bool isUndef(bool UndefOnly = false) const {
+    return NodeType == ISD::UNDEF || (!UndefOnly && NodeType == ISD::POISON);
+  }
+
+  /// Return true if the type of the node type poison.
+  bool isPoison() const { return 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 02b79c67af3ee0..ce776214df1f1e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16156,7 +16156,7 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
     // also recursively replace t184 by t150.
     SDValue MaybePoisonOperand = N->getOperand(0).getOperand(OpNo);
     // Don't replace every single UNDEF everywhere with frozen UNDEF, though.
-    if (MaybePoisonOperand.getOpcode() == ISD::UNDEF)
+    if (MaybePoisonOperand.isUndef())
       continue;
     // First, freeze each offending operand.
     SDValue FrozenMaybePoisonOperand = DAG.getFreeze(MaybePoisonOperand);
@@ -16182,9 +16182,10 @@ 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.
+  // Special-handle ISD::UNDEF, ISD::POISON, each single one of them can be it's
+  // own thing.
   for (SDValue &Op : Ops) {
-    if (Op.getOpcode() == ISD::UNDEF)
+    if (Op.isUndef())
       Op = DAG.getFreeze(Op);
   }
 
@@ -24320,7 +24321,7 @@ static SDValue combineConcatVectorOfScalars(SDNode *N, SelectionDAG &DAG) {
     if (ISD::BITCAST == Op.getOpcode() &&
         !Op.getOperand(0).getValueType().isVector())
       Ops.push_back(Op.getOperand(0));
-    else if (ISD::UNDEF == Op.getOpcode())
+    else if (Op.isUndef())
       Ops.push_back(DAG.getNode(ISD::UNDEF, DL, SVT));
     else
       return SDValue();
@@ -24715,7 +24716,7 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) {
   // fold (concat_vectors (BUILD_VECTOR A, B, ...), (BUILD_VECTOR C, D, ...))
   // -> (BUILD_VECTOR A, B, ..., C, D, ...)
   auto IsBuildVectorOrUndef = [](const SDValue &Op) {
-    return ISD::UNDEF == Op.getOpcode() || ISD::BUILD_VECTOR == Op.getOpcode();
+    return Op.isUndef() || ISD::BUILD_VECTOR == Op.getOpcode();
   };
   if (llvm::all_of(N->ops(), IsBuildVectorOrUndef)) {
     SmallVector<SDValue, 8> Opnds;
@@ -24739,7 +24740,7 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) {
       EVT OpVT = Op.getValueType();
       unsigned NumElts = OpVT.getVectorNumElements();
 
-      if (ISD::UNDEF == Op.getOpcode())
+      if (Op.isUndef())
         Opnds.append(NumElts, DAG.getUNDEF(MinVT));
 
       if (ISD::BUILD_VECTOR == Op.getOpcode()) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index c6475f02199033..773bf9f0b0e2f1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -977,6 +977,18 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
   TargetLowering::LegalizeAction Action = TargetLowering::Legal;
   bool SimpleFinishLegalizing = true;
   switch (Node->getOpcode()) {
+  // FixMe: If the node represents a poison value, replace it with an undef
+  // value.
+  //  A poison value results from an erroneous operation but does not cause
+  //  immediate undefined behavior, allowing speculative execution.
+  //  Since most operations propagate poison, it is valid to replace poison
+  //  with an undef value, which can take any legal value of the same type.
+  //  This ensures that downstream computations do not rely on poison semantics.
+  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:
@@ -3136,6 +3148,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 71f100bfa03434..1c28722f3f0a28 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -164,6 +164,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:
@@ -1474,6 +1475,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;
@@ -2783,6 +2785,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:
@@ -3242,6 +3245,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/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index be7521f3416850..4da7bf9a680abe 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;
@@ -2840,6 +2841,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 5117eb8d91dfb2..37aad1e21f7bd2 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;
@@ -1117,6 +1118,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;
@@ -4523,6 +4525,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 0dfd0302ae5438..aab7120cbf13ba 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5458,6 +5458,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
   case ISD::CopyFromReg:
     return true;
 
+  case ISD::POISON:
+    return false;
+
   case ISD::UNDEF:
     return PoisonOnly;
 
@@ -6310,6 +6313,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     if (OpOpcode == ISD::UNDEF)
       // sext(undef) = 0, because the top bits will all be the same.
       return getConstant(0, DL, VT);
+
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
+
     break;
   case ISD::ZERO_EXTEND:
     assert(VT.isInteger() && N1.getValueType().isInteger() &&
@@ -6331,6 +6338,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
       // zext(undef) = 0, because the top bits will be zero.
       return getConstant(0, DL, VT);
 
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
+
     // Skip unnecessary zext_inreg pattern:
     // (zext (trunc x)) -> x iff the upper bits are known zero.
     // TODO: Remove (zext (trunc (and x, c))) exception which some targets
@@ -6371,6 +6381,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     }
     if (OpOpcode == ISD::UNDEF)
       return getUNDEF(VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
 
     // (ext (trunc x)) -> x
     if (OpOpcode == ISD::TRUNCATE) {
@@ -6406,6 +6418,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     }
     if (OpOpcode == ISD::UNDEF)
       return getUNDEF(VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
     if (OpOpcode == ISD::VSCALE && !NewNodesMustHaveLegalTypes)
       return getVScale(DL, VT,
                        N1.getConstantOperandAPInt(0).trunc(VT.getSizeInBits()));
@@ -6424,6 +6438,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     assert(VT.isInteger() && VT == N1.getValueType() && "Invalid ABS!");
     if (OpOpcode == ISD::UNDEF)
       return getConstant(0, DL, VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
     break;
   case ISD::BSWAP:
     assert(VT.isInteger() && VT == N1.getValueType() && "Invalid BSWAP!");
@@ -6431,6 +6447,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
            "BSWAP types must be a multiple of 16 bits!");
     if (OpOpcode == ISD::UNDEF)
       return getUNDEF(VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
     // bswap(bswap(X)) -> X.
     if (OpOpcode == ISD::BSWAP)
       return N1.getOperand(0);
@@ -6439,6 +6457,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     assert(VT.isInteger() && VT == N1.getValueType() && "Invalid BITREVERSE!");
     if (OpOpcode == ISD::UNDEF)
       return getUNDEF(VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
     break;
   case ISD::BITCAST:
     assert(VT.getSizeInBits() == N1.getValueSizeInBits() &&
@@ -6448,6 +6468,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
       return getNode(ISD::BITCAST, DL, VT, N1.getOperand(0));
     if (OpOpcode == ISD::UNDEF)
       return getUNDEF(VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
     break;
   case ISD::SCALAR_TO_VECTOR:
     assert(VT.isVector() && !N1.getValueType().isVector() &&
@@ -6458,6 +6480,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
            "Illegal SCALAR_TO_VECTOR node!");
     if (OpOpcode == ISD::UNDEF)
       return getUNDEF(VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
     // scalar_to_vector(extract_vector_elt V, 0) -> V, top bits are undefined.
     if (OpOpcode == ISD::EXTRACT_VECTOR_ELT &&
         isa<ConstantSDNode>(N1.getOperand(1)) &&
@@ -6469,6 +6493,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
     // Negation of an unknown bag of bits is still completely undefined.
     if (OpOpcode == ISD::UNDEF)
       return getUNDEF(VT);
+    if (OpOpcode == ISD::POISON)
+      return getPoison(VT);
 
     if (OpOpcode == ISD::FNEG) // --X -> X
       return N1.getOperand(0);
@@ -9237,6 +9263,11 @@ SDValue SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
 
   SDVTList VTs = Indexed ?
     getVTList(VT, Ptr.getValueType(), MVT::Other) : getVTList(VT, MVT::Other);
+
+  // FixedMe: lower poison to undef.
+  if (Ptr.getNode()->isPoison())
+    Ptr = getUNDEF(Ptr.getValueType());
+
   SDValue Ops[] = { Chain, Ptr, Offset };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::LOAD, VTs, Ops);
@@ -13374,7 +13405,7 @@ void BuildVectorSDNode::recastRawBits(bool IsLittleEndian,
 bool BuildVectorSDNode::isConstant() const {
   for (const SDValue &Op : op_values()) {
     unsigned Opc = Op.getOpcode();
-    if (Opc != ISD::UNDEF && Opc != ISD::Constant && Opc != ISD::ConstantFP)
+    if (!Op.isUndef() && Opc != ISD::Constant && Opc != ISD::ConstantFP)
       return false;
   }
   return true;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index f8d7c3ef7bbe71..fe4e3c00d4260e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1819,7 +1819,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 580ff19065557b..4434b1203451f9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -188,6 +188,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 d64a90bcaae7da..48fd1e1e459195 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3275,6 +3275,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/RISCV/miss-sp-restore-eh.ll b/llvm/test/CodeGen/RISCV/miss-sp-restore-eh.ll
index a5847365159a84..395fc99ea05362 100644
--- a/llvm/test/CodeGen/RISCV/miss-sp-restore-eh.ll
+++ b/llvm/test/CodeGen/RISCV/miss-sp-restore-eh.ll
@@ -27,14 +27,6 @@ define signext i32 @foo() #1 personality ptr @__gxx_personality_v0 {
 ; CHECK-NEXT:    .cfi_remember_state
 ; CHECK-NEXT:  .Ltmp0:
 ; CHECK-NEXT:    addi sp, sp, -32
-; CHECK-NEXT:    li a0, 0
-; CHECK-NEXT:    li a1, 0
-; CHECK-NEXT:    li a2, 0
-; CHECK-NEXT:    li a3, 0
-; CHECK-NEXT:    li a4, 0
-; CHECK-NEXT:    li a5, 0
-; CHECK-NEXT:    li a6, 0
-; CHECK-NEXT:    li a7, 0
 ; CHECK-NEXT:    call _Z3fooiiiiiiiiiiPi
 ; CHECK-NEXT:    addi sp, sp, 32
 ; CHECK-NEXT:  .Ltmp1:

>From 3f216a568a97294a2353c61d6fa93ae43b2d895f Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 3 Feb 2025 19:50:40 +0000
Subject: [PATCH 2/2] added a new test case

---
 llvm/test/CodeGen/PowerPC/undef-args.ll | 221 ++++++++++++++++++++++++
 1 file changed, 221 insertions(+)
 create mode 100644 llvm/test/CodeGen/PowerPC/undef-args.ll

diff --git a/llvm/test/CodeGen/PowerPC/undef-args.ll b/llvm/test/CodeGen/PowerPC/undef-args.ll
new file mode 100644
index 00000000000000..3b944539f524d0
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/undef-args.ll
@@ -0,0 +1,221 @@
+;; Test the unused argument are converted to ISD::UNDEF SDNode.
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -debug-only=isel \
+; RUN:   %s -o - 2>&1 | FileCheck --check-prefix=CHECKSEL32 %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -debug-only=isel \
+; RUN:   %s -o - 2>&1 | FileCheck --check-prefix=CHECKSEL64 %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -filetype=asm \
+; RUN:   %s -o - 2>&1 | FileCheck --check-prefix=CHECKASM32 %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -filetype=asm \
+; RUN:   %s -o - 2>&1 | FileCheck --check-prefix=CHECKASM64 %s
+
+define void @bar32(i32 zeroext %var1, i32 noundef zeroext %var2) local_unnamed_addr  {
+entry:
+  tail call void @foo32(i32 noundef zeroext %var2)
+  ret void
+}
+
+declare void @foo32(i32 noundef zeroext) local_unnamed_addr
+
+define void @test32() local_unnamed_addr {
+entry:
+  tail call void @bar32(i32 zeroext poison, i32 noundef zeroext 255)
+  ret void
+}
+
+; CHECKSEL32:     Initial selection DAG: %bb.0 'test32:entry'
+; CHECKSEL32-NEXT: SelectionDAG has 18 nodes:
+; CHECKSEL32-NEXT:   t1: i32 = GlobalAddress<ptr @bar32> 0
+; CHECKSEL32-NEXT:   t7: i32 = Register $r1
+; CHECKSEL32-NEXT:       t0: ch,glue = EntryToken
+; CHECKSEL32-NEXT:     t6: ch,glue = callseq_start t0, TargetConstant:i32<56>, TargetConstant:i32<0>
+; CHECKSEL32-NEXT:   t9: ch,glue = CopyToReg t6, Register:i32 $r3, poison:i32
+; CHECKSEL32-NEXT:   t11: ch,glue = CopyToReg t9, Register:i32 $r4, Constant:i32<255>, t9:1
+; CHECKSEL32-NEXT:   t15: ch,glue = PPCISD::CALL_NOP t11, MCSymbol:i32, Register:i32 $r3, Register:i32 $r4, Register:i32 $r2, RegisterMask:Untyped, t11:1
+; CHECKSEL32-NEXT:     t16: ch,glue = callseq_end t15, TargetConstant:i32<56>, TargetConstant:i32<0>, t15:1
+; CHECKSEL32-NEXT:   t17: ch = PPCISD::RET_GLUE t16
+
+; CHECKASM32:      .test32:
+; CHECKASM32-NEXT: # %bb.0:                                # %entry
+; CHECKASM32-NEXT:         mflr 0
+; CHECKASM32-NEXT:         stwu 1, -64(1)
+; CHECKASM32-NEXT:         li 4, 255
+; CHECKASM32-NEXT:         stw 0, 72(1)
+; CHECKASM32-NEXT:         bl .bar32
+; CHECKASM32-NEXT:         nop
+; CHECKASM32-NEXT:         addi 1, 1, 64
+; CHECKASM32-NEXT:         lwz 0, 8(1)
+; CHECKASM32-NEXT:         mtlr 0
+; CHECKASM32-NEXT:         blr
+
+; CHECKSEL64:     Initial selection DAG: %bb.0 'test32:entry'
+; CHECKSEL64-NEXT: SelectionDAG has 20 nodes:
+; CHECKSEL64-NEXT:   t1: i64 = GlobalAddress<ptr @bar32> 0
+; CHECKSEL64-NEXT:   t2: i32 = poison
+; CHECKSEL64-NEXT:   t3: i32 = Constant<255>
+; CHECKSEL64-NEXT:   t7: i64 = Register $x1
+; CHECKSEL64-NEXT:       t0: ch,glue = EntryToken
+; CHECKSEL64-NEXT:     t6: ch,glue = callseq_start t0, TargetConstant:i64<112>, TargetConstant:i64<0>
+; CHECKSEL64-NEXT:   t11: ch,glue = CopyToReg t6, Register:i64 $x3, poison:i64
+; CHECKSEL64-NEXT:   t13: ch,glue = CopyToReg t11, Register:i64 $x4, Constant:i64<255>, t11:1
+; CHECKSEL64-NEXT:   t17: ch,glue = PPCISD::CALL_NOP t13, MCSymbol:i64, Register:i64 $x3, Register:i64 $x4, Register:i64 $x2, RegisterMask:Untyped, t13:1
+; CHECKSEL64-NEXT:     t18: ch,glue = callseq_end t17, TargetConstant:i64<112>, TargetConstant:i64<0>, t17:1
+; CHECKSEL64-NEXT:   t19: ch = PPCISD::RET_GLUE t18
+
+; CHECKASM64:      .test32:
+; CHECKASM64-NEXT: # %bb.0:                                # %entry
+; CHECKASM64-NEXT:         mflr 0
+; CHECKASM64-NEXT:         stdu 1, -112(1)
+; CHECKASM64-NEXT:         li 4, 255
+; CHECKASM64-NEXT:         std 0, 128(1)
+; CHECKASM64-NEXT:         bl .bar32
+; CHECKASM64-NEXT:         nop
+; CHECKASM64-NEXT:         addi 1, 1, 112
+; CHECKASM64-NEXT:         ld 0, 16(1)
+; CHECKASM64-NEXT:         mtlr 0
+; CHECKASM64-NEXT:         blr
+
+define void @bar8(i8 zeroext %var1, i8 noundef zeroext %var2) local_unnamed_addr  {
+entry:
+  tail call void @foo8(i8 noundef zeroext %var2)
+  ret void
+}
+
+declare void @foo8(i8 noundef zeroext) local_unnamed_addr
+
+define void @test8() local_unnamed_addr {
+entry:
+  tail call void @bar8(i8 zeroext poison, i8 noundef zeroext 255)
+  ret void
+}
+
+; CHECKSEL32:     Initial selection DAG: %bb.0 'test8:entry'
+; CHECKSEL32-NEXT: SelectionDAG has 20 nodes:
+; CHECKSEL32-NEXT:   t1: i32 = GlobalAddress<ptr @bar8> 0
+; CHECKSEL32-NEXT:   t2: i8 = poison
+; CHECKSEL32-NEXT:   t3: i8 = Constant<-1>
+; CHECKSEL32-NEXT:   t9: i32 = Register $r1
+; CHECKSEL32-NEXT:       t0: ch,glue = EntryToken
+; CHECKSEL32-NEXT:     t8: ch,glue = callseq_start t0, TargetConstant:i32<56>, TargetConstant:i32<0>
+; CHECKSEL32-NEXT:   t11: ch,glue = CopyToReg t8, Register:i32 $r3, poison:i32
+; CHECKSEL32-NEXT:   t13: ch,glue = CopyToReg t11, Register:i32 $r4, Constant:i32<255>, t11:1
+; CHECKSEL32-NEXT:   t17: ch,glue = PPCISD::CALL_NOP t13, MCSymbol:i32, Register:i32 $r3, Register:i32 $r4, Register:i32 $r2, RegisterMask:Untyped, t13:1
+; CHECKSEL32-NEXT:     t18: ch,glue = callseq_end t17, TargetConstant:i32<56>, TargetConstant:i32<0>, t17:1
+; CHECKSEL32-NEXT:   t19: ch = PPCISD::RET_GLUE t18
+
+; CHECKASM32:      .test8:
+; CHECKASM32-NEXT: # %bb.0:                                # %entry
+; CHECKASM32-NEXT:         mflr 0
+; CHECKASM32-NEXT:         stwu 1, -64(1)
+; CHECKASM32-NEXT:         li 4, 255
+; CHECKASM32-NEXT:         stw 0, 72(1)
+; CHECKASM32-NEXT:         bl .bar8
+; CHECKASM32-NEXT:         nop
+; CHECKASM32-NEXT:         addi 1, 1, 64
+; CHECKASM32-NEXT:         lwz 0, 8(1)
+; CHECKASM32-NEXT:         mtlr 0
+; CHECKASM32-NEXT:         blr
+
+; CHECKASM64:      .test8:
+; CHECKASM64-NEXT: # %bb.0:                                # %entry
+; CHECKASM64-NEXT:         mflr 0
+; CHECKASM64-NEXT:         stdu 1, -112(1)
+; CHECKASM64-NEXT:         li 4, 255
+; CHECKASM64-NEXT:         std 0, 128(1)
+; CHECKASM64-NEXT:         bl .bar8
+; CHECKASM64-NEXT:         nop
+; CHECKASM64-NEXT:         addi 1, 1, 112
+; CHECKASM64-NEXT:         ld 0, 16(1)
+; CHECKASM64-NEXT:         mtlr 0
+; CHECKASM64-NEXT:         blr
+
+; CHECKSEL64:      Initial selection DAG: %bb.0 'test8:entry'
+; CHECKSEL64-NEXT: SelectionDAG has 22 nodes:
+; CHECKSEL64-NEXT:   t1: i64 = GlobalAddress<ptr @bar8> 0
+; CHECKSEL64-NEXT:   t2: i8 = poison
+; CHECKSEL64-NEXT:   t3: i8 = Constant<-1>
+; CHECKSEL64-NEXT:   t4: i32 = poison
+; CHECKSEL64-NEXT:   t5: i32 = Constant<255>
+; CHECKSEL64-NEXT:   t9: i64 = Register $x1
+; CHECKSEL64-NEXT:       t0: ch,glue = EntryToken
+; CHECKSEL64-NEXT:     t8: ch,glue = callseq_start t0, TargetConstant:i64<112>, TargetConstant:i64<0>
+; CHECKSEL64-NEXT:   t13: ch,glue = CopyToReg t8, Register:i64 $x3, poison:i64
+; CHECKSEL64-NEXT:   t15: ch,glue = CopyToReg t13, Register:i64 $x4, Constant:i64<255>, t13:1
+; CHECKSEL64-NEXT:   t19: ch,glue = PPCISD::CALL_NOP t15, MCSymbol:i64, Register:i64 $x3, Register:i64 $x4, Register:i64 $x2, RegisterMask:Untyped, t15:1
+; CHECKSEL64-NEXT:     t20: ch,glue = callseq_end t19, TargetConstant:i64<112>, TargetConstant:i64<0>, t19:1
+; CHECKSEL64-NEXT:   t21: ch = PPCISD::RET_GLUE t20
+
+
+define void @bar64(i64 zeroext %var1, i64 noundef zeroext %var2) local_unnamed_addr  {
+entry:
+  tail call void @foo64(i64 noundef zeroext %var2)
+  ret void
+}
+
+declare void @foo64(i64 noundef zeroext) local_unnamed_addr
+
+; Function Attrs: noinline nounwind
+define void @test64() local_unnamed_addr {
+entry:
+  tail call void @bar64(i64 zeroext poison, i64 noundef zeroext 255)
+  ret void
+}
+
+; CHECKSEL32:     Initial selection DAG: %bb.0 'test64:entry'
+; CHECKSEL32-NEXT: SelectionDAG has 27 nodes:
+; CHECKSEL32-NEXT:   t1: i32 = GlobalAddress<ptr @bar64> 0
+; CHECKSEL32-NEXT:   t3: i64 = Constant<255>
+; CHECKSEL32-NEXT:   t12: i32 = Register $r1
+; CHECKSEL32-NEXT:       t0: ch,glue = EntryToken
+; CHECKSEL32-NEXT:     t11: ch,glue = callseq_start t0, TargetConstant:i32<56>, TargetConstant:i32<0>
+; CHECKSEL32-NEXT:     t5: i32 = extract_element poison:i64, Constant:i32<1>
+; CHECKSEL32-NEXT:   t14: ch,glue = CopyToReg t11, Register:i32 $r3, t5
+; CHECKSEL32-NEXT:     t7: i32 = extract_element poison:i64, Constant:i32<0>
+; CHECKSEL32-NEXT:   t16: ch,glue = CopyToReg t14, Register:i32 $r4, t7, t14:1
+; CHECKSEL32-NEXT:   t18: ch,glue = CopyToReg t16, Register:i32 $r5, Constant:i32<0>, t16:1
+; CHECKSEL32-NEXT:   t20: ch,glue = CopyToReg t18, Register:i32 $r6, Constant:i32<255>, t18:1
+; CHECKSEL32-NEXT:   t24: ch,glue = PPCISD::CALL_NOP t20, MCSymbol:i32, Register:i32 $r3, Register:i32 $r4, Register:i32 $r5, Register:i32 $r6, Register:i32 $r2, RegisterMask:Untyped, t20:1
+; CHECKSEL32-NEXT:     t25: ch,glue = callseq_end t24, TargetConstant:i32<56>, TargetConstant:i32<0>, t24:1
+; CHECKSEL32-NEXT:   t26: ch = PPCISD::RET_GLUE t25
+
+; CHECKASM32:      .test64:
+; CHECKASM32-NEXT: # %bb.0:                                # %entry
+; CHECKASM32-NEXT:         mflr 0
+; CHECKASM32-NEXT:         stwu 1, -64(1)
+; CHECKASM32-NEXT:         li 5, 0
+; CHECKASM32-NEXT:         li 6, 255
+; CHECKASM32-NEXT:         stw 0, 72(1)
+; CHECKASM32-NEXT:         bl .bar64
+; CHECKASM32-NEXT:         nop
+; CHECKASM32-NEXT:         addi 1, 1, 64
+; CHECKASM32-NEXT:         lwz 0, 8(1)
+; CHECKASM32-NEXT:         mtlr 0
+; CHECKASM32-NEXT:         blr
+
+; CHECKSEL64:     Initial selection DAG: %bb.0 'test64:entry'
+; CHECKSEL64-NEXT: SelectionDAG has 18 nodes:
+; CHECKSEL64-NEXT:   t1: i64 = GlobalAddress<ptr @bar64> 0
+; CHECKSEL64-NEXT:   t7: i64 = Register $x1
+; CHECKSEL64-NEXT:       t0: ch,glue = EntryToken
+; CHECKSEL64-NEXT:     t6: ch,glue = callseq_start t0, TargetConstant:i64<112>, TargetConstant:i64<0>
+; CHECKSEL64-NEXT:   t9: ch,glue = CopyToReg t6, Register:i64 $x3, poison:i64
+; CHECKSEL64-NEXT:   t11: ch,glue = CopyToReg t9, Register:i64 $x4, Constant:i64<255>, t9:1
+; CHECKSEL64-NEXT:   t15: ch,glue = PPCISD::CALL_NOP t11, MCSymbol:i64, Register:i64 $x3, Register:i64 $x4, Register:i64 $x2, RegisterMask:Untyped, t11:1
+; CHECKSEL64-NEXT:     t16: ch,glue = callseq_end t15, TargetConstant:i64<112>, TargetConstant:i64<0>, t15:1
+; CHECKSEL64-NEXT:   t17: ch = PPCISD::RET_GLUE t16
+
+; CHECKASM64:      .test64:
+; CHECKASM64-NEXT: # %bb.0:                                # %entry
+; CHECKASM64-NEXT:         mflr 0
+; CHECKASM64-NEXT:         stdu 1, -112(1)
+; CHECKASM64-NEXT:         li 4, 255
+; CHECKASM64-NEXT:         std 0, 128(1)
+; CHECKASM64-NEXT:         bl .bar64
+; CHECKASM64-NEXT:         nop
+; CHECKASM64-NEXT:         addi 1, 1, 112
+; CHECKASM64-NEXT:         ld 0, 16(1)
+; CHECKASM64-NEXT:         mtlr 0
+; CHECKASM64-NEXT:         blr



More information about the llvm-commits mailing list