diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -1472,7 +1472,7 @@ /// type has the alignment requirement of another type. virtual Align getABIAlignmentForCallingConv(Type *ArgTy, DataLayout DL) const { - return Align(DL.getABITypeAlignment(ArgTy)); + return DL.getABITypeAlign(ArgTy); } /// If true, then instruction selection should seek to shrink the FP constant @@ -2572,7 +2572,7 @@ /// this information should not be provided because it will generate more /// loads. virtual bool hasPairedLoad(EVT /*LoadedType*/, - unsigned & /*RequiredAlignment*/) const { + Align & /*RequiredAlignment*/) const { return false; } diff --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp --- a/llvm/lib/Analysis/Lint.cpp +++ b/llvm/lib/Analysis/Lint.cpp @@ -93,9 +93,8 @@ void visitFunction(Function &F); void visitCallBase(CallBase &CB); - void visitMemoryReference(Instruction &I, Value *Ptr, - uint64_t Size, unsigned Align, - Type *Ty, unsigned Flags); + void visitMemoryReference(Instruction &I, Value *Ptr, uint64_t Size, + MaybeAlign Alignment, Type *Ty, unsigned Flags); void visitEHBeginCatch(IntrinsicInst *II); void visitEHEndCatch(IntrinsicInst *II); @@ -222,7 +221,7 @@ void Lint::visitCallBase(CallBase &I) { Value *Callee = I.getCalledOperand(); - visitMemoryReference(I, Callee, MemoryLocation::UnknownSize, 0, nullptr, + visitMemoryReference(I, Callee, MemoryLocation::UnknownSize, None, nullptr, MemRef::Callee); if (Function *F = dyn_cast(findValue(Callee, @@ -285,7 +284,7 @@ Type *Ty = cast(Formal->getType())->getElementType(); visitMemoryReference(I, Actual, DL->getTypeStoreSize(Ty), - DL->getABITypeAlignment(Ty), Ty, + DL->getABITypeAlign(Ty), Ty, MemRef::Read | MemRef::Write); } } @@ -321,9 +320,9 @@ MemCpyInst *MCI = cast(&I); // TODO: If the size is known, use it. visitMemoryReference(I, MCI->getDest(), MemoryLocation::UnknownSize, - MCI->getDestAlignment(), nullptr, MemRef::Write); + MCI->getDestAlign(), nullptr, MemRef::Write); visitMemoryReference(I, MCI->getSource(), MemoryLocation::UnknownSize, - MCI->getSourceAlignment(), nullptr, MemRef::Read); + MCI->getSourceAlign(), nullptr, MemRef::Read); // Check that the memcpy arguments don't overlap. The AliasAnalysis API // isn't expressive enough for what we really want to do. Known partial @@ -342,10 +341,10 @@ case Intrinsic::memcpy_inline: { MemCpyInlineInst *MCII = cast(&I); const uint64_t Size = MCII->getLength()->getValue().getLimitedValue(); - visitMemoryReference(I, MCII->getDest(), Size, MCII->getDestAlignment(), + visitMemoryReference(I, MCII->getDest(), Size, MCII->getDestAlign(), nullptr, MemRef::Write); - visitMemoryReference(I, MCII->getSource(), Size, - MCII->getSourceAlignment(), nullptr, MemRef::Read); + visitMemoryReference(I, MCII->getSource(), Size, MCII->getSourceAlign(), + nullptr, MemRef::Read); // Check that the memcpy arguments don't overlap. The AliasAnalysis API // isn't expressive enough for what we really want to do. Known partial @@ -359,16 +358,16 @@ MemMoveInst *MMI = cast(&I); // TODO: If the size is known, use it. visitMemoryReference(I, MMI->getDest(), MemoryLocation::UnknownSize, - MMI->getDestAlignment(), nullptr, MemRef::Write); + MMI->getDestAlign(), nullptr, MemRef::Write); visitMemoryReference(I, MMI->getSource(), MemoryLocation::UnknownSize, - MMI->getSourceAlignment(), nullptr, MemRef::Read); + MMI->getSourceAlign(), nullptr, MemRef::Read); break; } case Intrinsic::memset: { MemSetInst *MSI = cast(&I); // TODO: If the size is known, use it. visitMemoryReference(I, MSI->getDest(), MemoryLocation::UnknownSize, - MSI->getDestAlignment(), nullptr, MemRef::Write); + MSI->getDestAlign(), nullptr, MemRef::Write); break; } @@ -378,17 +377,17 @@ &I); visitMemoryReference(I, I.getArgOperand(0), MemoryLocation::UnknownSize, - 0, nullptr, MemRef::Read | MemRef::Write); + None, nullptr, MemRef::Read | MemRef::Write); break; case Intrinsic::vacopy: visitMemoryReference(I, I.getArgOperand(0), MemoryLocation::UnknownSize, - 0, nullptr, MemRef::Write); + None, nullptr, MemRef::Write); visitMemoryReference(I, I.getArgOperand(1), MemoryLocation::UnknownSize, - 0, nullptr, MemRef::Read); + None, nullptr, MemRef::Read); break; case Intrinsic::vaend: visitMemoryReference(I, I.getArgOperand(0), MemoryLocation::UnknownSize, - 0, nullptr, MemRef::Read | MemRef::Write); + None, nullptr, MemRef::Read | MemRef::Write); break; case Intrinsic::stackrestore: @@ -396,7 +395,7 @@ // stack pointer, which the compiler may read from or write to // at any time, so check it for both readability and writeability. visitMemoryReference(I, I.getArgOperand(0), MemoryLocation::UnknownSize, - 0, nullptr, MemRef::Read | MemRef::Write); + None, nullptr, MemRef::Read | MemRef::Write); break; } } @@ -414,9 +413,8 @@ // TODO: Check that the reference is in bounds. // TODO: Check readnone/readonly function attributes. -void Lint::visitMemoryReference(Instruction &I, - Value *Ptr, uint64_t Size, unsigned Align, - Type *Ty, unsigned Flags) { +void Lint::visitMemoryReference(Instruction &I, Value *Ptr, uint64_t Size, + MaybeAlign Align, Type *Ty, unsigned Flags) { // If no memory is being referenced, it doesn't matter if the pointer // is valid. if (Size == 0) @@ -467,15 +465,13 @@ // something we can handle and if so extract the size of this base object // along with its alignment. uint64_t BaseSize = MemoryLocation::UnknownSize; - unsigned BaseAlign = 0; + MaybeAlign BaseAlign; if (AllocaInst *AI = dyn_cast(Base)) { Type *ATy = AI->getAllocatedType(); if (!AI->isArrayAllocation() && ATy->isSized()) BaseSize = DL->getTypeAllocSize(ATy); - BaseAlign = AI->getAlignment(); - if (BaseAlign == 0 && ATy->isSized()) - BaseAlign = DL->getABITypeAlignment(ATy); + BaseAlign = AI->getAlign(); } else if (GlobalVariable *GV = dyn_cast(Base)) { // If the global may be defined differently in another compilation unit // then don't warn about funky memory accesses. @@ -483,9 +479,9 @@ Type *GTy = GV->getValueType(); if (GTy->isSized()) BaseSize = DL->getTypeAllocSize(GTy); - BaseAlign = GV->getAlignment(); - if (BaseAlign == 0 && GTy->isSized()) - BaseAlign = DL->getABITypeAlignment(GTy); + BaseAlign = GV->getAlign(); + if (!BaseAlign && GTy->isSized()) + BaseAlign = DL->getABITypeAlign(GTy); } } @@ -498,24 +494,24 @@ // Accesses that say that the memory is more aligned than it is are not // defined. - if (Align == 0 && Ty && Ty->isSized()) - Align = DL->getABITypeAlignment(Ty); - Assert(!BaseAlign || Align <= MinAlign(BaseAlign, Offset), - "Undefined behavior: Memory reference address is misaligned", &I); + if (!Align && Ty && Ty->isSized()) + Align = DL->getABITypeAlign(Ty); + if (BaseAlign && Align) + Assert(*Align <= commonAlignment(*BaseAlign, Offset), + "Undefined behavior: Memory reference address is misaligned", &I); } } void Lint::visitLoadInst(LoadInst &I) { visitMemoryReference(I, I.getPointerOperand(), - DL->getTypeStoreSize(I.getType()), I.getAlignment(), + DL->getTypeStoreSize(I.getType()), I.getAlign(), I.getType(), MemRef::Read); } void Lint::visitStoreInst(StoreInst &I) { visitMemoryReference(I, I.getPointerOperand(), DL->getTypeStoreSize(I.getOperand(0)->getType()), - I.getAlignment(), - I.getOperand(0)->getType(), MemRef::Write); + I.getAlign(), I.getOperand(0)->getType(), MemRef::Write); } void Lint::visitXor(BinaryOperator &I) { @@ -614,12 +610,12 @@ } void Lint::visitVAArgInst(VAArgInst &I) { - visitMemoryReference(I, I.getOperand(0), MemoryLocation::UnknownSize, 0, + visitMemoryReference(I, I.getOperand(0), MemoryLocation::UnknownSize, None, nullptr, MemRef::Read | MemRef::Write); } void Lint::visitIndirectBrInst(IndirectBrInst &I) { - visitMemoryReference(I, I.getAddress(), MemoryLocation::UnknownSize, 0, + visitMemoryReference(I, I.getAddress(), MemoryLocation::UnknownSize, None, nullptr, MemRef::Branchee); Assert(I.getNumDestinations() != 0, diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11455,14 +11455,14 @@ unsigned LD1Bytes = LD1VT.getStoreSize(); if (ISD::isNON_EXTLoad(LD2) && LD2->hasOneUse() && DAG.areNonVolatileConsecutiveLoads(LD2, LD1, LD1Bytes, 1)) { - unsigned Align = LD1->getAlignment(); - unsigned NewAlign = DAG.getDataLayout().getABITypeAlignment( + Align Alignment = LD1->getAlign(); + Align NewAlign = DAG.getDataLayout().getABITypeAlign( VT.getTypeForEVT(*DAG.getContext())); - if (NewAlign <= Align && + if (NewAlign <= Alignment && (!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT))) return DAG.getLoad(VT, SDLoc(N), LD1->getChain(), LD1->getBasePtr(), - LD1->getPointerInfo(), Align); + LD1->getPointerInfo(), Alignment); } return SDValue(); @@ -15011,11 +15011,11 @@ } /// Get the alignment of the load used for this slice. - unsigned getAlignment() const { - unsigned Alignment = Origin->getAlignment(); + Align getAlign() const { + Align Alignment = Origin->getAlign(); uint64_t Offset = getOffsetFromBase(); if (Offset != 0) - Alignment = MinAlign(Alignment, Alignment + Offset); + Alignment = commonAlignment(Alignment, Alignment.value() + Offset); return Alignment; } @@ -15111,8 +15111,8 @@ // Create the load for the slice. SDValue LastInst = DAG->getLoad(SliceType, SDLoc(Origin), Origin->getChain(), BaseAddr, - Origin->getPointerInfo().getWithOffset(Offset), - getAlignment(), Origin->getMemOperand()->getFlags()); + Origin->getPointerInfo().getWithOffset(Offset), getAlign(), + Origin->getMemOperand()->getFlags()); // If the final type is not the same as the loaded type, this means that // we have to pad with zero. Create a zero extend for that. EVT FinalType = Inst->getValueType(0); @@ -15153,10 +15153,10 @@ // Check if it will be merged with the load. // 1. Check the alignment constraint. - unsigned RequiredAlignment = DAG->getDataLayout().getABITypeAlignment( + Align RequiredAlignment = DAG->getDataLayout().getABITypeAlign( ResVT.getTypeForEVT(*DAG->getContext())); - if (RequiredAlignment > getAlignment()) + if (RequiredAlignment > getAlign()) return false; // 2. Check that the load is a legal operation for that type. @@ -15242,14 +15242,14 @@ continue; // Check if the target supplies paired loads for this type. - unsigned RequiredAlignment = 0; + Align RequiredAlignment; if (!TLI.hasPairedLoad(LoadedType, RequiredAlignment)) { // move to the next pair, this type is hopeless. Second = nullptr; continue; } // Check if we meet the alignment requirement. - if (RequiredAlignment > First->getAlignment()) + if (First->getAlign() < RequiredAlignment) continue; // Check that both loads are next to each other in memory. @@ -15644,9 +15644,9 @@ if (DAG.getDataLayout().isBigEndian()) PtrOff = (BitWidth + 7 - NewBW) / 8 - PtrOff; - unsigned NewAlign = MinAlign(LD->getAlignment(), PtrOff); + Align NewAlign = commonAlignment(LD->getAlign(), PtrOff); Type *NewVTTy = NewVT.getTypeForEVT(*DAG.getContext()); - if (NewAlign < DAG.getDataLayout().getABITypeAlignment(NewVTTy)) + if (NewAlign < DAG.getDataLayout().getABITypeAlign(NewVTTy)) return SDValue(); SDValue NewPtr = DAG.getMemBasePlusOffset(Ptr, PtrOff, SDLoc(LD)); @@ -15699,10 +15699,10 @@ !TLI.isDesirableToTransformToIntegerOp(ISD::STORE, VT)) return SDValue(); - unsigned LDAlign = LD->getAlignment(); - unsigned STAlign = ST->getAlignment(); + Align LDAlign = LD->getAlign(); + Align STAlign = ST->getAlign(); Type *IntVTTy = IntVT.getTypeForEVT(*DAG.getContext()); - unsigned ABIAlign = DAG.getDataLayout().getABITypeAlignment(IntVTTy); + Align ABIAlign = DAG.getDataLayout().getABITypeAlign(IntVTTy); if (LDAlign < ABIAlign || STAlign < ABIAlign) return SDValue(); @@ -16523,10 +16523,10 @@ while (NumConsecutiveStores >= 2 && LoadNodes.size() >= 2) { // If we have load/store pair instructions and we only have two values, // don't bother merging. - unsigned RequiredAlignment; + Align RequiredAlignment; if (LoadNodes.size() == 2 && TLI.hasPairedLoad(MemVT, RequiredAlignment) && - StoreNodes[0].MemNode->getAlignment() >= RequiredAlignment) { + StoreNodes[0].MemNode->getAlign() >= RequiredAlignment) { StoreNodes.erase(StoreNodes.begin(), StoreNodes.begin() + 2); LoadNodes.erase(LoadNodes.begin(), LoadNodes.begin() + 2); break; @@ -17428,11 +17428,12 @@ EVT ResultVT = EVE->getValueType(0); EVT VecEltVT = InVecVT.getVectorElementType(); - unsigned Align = OriginalLoad->getAlignment(); - unsigned NewAlign = DAG.getDataLayout().getABITypeAlignment( + Align Alignment = OriginalLoad->getAlign(); + Align NewAlign = DAG.getDataLayout().getABITypeAlign( VecEltVT.getTypeForEVT(*DAG.getContext())); - if (NewAlign > Align || !TLI.isOperationLegalOrCustom(ISD::LOAD, VecEltVT)) + if (NewAlign > Alignment || + !TLI.isOperationLegalOrCustom(ISD::LOAD, VecEltVT)) return SDValue(); ISD::LoadExtType ExtTy = ResultVT.bitsGT(VecEltVT) ? @@ -17440,7 +17441,7 @@ if (!TLI.shouldReduceLoadWidth(OriginalLoad, ExtTy, VecEltVT)) return SDValue(); - Align = NewAlign; + Alignment = NewAlign; SDValue NewPtr = OriginalLoad->getBasePtr(); SDValue Offset; @@ -17480,13 +17481,13 @@ : ISD::EXTLOAD; Load = DAG.getExtLoad(ExtType, SDLoc(EVE), ResultVT, OriginalLoad->getChain(), NewPtr, MPI, VecEltVT, - Align, OriginalLoad->getMemOperand()->getFlags(), + Alignment, OriginalLoad->getMemOperand()->getFlags(), OriginalLoad->getAAInfo()); Chain = Load.getValue(1); } else { - Load = DAG.getLoad(VecEltVT, SDLoc(EVE), OriginalLoad->getChain(), NewPtr, - MPI, Align, OriginalLoad->getMemOperand()->getFlags(), - OriginalLoad->getAAInfo()); + Load = DAG.getLoad( + VecEltVT, SDLoc(EVE), OriginalLoad->getChain(), NewPtr, MPI, Alignment, + OriginalLoad->getMemOperand()->getFlags(), OriginalLoad->getAAInfo()); Chain = Load.getValue(1); if (ResultVT.bitsLT(VecEltVT)) Load = DAG.getNode(ISD::TRUNCATE, SDLoc(EVE), ResultVT, Load); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -505,7 +505,7 @@ bool shouldSinkOperands(Instruction *I, SmallVectorImpl &Ops) const override; - bool hasPairedLoad(EVT LoadedType, unsigned &RequiredAligment) const override; + bool hasPairedLoad(EVT LoadedType, Align &RequiredAligment) const override; unsigned getMaxSupportedInterleaveFactor() const override { return 4; } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -9250,7 +9250,7 @@ Info.memVT = MVT::getVT(PtrTy->getElementType()); Info.ptrVal = I.getArgOperand(0); Info.offset = 0; - Info.align = MaybeAlign(DL.getABITypeAlignment(PtrTy->getElementType())); + Info.align = DL.getABITypeAlign(PtrTy->getElementType()); Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile; return true; } @@ -9261,7 +9261,7 @@ Info.memVT = MVT::getVT(PtrTy->getElementType()); Info.ptrVal = I.getArgOperand(1); Info.offset = 0; - Info.align = MaybeAlign(DL.getABITypeAlignment(PtrTy->getElementType())); + Info.align = DL.getABITypeAlign(PtrTy->getElementType()); Info.flags = MachineMemOperand::MOStore | MachineMemOperand::MOVolatile; return true; } @@ -9289,7 +9289,7 @@ Info.memVT = MVT::getVT(I.getType()); Info.ptrVal = I.getArgOperand(1); Info.offset = 0; - Info.align = MaybeAlign(DL.getABITypeAlignment(PtrTy->getElementType())); + Info.align = DL.getABITypeAlign(PtrTy->getElementType()); Info.flags = MachineMemOperand::MOLoad; if (Intrinsic == Intrinsic::aarch64_sve_ldnt1) Info.flags |= MachineMemOperand::MONonTemporal; @@ -9301,7 +9301,7 @@ Info.memVT = MVT::getVT(I.getOperand(0)->getType()); Info.ptrVal = I.getArgOperand(2); Info.offset = 0; - Info.align = MaybeAlign(DL.getABITypeAlignment(PtrTy->getElementType())); + Info.align = DL.getABITypeAlign(PtrTy->getElementType()); Info.flags = MachineMemOperand::MOStore; if (Intrinsic == Intrinsic::aarch64_sve_stnt1) Info.flags |= MachineMemOperand::MONonTemporal; @@ -9606,12 +9606,12 @@ } bool AArch64TargetLowering::hasPairedLoad(EVT LoadedType, - unsigned &RequiredAligment) const { + Align &RequiredAligment) const { if (!LoadedType.isSimple() || (!LoadedType.isInteger() && !LoadedType.isFloatingPoint())) return false; // Cyclone supports unaligned accesses. - RequiredAligment = 0; + RequiredAligment = Align(1); unsigned NumBits = LoadedType.getSizeInBits(); return NumBits == 32 || NumBits == 64; }