Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -14341,6 +14341,13 @@ MaybePoisonOperand); } } + // Early-out if the node has already been updated in place. + if(N0.getOpcode() == ISD::DELETED_NODE) + return SDValue(); + + // The whole node may have been updated, so the value we were holding + // may no longer be valid. Re-fetch the operand we're `freeze`ing. + N0 = N->getOperand(0); // Finally, recreate the node, it's operands were updated to use // frozen operands, so we just need to use it's "original" operands. Index: llvm/test/CodeGen/AArch64/dagcombine-deleted-freeze.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/dagcombine-deleted-freeze.ll @@ -0,0 +1,15 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=aarch64 | FileCheck %s +define i8 @f(i64 %0) { +; CHECK-LABEL: f: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w0, wzr +; CHECK-NEXT: ret + %2 = freeze i64 %0 + %3 = trunc i64 %2 to i1 + %4 = trunc i64 %0 to i1 + %5 = xor i1 %3, %4 + %6 = freeze i1 %5 + %7 = zext i1 %6 to i8 + ret i8 %7 +}