Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10730,8 +10730,18 @@ (!LegalOperations || (TLI.isOperationLegal(ISD::ZERO_EXTEND, VT) && TLI.isOperationLegal(ISD::ADD, VT)))) { // If we can eliminate the 'not', the sext form should be better - if (SDValue NewXor = visitXOR(N0.getNode())) - return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, NewXor); + if (SDValue NewXor = visitXOR(N0.getNode())) { + // Returning N0 is a form of in-visit replacement that may have + // invalidated N0. + if (NewXor.getNode() == N0.getNode()) { + // Return SDValue here as the xor should have already been replaced in + // this sext. + return SDValue(); + } else { + // Return a new sext with the new xor. + return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, NewXor); + } + } SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0)); return DAG.getNode(ISD::ADD, DL, VT, Zext, DAG.getAllOnesConstant(DL, VT)); Index: llvm/test/CodeGen/SystemZ/sext-zext.ll =================================================================== --- llvm/test/CodeGen/SystemZ/sext-zext.ll +++ llvm/test/CodeGen/SystemZ/sext-zext.ll @@ -28,6 +28,25 @@ ret i32 %sext } +;; fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc)) +;; make sure we don't crash if the not gets replaced in-visit +define i32 @sext_of_not_fsetccs(double %x) { +; CHECK-LABEL: sext_of_not_fsetccs: +; CHECK: # %bb.0: +; CHECK-NEXT: ltdbr %f0, %f0 +; CHECK-NEXT: ipm %r0 +; CHECK-NEXT: afi %r0, 1879048192 +; CHECK-NEXT: srl %r0, 31 +; CHECK-NEXT: lcr %r2, %r0 +; CHECK-NEXT: br %r14 + %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %x, double 0.000000e+00, metadata !"oeq", metadata !"fpexcept.ignore") + %xor = xor i1 %cmp, 1 + %sext = sext i1 %xor to i32 + ret i32 %sext +} + +declare i1 @llvm.experimental.constrained.fcmp.f64(double, double, metadata, metadata) + ;; TODO: fold (add (zext (setcc a, b, cc)), -1) -> (sext (setcc a, b, !cc)) define i32 @dec_of_zexted_cmp(i32 %x) { ; CHECK-LABEL: dec_of_zexted_cmp: