Index: lib/CodeGen/OptimizePHIs.cpp =================================================================== --- lib/CodeGen/OptimizePHIs.cpp +++ lib/CodeGen/OptimizePHIs.cpp @@ -119,8 +119,16 @@ if (SrcMI && SrcMI->isCopy() && !SrcMI->getOperand(0).getSubReg() && !SrcMI->getOperand(1).getSubReg() && - TargetRegisterInfo::isVirtualRegister(SrcMI->getOperand(1).getReg())) - SrcMI = MRI->getVRegDef(SrcMI->getOperand(1).getReg()); + TargetRegisterInfo::isVirtualRegister(SrcMI->getOperand(1).getReg())) { + if (MI->getOperand(i+1).getMBB() == SrcMI->getParent()) { + // If the copy instr is in the predecessor BB (almost always for PHI + // reg operands), try to propagate copy's operand. + SrcReg = SrcMI->getOperand(1).getReg(); + SrcMI = MRI->getVRegDef(SrcReg); + } else { + SrcMI = MRI->getVRegDef(SrcMI->getOperand(1).getReg()); + } + } if (!SrcMI) return false; @@ -129,7 +137,7 @@ return false; } else { // Fail if there is more than one non-phi/non-move register. - if (SingleValReg != 0) + if (SingleValReg != 0 && SingleValReg != SrcReg) return false; SingleValReg = SrcReg; } @@ -180,6 +188,9 @@ if (!MRI->constrainRegClass(SingleValReg, MRI->getRegClass(OldReg))) continue; + // for the case SingleValReg taken from copy instr + MRI->clearKillFlags(SingleValReg); + MRI->replaceRegWith(OldReg, SingleValReg); MI->eraseFromParent(); ++NumPHICycles; Index: test/CodeGen/X86/madd.ll =================================================================== --- test/CodeGen/X86/madd.ll +++ test/CodeGen/X86/madd.ll @@ -427,8 +427,7 @@ ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 ; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm2 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm6 -; AVX1-NEXT: vpaddd %xmm6, %xmm2, %xmm2 +; AVX1-NEXT: vpaddd %xmm5, %xmm2, %xmm2 ; AVX1-NEXT: vpaddd %xmm2, %xmm5, %xmm2 ; AVX1-NEXT: vpaddd %xmm2, %xmm4, %xmm2 ; AVX1-NEXT: vpaddd %xmm3, %xmm0, %xmm0 @@ -1036,8 +1035,7 @@ ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm4 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 ; AVX1-NEXT: vextractf128 $1, %ymm2, %xmm2 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm6 -; AVX1-NEXT: vpaddd %xmm6, %xmm2, %xmm2 +; AVX1-NEXT: vpaddd %xmm5, %xmm2, %xmm2 ; AVX1-NEXT: vpaddd %xmm2, %xmm5, %xmm2 ; AVX1-NEXT: vpaddd %xmm2, %xmm4, %xmm2 ; AVX1-NEXT: vpaddd %xmm3, %xmm0, %xmm0 Index: test/CodeGen/X86/opt_phis2.mir =================================================================== --- /dev/null +++ test/CodeGen/X86/opt_phis2.mir @@ -0,0 +1,98 @@ +# RUN: llc -run-pass opt-phis -march=x86-64 -o - %s | FileCheck %s +# All PHIs should be removed since they can be securely replaced +# by %8 register. +# CHECK-NOT: PHI +--- | + define void @test() { + ret void + } +... +--- +name: test +alignment: 4 +tracksRegLiveness: true +registers: + - { id: 0, class: vr256, preferred-register: '' } + - { id: 1, class: vr256, preferred-register: '' } + - { id: 2, class: vr256, preferred-register: '' } + - { id: 3, class: vr256, preferred-register: '' } + - { id: 4, class: vr256, preferred-register: '' } + - { id: 5, class: vr256, preferred-register: '' } + - { id: 6, class: vr256, preferred-register: '' } + - { id: 7, class: gr32, preferred-register: '' } + - { id: 8, class: vr256, preferred-register: '' } + - { id: 9, class: gr64, preferred-register: '' } + - { id: 10, class: gr64_nosp, preferred-register: '' } + - { id: 11, class: gr32, preferred-register: '' } + - { id: 12, class: gr32, preferred-register: '' } + - { id: 13, class: gr32, preferred-register: '' } + - { id: 14, class: gr32, preferred-register: '' } + - { id: 15, class: gr32, preferred-register: '' } + - { id: 16, class: gr32, preferred-register: '' } + - { id: 17, class: vr128, preferred-register: '' } + - { id: 18, class: vr128, preferred-register: '' } + - { id: 19, class: vr128, preferred-register: '' } + - { id: 20, class: vr128, preferred-register: '' } +liveins: + - { reg: '$edi', virtual-reg: '%7' } + - { reg: '$ymm0', virtual-reg: '%8' } + - { reg: '$rsi', virtual-reg: '%9' } +jumpTable: + kind: block-address + entries: + - id: 0 + blocks: [ '%bb.3', '%bb.2', '%bb.1', '%bb.4' ] +body: | + bb.0: + liveins: $edi, $ymm0, $rsi + + %9:gr64 = COPY $rsi + %8:vr256 = COPY $ymm0 + %7:gr32 = COPY $edi + %11:gr32 = SAR32ri %7, 31, implicit-def dead $eflags + %12:gr32 = SHR32ri %11, 30, implicit-def dead $eflags + %13:gr32 = ADD32rr %7, killed %12, implicit-def dead $eflags + %14:gr32 = AND32ri8 %13, -4, implicit-def dead $eflags + %15:gr32 = SUB32rr %7, %14, implicit-def dead $eflags + %10:gr64_nosp = SUBREG_TO_REG 0, %15, %subreg.sub_32bit + %16:gr32 = SUB32ri8 %15, 3, implicit-def $eflags + JA_1 %bb.8, implicit $eflags + + bb.9: + JMP64m $noreg, 8, %10, %jump-table.0, $noreg :: (load 8 from jump-table) + + bb.1: + %0:vr256 = COPY %8 + JMP_1 %bb.5 + + bb.2: + %1:vr256 = COPY %8 + JMP_1 %bb.6 + + bb.3: + %2:vr256 = COPY %8 + JMP_1 %bb.7 + + bb.4: + %3:vr256 = COPY %8 + %17:vr128 = VEXTRACTF128rr %8, 1 + VPEXTRDmr %9, 1, $noreg, 12, $noreg, killed %17, 2 + + bb.5: + %4:vr256 = PHI %0, %bb.1, %3, %bb.4 + %18:vr128 = VEXTRACTF128rr %4, 1 + VPEXTRDmr %9, 1, $noreg, 8, $noreg, killed %18, 1 + + bb.6: + %5:vr256 = PHI %1, %bb.2, %4, %bb.5 + %19:vr128 = VEXTRACTF128rr %5, 1 + VMOVPDI2DImr %9, 1, $noreg, 4, $noreg, killed %19 + + bb.7: + %6:vr256 = PHI %2, %bb.3, %5, %bb.6 + %20:vr128 = COPY %6.sub_xmm + VPEXTRDmr %9, 1, $noreg, 0, $noreg, killed %20, 3 + + bb.8: + RET 0 +... Index: test/CodeGen/X86/sad.ll =================================================================== --- test/CodeGen/X86/sad.ll +++ test/CodeGen/X86/sad.ll @@ -307,9 +307,7 @@ ; AVX1-NEXT: vpaddd %xmm0, %xmm0, %xmm2 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm4 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm5 -; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm6 -; AVX1-NEXT: vpaddd %xmm6, %xmm5, %xmm5 +; AVX1-NEXT: vpaddd %xmm4, %xmm4, %xmm5 ; AVX1-NEXT: vpaddd %xmm5, %xmm4, %xmm4 ; AVX1-NEXT: vpaddd %xmm4, %xmm3, %xmm3 ; AVX1-NEXT: vpaddd %xmm2, %xmm0, %xmm0