Builder.setInstr(MI);
// We get a copy/trunc/extend depending on the sizes
Builder.buildAnyExtOrTrunc(DstReg, SrcReg);
- MI.eraseFromParent();
- if (MRI.use_empty(DefMI->getOperand(0).getReg()))
- DeadInsts.push_back(DefMI);
+ markInstAndDefDead(MI, *DefMI, DeadInsts);
return true;
}
return false;
// We get a copy/trunc/extend depending on the sizes
auto SrcCopyOrTrunc = Builder.buildAnyExtOrTrunc(DstTy, TruncSrc);
Builder.buildAnd(DstReg, SrcCopyOrTrunc, MaskCstMIB);
- MI.eraseFromParent();
- if (MRI.use_empty(DefMI->getOperand(0).getReg()))
- DeadInsts.push_back(DefMI);
+ markInstAndDefDead(MI, *DefMI, DeadInsts);
return true;
}
return false;
auto ShlMIB = Builder.buildInstr(TargetOpcode::G_SHL, DstTy,
SrcCopyExtOrTrunc, SizeDiffMIB);
Builder.buildInstr(TargetOpcode::G_ASHR, DstReg, ShlMIB, SizeDiffMIB);
- MI.eraseFromParent();
- if (MRI.use_empty(DefMI->getOperand(0).getReg()))
- DeadInsts.push_back(DefMI);
+ markInstAndDefDead(MI, *DefMI, DeadInsts);
return true;
}
return false;
MergeI->getOperand(Idx + 1).getReg());
}
- MI.eraseFromParent();
- if (MRI.use_empty(MergeI->getOperand(0).getReg()))
- DeadInsts.push_back(MergeI);
+ markInstAndDefDead(MI, *MergeI, DeadInsts);
return true;
}
/// Try to combine away MI.
/// Returns true if it combined away the MI.
- /// Caller should not rely in MI existing as it may be deleted.
/// Adds instructions that are dead as a result of the combine
- // into DeadInsts
+ /// into DeadInsts, which can include MI.
bool tryCombineInstruction(MachineInstr &MI,
SmallVectorImpl<MachineInstr *> &DeadInsts) {
switch (MI.getOpcode()) {
return tryCombineMerges(MI, DeadInsts);
}
}
+
+private:
+ /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
+ /// dead due to MI being killed, then mark DefMI as dead too.
+ void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI,
+ SmallVectorImpl<MachineInstr *> &DeadInsts) {
+ DeadInsts.push_back(&MI);
+ if (MRI.hasOneUse(DefMI.getOperand(0).getReg()))
+ DeadInsts.push_back(&DefMI);
+ }
};
} // namespace llvm
--- /dev/null
+# RUN: llc -O0 -run-pass=legalizer -global-isel %s -o - | FileCheck %s
+--- |
+ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64--"
+
+ define void @test_anyext_crash() {
+ entry:
+ br label %block2
+
+ block2:
+ %0 = trunc i16 0 to i8
+ %1 = uitofp i8 %0 to double
+ br label %block2
+ }
+
+
+...
+---
+name: test_anyext_crash
+alignment: 2
+legalized: false
+registers:
+ - { id: 0, class: _, preferred-register: '' }
+ - { id: 1, class: _, preferred-register: '' }
+ - { id: 2, class: _, preferred-register: '' }
+body: |
+ bb.1:
+ ; Check we don't crash due to trying to legalize a dead instruction.
+ ; CHECK-LABEL: test_anyext_crash
+ ; CHECK-LABEL: bb.1:
+ successors: %bb.2
+
+ %0(s16) = G_CONSTANT i16 0
+
+ bb.2:
+ successors: %bb.2
+
+ %1(s8) = G_TRUNC %0(s16)
+ %2(s64) = G_UITOFP %1(s8)
+ G_BR %bb.2
+
+...