diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -2597,6 +2597,13 @@ return true; return false; }; + + // We are trying to replace the ImmOpNo with ScaleReg. Give up if it is + // treated as special zero when ScaleReg is R0/X0 register. + if (III.ZeroIsSpecialOrig == III.ImmOpNo && + (ScaleReg == PPC::R0 || ScaleReg == PPC::X0)) + return false; + // Make sure no other def for ToBeChangedReg and ScaleReg between ADD Instr // and Imm Instr. if (NewDefFor(ToBeChangedReg, *ADDMI, MI) || NewDefFor(ScaleReg, *ADDMI, MI)) diff --git a/llvm/test/CodeGen/PowerPC/fold-frame-offset-using-rr.mir b/llvm/test/CodeGen/PowerPC/fold-frame-offset-using-rr.mir --- a/llvm/test/CodeGen/PowerPC/fold-frame-offset-using-rr.mir +++ b/llvm/test/CodeGen/PowerPC/fold-frame-offset-using-rr.mir @@ -152,3 +152,16 @@ ; CHECK: $x6 = LD 4, killed $x4 BLR8 implicit $lr8, implicit $rm ... +--- +name: testR0 +# Give up the folding if the register is R0/X0 +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $f1, $x0, $x3 + $x4 = ADDI8 killed $x3, -8 + $x4 = ADD8 killed $x4, $x0 + STFD killed $f1, -8, killed $x4 + ; CHECK-NOT: STFDX + BLR8 implicit $lr8, implicit $rm +...