diff --git a/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp b/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp --- a/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp +++ b/llvm/lib/Target/PowerPC/PPCLoopInstrFormPrep.cpp @@ -534,13 +534,6 @@ return MadeChange; } - // Now we only handle update form for constant increment. - // FIXME: add support for non-constant increment UpdateForm. - if (!IsConstantInc && Form == UpdateForm) { - LLVM_DEBUG(dbgs() << "not a constant incresement for update form!\n"); - return MadeChange; - } - // For some DS form load/store instructions, it can also be an update form, // if the stride is a multipler of 4. Use update form if prefer it. bool CanPreInc = @@ -548,10 +541,13 @@ ((Form == DSForm) && IsConstantInc && !BasePtrIncConstantSCEV->getAPInt().urem(4) && PreferUpdateForm)); const SCEV *BasePtrStartSCEV = nullptr; - if (CanPreInc) - BasePtrStartSCEV = - SE->getMinusSCEV(BasePtrSCEV->getStart(), BasePtrIncConstantSCEV); - else + if (CanPreInc) { + assert(SE->isLoopInvariant(BasePtrIncSCEV, L) && + "Increment is not loop invariant!\n"); + BasePtrStartSCEV = SE->getMinusSCEV(BasePtrSCEV->getStart(), + IsConstantInc ? BasePtrIncConstantSCEV + : BasePtrIncSCEV); + } else BasePtrStartSCEV = BasePtrSCEV->getStart(); if (!isSafeToExpand(BasePtrStartSCEV, *SE)) @@ -589,12 +585,10 @@ Instruction *PtrInc = nullptr; Instruction *NewBasePtr = nullptr; if (CanPreInc) { - assert(BasePtrIncConstantSCEV && - "update form now only supports constant increment."); Instruction *InsPoint = &*Header->getFirstInsertionPt(); - PtrInc = GetElementPtrInst::Create( - I8Ty, NewPHI, BasePtrIncConstantSCEV->getValue(), - getInstrName(MemI, GEPNodeIncNameSuffix), InsPoint); + PtrInc = GetElementPtrInst::Create(I8Ty, NewPHI, IncNode, + getInstrName(MemI, GEPNodeIncNameSuffix), + InsPoint); cast(PtrInc)->setIsInBounds(IsPtrInBounds(BasePtr)); for (auto PI : predecessors(Header)) { if (PI == LoopPredecessor) diff --git a/llvm/test/CodeGen/PowerPC/loop-instr-prep-non-const-increasement.ll b/llvm/test/CodeGen/PowerPC/loop-instr-prep-non-const-increasement.ll --- a/llvm/test/CodeGen/PowerPC/loop-instr-prep-non-const-increasement.ll +++ b/llvm/test/CodeGen/PowerPC/loop-instr-prep-non-const-increasement.ll @@ -19,18 +19,18 @@ ; CHECK-NEXT: cmpwi r4, 1 ; CHECK-NEXT: blt cr0, .LBB0_4 ; CHECK-NEXT: # %bb.1: # %for.body.preheader +; CHECK-NEXT: extsw r5, r5 +; CHECK-NEXT: sub r3, r3, r5 ; CHECK-NEXT: addi r6, r3, 5 ; CHECK-NEXT: clrldi r3, r4, 32 -; CHECK-NEXT: extsw r5, r5 ; CHECK-NEXT: mtctr r3 ; CHECK-NEXT: li r3, 0 ; CHECK-NEXT: .p2align 5 ; CHECK-NEXT: .LBB0_2: # %for.body ; CHECK-NEXT: # -; CHECK-NEXT: ld r4, 0(r6) +; CHECK-NEXT: ldux r4, r6, r5 ; CHECK-NEXT: add r3, r4, r3 ; CHECK-NEXT: ld r4, 4(r6) -; CHECK-NEXT: add r6, r6, r5 ; CHECK-NEXT: add r3, r3, r4 ; CHECK-NEXT: bdnz .LBB0_2 ; CHECK-NEXT: # %bb.3: # %for.cond.cleanup @@ -85,18 +85,17 @@ ; CHECK-NEXT: cmpwi r4, 1 ; CHECK-NEXT: blt cr0, .LBB1_4 ; CHECK-NEXT: # %bb.1: # %for.body.preheader +; CHECK-NEXT: extsw r5, r5 +; CHECK-NEXT: sub r3, r3, r5 ; CHECK-NEXT: addi r6, r3, 1000 ; CHECK-NEXT: clrldi r3, r4, 32 -; CHECK-NEXT: extsw r5, r5 -; CHECK-NEXT: li r4, 0 ; CHECK-NEXT: mtctr r3 ; CHECK-NEXT: li r3, 0 ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: .LBB1_2: # %for.body ; CHECK-NEXT: # -; CHECK-NEXT: lbzx r7, r6, r4 -; CHECK-NEXT: add r4, r4, r5 -; CHECK-NEXT: add r3, r7, r3 +; CHECK-NEXT: lbzux r4, r6, r5 +; CHECK-NEXT: add r3, r4, r3 ; CHECK-NEXT: bdnz .LBB1_2 ; CHECK-NEXT: # %bb.3: # %for.cond.cleanup ; CHECK-NEXT: clrldi r3, r3, 56