diff --git a/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp b/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp --- a/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp +++ b/llvm/lib/Target/AArch64/AArch64RedundantCopyElimination.cpp @@ -400,21 +400,21 @@ if (KnownReg.Imm != SrcImm) continue; - // Don't remove a move immediate that implicitly defines the upper - // bits when only the lower 32 bits are known. - MCPhysReg CmpReg = KnownReg.Reg; - if (any_of(MI->implicit_operands(), [CmpReg](MachineOperand &O) { - return !O.isDead() && O.isReg() && O.isDef() && - O.getReg() != CmpReg; - })) - continue; - // Don't remove a move immediate that implicitly defines the upper // bits as different. if (TRI->isSuperRegister(DefReg, KnownReg.Reg) && KnownReg.Imm < 0) continue; } + // Don't remove a move immediate or a copy that implicitly defines the + // upper bits when only the lower 32 bits are known. + MCPhysReg CmpReg = KnownReg.Reg; + if (any_of(MI->implicit_operands(), [CmpReg](MachineOperand &O) { + return !O.isDead() && O.isReg() && O.isDef() && + O.getReg() != CmpReg; + })) + continue; + if (IsCopy) LLVM_DEBUG(dbgs() << "Remove redundant Copy : " << *MI); else diff --git a/llvm/test/CodeGen/AArch64/machine-copy-remove.mir b/llvm/test/CodeGen/AArch64/machine-copy-remove.mir --- a/llvm/test/CodeGen/AArch64/machine-copy-remove.mir +++ b/llvm/test/CodeGen/AArch64/machine-copy-remove.mir @@ -608,3 +608,57 @@ bb.2: RET_ReallyLR +... +# Check that we don't remove a COPY that is implicitly defining the upper +# 32 bits of an X reg if we don't know the upper 32 bits are zero. +# CHECK-LABEL: name: test24 +# CHECK: COPY $wzr +name: test24 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0, $x1, $w0 + + $x0 = COPY $x1 + CBNZW $w0, %bb.2 + + bb.1: + $w0 = COPY $wzr, implicit-def $x0 + B %bb.3 + + bb.2: + liveins: $x1 + + $x0 = LDRXui $x1, 0 + + bb.3: + liveins: $x0 + + RET_ReallyLR implicit $x0 +... +# Check that we do remove a COPY that is implicitly defining the upper +# 32 bits of an X reg if we know the upper 32 bits are zero. +# CHECK-LABEL: name: test25 +# CHECK-NOT: COPY $wzr +name: test25 +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0, $x1, $w0 + + $x0 = COPY $x1 + CBNZX $x0, %bb.2 + + bb.1: + $w0 = COPY $wzr, implicit-def $x0 + B %bb.3 + + bb.2: + liveins: $x1 + + $x0 = LDRXui $x1, 0 + + bb.3: + liveins: $x0 + + RET_ReallyLR implicit $x0