diff --git a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp --- a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp @@ -123,9 +123,9 @@ // There is an address given by an offset OffSCEV from AASCEV which has an // alignment AlignSCEV. Use that information, if possible, to compute a new // alignment for Ptr. -static unsigned getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV, - const SCEV *OffSCEV, Value *Ptr, - ScalarEvolution *SE) { +static Align getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV, + const SCEV *OffSCEV, Value *Ptr, + ScalarEvolution *SE) { const SCEV *PtrSCEV = SE->getSCEV(Ptr); // On a platform with 32-bit allocas, but 64-bit flat/global pointer sizes // (*cough* AMDGPU), the effective SCEV type of AASCEV and PtrSCEV @@ -146,13 +146,12 @@ << *AlignSCEV << " and offset " << *OffSCEV << " using diff " << *DiffSCEV << "\n"); - unsigned NewAlignment = getNewAlignmentDiff(DiffSCEV, AlignSCEV, SE); - LLVM_DEBUG(dbgs() << "\tnew alignment: " << NewAlignment << "\n"); + if (unsigned NewAlignment = getNewAlignmentDiff(DiffSCEV, AlignSCEV, SE)) { + LLVM_DEBUG(dbgs() << "\tnew alignment: " << NewAlignment << "\n"); + return Align(NewAlignment); + } - if (NewAlignment) { - return NewAlignment; - } else if (const SCEVAddRecExpr *DiffARSCEV = - dyn_cast(DiffSCEV)) { + if (const SCEVAddRecExpr *DiffARSCEV = dyn_cast(DiffSCEV)) { // The relative offset to the alignment assumption did not yield a constant, // but we should try harder: if we assume that a is 32-byte aligned, then in // for (i = 0; i < 1024; i += 4) r += a[i]; not all of the loads from a are @@ -170,34 +169,33 @@ // first iteration, and also the alignment using the per-iteration delta. // If these are the same, then use that answer. Otherwise, use the smaller // one, but only if it divides the larger one. - NewAlignment = getNewAlignmentDiff(DiffStartSCEV, AlignSCEV, SE); + unsigned NewAlignment = getNewAlignmentDiff(DiffStartSCEV, AlignSCEV, SE); unsigned NewIncAlignment = getNewAlignmentDiff(DiffIncSCEV, AlignSCEV, SE); LLVM_DEBUG(dbgs() << "\tnew start alignment: " << NewAlignment << "\n"); LLVM_DEBUG(dbgs() << "\tnew inc alignment: " << NewIncAlignment << "\n"); if (!NewAlignment || !NewIncAlignment) { - return 0; - } else if (NewAlignment > NewIncAlignment) { - if (NewAlignment % NewIncAlignment == 0) { - LLVM_DEBUG(dbgs() << "\tnew start/inc alignment: " << NewIncAlignment - << "\n"); - return NewIncAlignment; - } - } else if (NewIncAlignment > NewAlignment) { - if (NewIncAlignment % NewAlignment == 0) { - LLVM_DEBUG(dbgs() << "\tnew start/inc alignment: " << NewAlignment - << "\n"); - return NewAlignment; - } - } else if (NewIncAlignment == NewAlignment) { + return Align(1); + } + assert(isPowerOf2_64(NewAlignment) && "valid alignment"); + assert(isPowerOf2_64(NewIncAlignment) && "valid alignment"); + if (NewAlignment > NewIncAlignment) { + LLVM_DEBUG(dbgs() << "\tnew start/inc alignment: " << NewIncAlignment + << "\n"); + return Align(NewIncAlignment); + } + if (NewIncAlignment > NewAlignment) { LLVM_DEBUG(dbgs() << "\tnew start/inc alignment: " << NewAlignment << "\n"); - return NewAlignment; + return Align(NewAlignment); } + assert(NewIncAlignment == NewAlignment); + LLVM_DEBUG(dbgs() << "\tnew start/inc alignment: " << NewAlignment << "\n"); + return Align(NewAlignment); } - return 0; + return Align(1); } bool AlignmentFromAssumptionsPass::extractAlignmentInfo(CallInst *I, @@ -321,29 +319,29 @@ while (!WorkList.empty()) { Instruction *J = WorkList.pop_back_val(); - if (LoadInst *LI = dyn_cast(J)) { - unsigned NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, - LI->getPointerOperand(), SE); + Align NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, + LI->getPointerOperand(), SE); - if (NewAlignment > LI->getAlignment()) { - LI->setAlignment(MaybeAlign(NewAlignment)); + if (NewAlignment > *LI->getAlign()) { + LI->setAlignment(NewAlignment); ++NumLoadAlignChanged; } } else if (StoreInst *SI = dyn_cast(J)) { - unsigned NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, - SI->getPointerOperand(), SE); + Align NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, + SI->getPointerOperand(), SE); - if (NewAlignment > SI->getAlignment()) { - SI->setAlignment(MaybeAlign(NewAlignment)); + if (NewAlignment > *SI->getAlign()) { + SI->setAlignment(NewAlignment); ++NumStoreAlignChanged; } } else if (MemIntrinsic *MI = dyn_cast(J)) { - unsigned NewDestAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, - MI->getDest(), SE); + Align NewDestAlignment = + getNewAlignment(AASCEV, AlignSCEV, OffSCEV, MI->getDest(), SE); - LLVM_DEBUG(dbgs() << "\tmem inst: " << NewDestAlignment << "\n";); - if (NewDestAlignment > MI->getDestAlignment()) { + LLVM_DEBUG(dbgs() << "\tmem inst: " << DebugStr(NewDestAlignment) + << "\n";); + if (NewDestAlignment > *MI->getDestAlign()) { MI->setDestAlignment(NewDestAlignment); ++NumMemIntAlignChanged; } @@ -351,12 +349,13 @@ // For memory transfers, there is also a source alignment that // can be set. if (MemTransferInst *MTI = dyn_cast(MI)) { - unsigned NewSrcAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, - MTI->getSource(), SE); + Align NewSrcAlignment = + getNewAlignment(AASCEV, AlignSCEV, OffSCEV, MTI->getSource(), SE); - LLVM_DEBUG(dbgs() << "\tmem trans: " << NewSrcAlignment << "\n";); + LLVM_DEBUG(dbgs() << "\tmem trans: " << DebugStr(NewSrcAlignment) + << "\n";); - if (NewSrcAlignment > MTI->getSourceAlignment()) { + if (NewSrcAlignment > *MTI->getSourceAlign()) { MTI->setSourceAlignment(NewSrcAlignment); ++NumMemIntAlignChanged; }