Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions llvm/include/llvm/Analysis/TargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/InstructionCost.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
#include <functional>
#include <optional>
#include <utility>
Expand Down Expand Up @@ -1665,7 +1666,9 @@ class TargetTransformInfo {
/// will contain additional information - whether the intrinsic may write
/// or read to memory, volatility and the pointer. Info is undefined
/// if false is returned.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may update the comment to indicate the relationship between return value and Interesting?

bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const;
bool getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting = nullptr) const;

/// \returns The maximum element size, in bytes, for an element
/// unordered-atomic memory intrinsic.
Expand Down Expand Up @@ -2289,8 +2292,9 @@ class TargetTransformInfo::Concept {
getAddressComputationCost(Type *Ty, ScalarEvolution *SE, const SCEV *Ptr) = 0;
virtual InstructionCost
getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) = 0;
virtual bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) = 0;
virtual bool getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting = nullptr) = 0;
virtual unsigned getAtomicMemIntrinsicMaxElementSize() const = 0;
virtual Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) = 0;
Expand Down Expand Up @@ -3060,9 +3064,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
InstructionCost getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) override {
return Impl.getCostOfKeepingLiveOverCall(Tys);
}
bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) override {
return Impl.getTgtMemIntrinsic(Inst, Info);
bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand>
*Interesting = nullptr) override {
return Impl.getTgtMemIntrinsic(Inst, Info, Interesting);
}
unsigned getAtomicMemIntrinsicMaxElementSize() const override {
return Impl.getAtomicMemIntrinsicMaxElementSize();
Expand Down
4 changes: 3 additions & 1 deletion llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,9 @@ class TargetTransformInfoImplBase {
return 0;
}

bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const {
bool getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting = nullptr) const {
return false;
}

Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Analysis/TargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1268,9 +1268,10 @@ TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
}

bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const {
return TTIImpl->getTgtMemIntrinsic(Inst, Info);
bool TargetTransformInfo::getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting) const {
return TTIImpl->getTgtMemIntrinsic(Inst, Info, Interesting);
}

unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const {
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4874,8 +4874,9 @@ Value *AArch64TTIImpl::getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
}
}

bool AArch64TTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) {
bool AArch64TTIImpl::getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fill the InterestingMemoryOperand as well if available?

switch (Inst->getIntrinsicID()) {
default:
break;
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ class AArch64TTIImpl : public BasicTTIImplBase<AArch64TTIImpl> {
Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType);

bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info);
bool getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting = nullptr);

bool isElementTypeLegalForScalableVector(Type *Ty) const {
if (Ty->isPointerTy())
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,9 @@ unsigned GCNTTIImpl::getMaxInterleaveFactor(ElementCount VF) {
return 8;
}

bool GCNTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const {
bool GCNTTIImpl::getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting) const {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fill the InterestingMemoryOperand as well if available?

Copy link
Contributor Author

@HankChang736 HankChang736 Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arichardson Thank you for the feedback, after few days of thinking. I'd like to rewrite this patch since this getTgtMemIntrinsic() return true means it fill MemIntrinsicInfo. However, I break this rule and it might cause further error in EarlyCSE where getTgtMemIntrinsic is used if we fill InterestingMemoryOperand. I will try to find a way to combine these, maybe change the return value to optional value or another better way.

switch (Inst->getIntrinsicID()) {
case Intrinsic::amdgcn_ds_ordered_add:
case Intrinsic::amdgcn_ds_ordered_swap: {
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> {
std::optional<uint32_t> AtomicCpySize) const;
unsigned getMaxInterleaveFactor(ElementCount VF);

bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const;
bool getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting = nullptr) const;

InstructionCost getArithmeticInstrCost(
unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -974,8 +974,9 @@ bool PPCTTIImpl::shouldBuildRelLookupTables() const {
return BaseT::shouldBuildRelLookupTables();
}

bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) {
bool PPCTTIImpl::getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting) {
switch (Inst->getIntrinsicID()) {
case Intrinsic::ppc_altivec_lvx:
case Intrinsic::ppc_altivec_lvxl:
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ class PPCTTIImpl : public BasicTTIImplBase<PPCTTIImpl> {
bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
DominatorTree *DT, AssumptionCache *AC,
TargetLibraryInfo *LibInfo);
bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info);
bool getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting = nullptr);
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
TTI::UnrollingPreferences &UP,
OptimizationRemarkEmitter *ORE);
Expand Down
82 changes: 82 additions & 0 deletions llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/PatternMatch.h"
#include <cmath>
#include <optional>
Expand Down Expand Up @@ -43,6 +44,87 @@ static cl::opt<unsigned>
"vectorization while tail-folding."),
cl::init(5), cl::Hidden);

bool RISCVTTIImpl::getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting) const {
const DataLayout &DL = getDataLayout();
Intrinsic::ID IID = Inst->getIntrinsicID();
LLVMContext &C = Inst->getContext();
bool HasMask = false;
bool HasInteresting = (Interesting == nullptr) ? false : true;

switch (IID) {
case Intrinsic::riscv_vle_mask:
case Intrinsic::riscv_vse_mask:
HasMask = true;
[[fallthrough]];
case Intrinsic::riscv_vle:
case Intrinsic::riscv_vse: {
// Intrinsic interface:
// riscv_vle(merge, ptr, vl)
// riscv_vle_mask(merge, ptr, mask, vl, policy)
// riscv_vse(val, ptr, vl)
// riscv_vse_mask(val, ptr, mask, vl, policy)
bool IsWrite = Inst->getType()->isVoidTy();
Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType();
const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
unsigned VLIndex = RVVIInfo->VLOperand;
unsigned PtrOperandNo = VLIndex - 1 - HasMask;
MaybeAlign Alignment =
Inst->getArgOperand(PtrOperandNo)->getPointerAlignment(DL);
Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C));
Value *Mask = ConstantInt::getTrue(MaskType);
if (HasMask)
Mask = Inst->getArgOperand(VLIndex - 1);
Value *EVL = Inst->getArgOperand(VLIndex);
if (HasInteresting)
Interesting->emplace_back(Inst, PtrOperandNo, IsWrite, Ty, Alignment,
Mask, EVL);
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return true means we have fill up MemIntrinsicInfo, but seems like we didn't...

}
case Intrinsic::riscv_vlse_mask:
case Intrinsic::riscv_vsse_mask:
HasMask = true;
[[fallthrough]];
case Intrinsic::riscv_vlse:
case Intrinsic::riscv_vsse: {
// Intrinsic interface:
// riscv_vlse(merge, ptr, stride, vl)
// riscv_vlse_mask(merge, ptr, stride, mask, vl, policy)
// riscv_vsse(val, ptr, stride, vl)
// riscv_vsse_mask(val, ptr, stride, mask, vl, policy)
bool IsWrite = Inst->getType()->isVoidTy();
Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType();
const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
unsigned VLIndex = RVVIInfo->VLOperand;
unsigned PtrOperandNo = VLIndex - 2 - HasMask;
MaybeAlign Alignment =
Inst->getArgOperand(PtrOperandNo)->getPointerAlignment(DL);

Value *Stride = Inst->getArgOperand(PtrOperandNo + 1);
// Use the pointer alignment as the element alignment if the stride is a
// multiple of the pointer alignment. Otherwise, the element alignment
// should be the greatest common divisor of pointer alignment and stride.
// For simplicity, just consider unalignment for elements.
unsigned PointerAlign = Alignment.valueOrOne().value();
if (!isa<ConstantInt>(Stride) ||
cast<ConstantInt>(Stride)->getZExtValue() % PointerAlign != 0)
Alignment = Align(1);

Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C));
Value *Mask = ConstantInt::getTrue(MaskType);
if (HasMask)
Mask = Inst->getArgOperand(VLIndex - 1);
Value *EVL = Inst->getArgOperand(VLIndex);
if (HasInteresting)
Interesting->emplace_back(Inst, PtrOperandNo, IsWrite, Ty, Alignment,
Mask, EVL, Stride);
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

}
}
return false;
}

InstructionCost
RISCVTTIImpl::getRISCVInstructionCost(ArrayRef<unsigned> OpCodes, MVT VT,
TTI::TargetCostKind CostKind) {
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
TTI::PeelingPreferences &PP);

bool getTgtMemIntrinsic(
IntrinsicInst *Inst, MemIntrinsicInfo &Info,
SmallVectorImpl<InterestingMemoryOperand> *Interesting) const;

unsigned getMinVectorRegisterBitWidth() const {
return ST->useRVVForFixedLengthVectors() ? 16 : 0;
}
Expand Down
23 changes: 17 additions & 6 deletions llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Demangle/Demangle.h"
Expand Down Expand Up @@ -799,7 +800,8 @@ struct AddressSanitizer {

bool ignoreAccess(Instruction *Inst, Value *Ptr);
void getInterestingMemoryOperands(
Instruction *I, SmallVectorImpl<InterestingMemoryOperand> &Interesting);
Instruction *I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
const TargetTransformInfo *TTI);

void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
InterestingMemoryOperand &O, bool UseCalls,
Expand Down Expand Up @@ -839,7 +841,8 @@ struct AddressSanitizer {
void instrumentMemIntrinsic(MemIntrinsic *MI, RuntimeCallInserter &RTCI);
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
bool suppressInstrumentationSiteForDebug(int &Instrumented);
bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI);
bool instrumentFunction(Function &F, const TargetLibraryInfo *TLI,
const TargetTransformInfo *TTI);
bool maybeInsertAsanInitAtFunctionEntry(Function &F);
bool maybeInsertDynamicShadowAtFunctionEntry(Function &F);
void markEscapedLocalAllocas(Function &F);
Expand Down Expand Up @@ -1327,7 +1330,8 @@ PreservedAnalyses AddressSanitizerPass::run(Module &M,
Options.MaxInlinePoisoningSize, Options.CompileKernel, Options.Recover,
Options.UseAfterScope, Options.UseAfterReturn);
const TargetLibraryInfo &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
Modified |= FunctionSanitizer.instrumentFunction(F, &TLI);
const TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(F);
Modified |= FunctionSanitizer.instrumentFunction(F, &TLI, &TTI);
}
Modified |= ModuleSanitizer.instrumentModule();
if (!Modified)
Expand Down Expand Up @@ -1465,7 +1469,8 @@ bool AddressSanitizer::ignoreAccess(Instruction *Inst, Value *Ptr) {
}

void AddressSanitizer::getInterestingMemoryOperands(
Instruction *I, SmallVectorImpl<InterestingMemoryOperand> &Interesting) {
Instruction *I, SmallVectorImpl<InterestingMemoryOperand> &Interesting,
const TargetTransformInfo *TTI) {
// Do not instrument the load fetching the dynamic shadow address.
if (LocalDynamicShadow == I)
return;
Expand Down Expand Up @@ -1583,6 +1588,11 @@ void AddressSanitizer::getInterestingMemoryOperands(
break;
}
default:
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
MemIntrinsicInfo DummyInfo;
if (TTI->getTgtMemIntrinsic(II, DummyInfo, &Interesting))
return;
}
for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
ignoreAccess(I, CI->getArgOperand(ArgNo)))
Expand Down Expand Up @@ -2998,7 +3008,8 @@ bool AddressSanitizer::suppressInstrumentationSiteForDebug(int &Instrumented) {
}

bool AddressSanitizer::instrumentFunction(Function &F,
const TargetLibraryInfo *TLI) {
const TargetLibraryInfo *TLI,
const TargetTransformInfo *TTI) {
bool FunctionModified = false;

// Do not apply any instrumentation for naked functions.
Expand Down Expand Up @@ -3051,7 +3062,7 @@ bool AddressSanitizer::instrumentFunction(Function &F,
if (Inst.hasMetadata(LLVMContext::MD_nosanitize))
continue;
SmallVector<InterestingMemoryOperand, 1> InterestingOperands;
getInterestingMemoryOperands(&Inst, InterestingOperands);
getInterestingMemoryOperands(&Inst, InterestingOperands, TTI);

if (!InterestingOperands.empty()) {
for (auto &Operand : InterestingOperands) {
Expand Down
Loading
Loading