[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