diff options
author | Craig Topper <craig.topper@sifive.com> | 2024-02-19 12:21:17 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-19 12:21:17 -0800 |
commit | f8cbb67b10856465faedfbda81cd23c3ec920730 (patch) | |
tree | e94df9c7826c596e7e6f1939e9f7f83e1d3ee115 | |
parent | 1b26c25f7e56fe3d5e06c285566ef43812d7baee (diff) | |
download | llvm-f8cbb67b10856465faedfbda81cd23c3ec920730.zip llvm-f8cbb67b10856465faedfbda81cd23c3ec920730.tar.gz llvm-f8cbb67b10856465faedfbda81cd23c3ec920730.tar.bz2 |
[DAGCombiner] Preserve nneg flag from inner zext when we combine (z/s/aext (zext X)) (#82199)
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 23 | ||||
-rw-r--r-- | llvm/test/CodeGen/RISCV/sext-zext-trunc.ll | 75 |
3 files changed, 51 insertions, 66 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 030438a..89ef648 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -13710,8 +13710,12 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { // fold (zext (zext x)) -> (zext x) // fold (zext (aext x)) -> (zext x) - if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) - return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0)); + if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) { + SDNodeFlags Flags; + if (N0.getOpcode() == ISD::ZERO_EXTEND) + Flags.setNonNeg(N0->getFlags().hasNonNeg()); + return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0), Flags); + } // fold (zext (aext_extend_vector_inreg x)) -> (zext_extend_vector_inreg x) // fold (zext (zext_extend_vector_inreg x)) -> (zext_extend_vector_inreg x) @@ -14011,10 +14015,13 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { // fold (aext (aext x)) -> (aext x) // fold (aext (zext x)) -> (zext x) // fold (aext (sext x)) -> (sext x) - if (N0.getOpcode() == ISD::ANY_EXTEND || - N0.getOpcode() == ISD::ZERO_EXTEND || - N0.getOpcode() == ISD::SIGN_EXTEND) - return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0)); + if (N0.getOpcode() == ISD::ANY_EXTEND || N0.getOpcode() == ISD::ZERO_EXTEND || + N0.getOpcode() == ISD::SIGN_EXTEND) { + SDNodeFlags Flags; + if (N0.getOpcode() == ISD::ZERO_EXTEND) + Flags.setNonNeg(N0->getFlags().hasNonNeg()); + return DAG.getNode(N0.getOpcode(), DL, VT, N0.getOperand(0), Flags); + } // fold (aext (aext_extend_vector_inreg x)) -> (aext_extend_vector_inreg x) // fold (aext (zext_extend_vector_inreg x)) -> (zext_extend_vector_inreg x) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 421bb51..add92cf 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5715,8 +5715,12 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, N1.getValueType().getVectorElementCount()) && "Vector element count mismatch!"); assert(N1.getValueType().bitsLT(VT) && "Invalid sext node, dst < src!"); - if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND) - return getNode(OpOpcode, DL, VT, N1.getOperand(0)); + if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND) { + SDNodeFlags Flags; + if (OpOpcode == ISD::ZERO_EXTEND) + Flags.setNonNeg(N1->getFlags().hasNonNeg()); + return getNode(OpOpcode, DL, VT, N1.getOperand(0), Flags); + } if (OpOpcode == ISD::UNDEF) // sext(undef) = 0, because the top bits will all be the same. return getConstant(0, DL, VT); @@ -5732,8 +5736,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, N1.getValueType().getVectorElementCount()) && "Vector element count mismatch!"); assert(N1.getValueType().bitsLT(VT) && "Invalid zext node, dst < src!"); - if (OpOpcode == ISD::ZERO_EXTEND) // (zext (zext x)) -> (zext x) - return getNode(ISD::ZERO_EXTEND, DL, VT, N1.getOperand(0)); + if (OpOpcode == ISD::ZERO_EXTEND) { // (zext (zext x)) -> (zext x) + SDNodeFlags Flags; + Flags.setNonNeg(N1->getFlags().hasNonNeg()); + return getNode(ISD::ZERO_EXTEND, DL, VT, N1.getOperand(0), Flags); + } if (OpOpcode == ISD::UNDEF) // zext(undef) = 0, because the top bits will be zero. return getConstant(0, DL, VT); @@ -5769,9 +5776,13 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, assert(N1.getValueType().bitsLT(VT) && "Invalid anyext node, dst < src!"); if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND || - OpOpcode == ISD::ANY_EXTEND) + OpOpcode == ISD::ANY_EXTEND) { + SDNodeFlags Flags; + if (OpOpcode == ISD::ZERO_EXTEND) + Flags.setNonNeg(N1->getFlags().hasNonNeg()); // (ext (zext x)) -> (zext x) and (ext (sext x)) -> (sext x) - return getNode(OpOpcode, DL, VT, N1.getOperand(0)); + return getNode(OpOpcode, DL, VT, N1.getOperand(0), Flags); + } if (OpOpcode == ISD::UNDEF) return getUNDEF(VT); diff --git a/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll b/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll index 1257e7e..a2a953c 100644 --- a/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll +++ b/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll @@ -791,24 +791,13 @@ define void @zext_nneg_dominating_icmp_i32(i16 signext %0) { ; RV32I-NEXT: .LBB47_2: ; RV32I-NEXT: ret ; -; RV64I-LABEL: zext_nneg_dominating_icmp_i32: -; RV64I: # %bb.0: -; RV64I-NEXT: bltz a0, .LBB47_2 -; RV64I-NEXT: # %bb.1: -; RV64I-NEXT: slli a0, a0, 48 -; RV64I-NEXT: srli a0, a0, 48 -; RV64I-NEXT: tail bar_i32 -; RV64I-NEXT: .LBB47_2: -; RV64I-NEXT: ret -; -; RV64ZBB-LABEL: zext_nneg_dominating_icmp_i32: -; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: bltz a0, .LBB47_2 -; RV64ZBB-NEXT: # %bb.1: -; RV64ZBB-NEXT: zext.h a0, a0 -; RV64ZBB-NEXT: tail bar_i32 -; RV64ZBB-NEXT: .LBB47_2: -; RV64ZBB-NEXT: ret +; RV64-LABEL: zext_nneg_dominating_icmp_i32: +; RV64: # %bb.0: +; RV64-NEXT: bltz a0, .LBB47_2 +; RV64-NEXT: # %bb.1: +; RV64-NEXT: tail bar_i32 +; RV64-NEXT: .LBB47_2: +; RV64-NEXT: ret %2 = icmp sgt i16 %0, -1 br i1 %2, label %3, label %5 @@ -834,24 +823,13 @@ define void @zext_nneg_dominating_icmp_i32_signext(i16 signext %0) { ; RV32I-NEXT: .LBB48_2: ; RV32I-NEXT: ret ; -; RV64I-LABEL: zext_nneg_dominating_icmp_i32_signext: -; RV64I: # %bb.0: -; RV64I-NEXT: bltz a0, .LBB48_2 -; RV64I-NEXT: # %bb.1: -; RV64I-NEXT: slli a0, a0, 48 -; RV64I-NEXT: srli a0, a0, 48 -; RV64I-NEXT: tail bar_i32 -; RV64I-NEXT: .LBB48_2: -; RV64I-NEXT: ret -; -; RV64ZBB-LABEL: zext_nneg_dominating_icmp_i32_signext: -; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: bltz a0, .LBB48_2 -; RV64ZBB-NEXT: # %bb.1: -; RV64ZBB-NEXT: zext.h a0, a0 -; RV64ZBB-NEXT: tail bar_i32 -; RV64ZBB-NEXT: .LBB48_2: -; RV64ZBB-NEXT: ret +; RV64-LABEL: zext_nneg_dominating_icmp_i32_signext: +; RV64: # %bb.0: +; RV64-NEXT: bltz a0, .LBB48_2 +; RV64-NEXT: # %bb.1: +; RV64-NEXT: tail bar_i32 +; RV64-NEXT: .LBB48_2: +; RV64-NEXT: ret %2 = icmp sgt i16 %0, -1 br i1 %2, label %3, label %5 @@ -875,24 +853,13 @@ define void @zext_nneg_dominating_icmp_i32_zeroext(i16 signext %0) { ; RV32I-NEXT: .LBB49_2: ; RV32I-NEXT: ret ; -; RV64I-LABEL: zext_nneg_dominating_icmp_i32_zeroext: -; RV64I: # %bb.0: -; RV64I-NEXT: bltz a0, .LBB49_2 -; RV64I-NEXT: # %bb.1: -; RV64I-NEXT: slli a0, a0, 48 -; RV64I-NEXT: srli a0, a0, 48 -; RV64I-NEXT: tail bar_i32 -; RV64I-NEXT: .LBB49_2: -; RV64I-NEXT: ret -; -; RV64ZBB-LABEL: zext_nneg_dominating_icmp_i32_zeroext: -; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: bltz a0, .LBB49_2 -; RV64ZBB-NEXT: # %bb.1: -; RV64ZBB-NEXT: zext.h a0, a0 -; RV64ZBB-NEXT: tail bar_i32 -; RV64ZBB-NEXT: .LBB49_2: -; RV64ZBB-NEXT: ret +; RV64-LABEL: zext_nneg_dominating_icmp_i32_zeroext: +; RV64: # %bb.0: +; RV64-NEXT: bltz a0, .LBB49_2 +; RV64-NEXT: # %bb.1: +; RV64-NEXT: tail bar_i32 +; RV64-NEXT: .LBB49_2: +; RV64-NEXT: ret %2 = icmp sgt i16 %0, -1 br i1 %2, label %3, label %5 |