@@ -5185,6 +5185,7 @@ struct AADereferenceableCallSiteReturned final
51855185// ------------------------ Align Argument Attribute ------------------------
51865186
51875187namespace {
5188+
51885189static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
51895190 Value &AssociatedValue, const Use *U,
51905191 const Instruction *I, bool &TrackUse) {
@@ -5200,6 +5201,28 @@ static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
52005201 TrackUse = true;
52015202 return 0;
52025203 }
5204+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5205+ switch (II->getIntrinsicID()) {
5206+ case Intrinsic::ptrmask: {
5207+ // Is it appropriate to pull attribute in initialization?
5208+ const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5209+ QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5210+ const auto *AlignAA = A.getAAFor<AAAlign>(
5211+ QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5212+ if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5213+ unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5214+ Value::MaxAlignmentExponent);
5215+ Align ConstAlign(UINT64_C(1) << ShiftValue);
5216+ if (ConstAlign >= AlignAA->getKnownAlign())
5217+ return Align(1).value();
5218+ }
5219+ if (AlignAA)
5220+ return AlignAA->getKnownAlign().value();
5221+ break;
5222+ }
5223+ default:
5224+ break;
5225+ }
52035226
52045227 MaybeAlign MA;
52055228 if (const auto *CB = dyn_cast<CallBase>(I)) {
@@ -5499,6 +5522,44 @@ struct AAAlignCallSiteReturned final
54995522 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
55005523 : Base(IRP, A) {}
55015524
5525+ ChangeStatus updateImpl(Attributor &A) override {
5526+ Instruction *I = getIRPosition().getCtxI();
5527+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5528+ switch (II->getIntrinsicID()) {
5529+ case Intrinsic::ptrmask: {
5530+ Align Alignment;
5531+ bool Valid = false;
5532+
5533+ const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5534+ *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5535+ if (ConstVals && ConstVals->isValidState()) {
5536+ unsigned ShiftValue =
5537+ std::min(ConstVals->getAssumedMinTrailingZeros(),
5538+ Value::MaxAlignmentExponent);
5539+ Alignment = Align(UINT64_C(1) << ShiftValue);
5540+ Valid = true;
5541+ }
5542+
5543+ const auto *AlignAA =
5544+ A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5545+ DepClassTy::REQUIRED);
5546+ if (AlignAA && AlignAA->isValidState()) {
5547+ Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5548+ Valid = true;
5549+ }
5550+
5551+ if (Valid)
5552+ return clampStateAndIndicateChange<StateType>(
5553+ this->getState(),
5554+ std::min(this->getAssumedAlign(), Alignment).value());
5555+ break;
5556+ }
5557+ default:
5558+ break;
5559+ }
5560+ }
5561+ return Base::updateImpl(A);
5562+ };
55025563 /// See AbstractAttribute::trackStatistics()
55035564 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
55045565};
0 commit comments