Index: llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerCombiner.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerCombiner.h +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/LegalizerCombiner.h @@ -41,9 +41,7 @@ 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; @@ -68,9 +66,7 @@ // 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; @@ -97,9 +93,7 @@ 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; @@ -175,17 +169,14 @@ 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 &DeadInsts) { switch (MI.getOpcode()) { @@ -201,6 +192,16 @@ 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 &DeadInsts) { + DeadInsts.push_back(&MI); + if (MRI.hasOneUse(DefMI.getOperand(0).getReg())) + DeadInsts.push_back(&DefMI); + } }; } // namespace llvm Index: llvm/trunk/test/CodeGen/AArch64/GlobalISel/combine-anyext-crash.mir =================================================================== --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/combine-anyext-crash.mir +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/combine-anyext-crash.mir @@ -0,0 +1,42 @@ +# 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 + +...