Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -2686,7 +2686,10 @@ Indexes->getInstructionFromIndex(Def)->operands()) { if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) { if (MO.getSubReg() != 0) - MO.setIsUndef(EraseImpDef); + // Only set undef on the MO if we can't find any reaching + // definition of the value. If it does exist and we set undef on + // the MO we will effectively kill the reaching definition. + MO.setIsUndef(EraseImpDef && !LR.getVNInfoBefore(Def)); MO.setIsDead(false); } } Index: test/CodeGen/MIR/X86/simple-register-allocation-read-undef.mir =================================================================== --- /dev/null +++ test/CodeGen/MIR/X86/simple-register-allocation-read-undef.mir @@ -0,0 +1,40 @@ +# RUN: llc -mtriple=x86_64-- %s -o - -run-pass=simple-register-coalescing | FileCheck %s +--- +name: f +registers: + - { id: 0, class: gr64 } + - { id: 1, class: gr64_with_sub_8bit } + - { id: 2, class: vr128 } + - { id: 3, class: vr128 } + - { id: 4, class: vr128 } +body: | + bb.0: + JB_1 %bb.2, undef implicit killed %eflags + JMP_1 %bb.1 + + bb.1: + + %0 = IMPLICIT_DEF + undef %1.sub_32bit = MOV32r0 implicit-def %eflags + %1.sub_16bit = MOV16ri 3 + JMP_1 %bb.3 + + bb.2: + + %0 = MOVPQIto64rr undef %2 + %1 = COPY %0 + + bb.3: + + %3 = MOV64toPQIrr killed %0 + %4 = MOV64toPQIrr killed %1 + +... + +# We should have a setting of both sub_32bit and sub_16bit. The first one +# should be undef and not dead, and the second should not be undef. + +# CHECK-NOT: dead +# CHECK: undef [[TMP:%[0-1]+]].sub_32bit = MOV32r0 +# CHECK-NOT: undef +# CHECK: [[TMP]].sub_16bit = MOV16ri