Skip to content

Commit 1c16710

Browse files
HankChang736Yeting Kuo
authored andcommitted
[ASan][RISCV] Teach AddressSanitizer to support indexed load/store. (llvm#160443)
This patch is based on llvm#159713 This patch extends AddressSanitizer to support indexed/segment instructions in RVV. It enables proper instrumentation for these memory operations. A new member, `MaybeOffset`, is added to `InterestingMemoryOperand` to describe the offset between the base pointer and the actual memory reference address. Co-authored-by: Yeting Kuo <[email protected]>
1 parent cbbd4db commit 1c16710

File tree

4 files changed

+289
-11
lines changed

4 files changed

+289
-11
lines changed

llvm/include/llvm/Analysis/InterestingMemoryOperand.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,19 @@ class InterestingMemoryOperand {
3232
Value *MaybeEVL;
3333
// The Stride Value, if we're looking at a strided load/store.
3434
Value *MaybeStride;
35+
// The Offset Value, if we're looking at a indexed load/store. The
36+
// offset actually means byte-offset instead of array index.
37+
Value *MaybeByteOffset;
3538

3639
InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite,
3740
class Type *OpType, MaybeAlign Alignment,
3841
Value *MaybeMask = nullptr,
3942
Value *MaybeEVL = nullptr,
40-
Value *MaybeStride = nullptr)
43+
Value *MaybeStride = nullptr,
44+
Value *MaybeByteOffset = nullptr)
4145
: IsWrite(IsWrite), OpType(OpType), Alignment(Alignment),
42-
MaybeMask(MaybeMask), MaybeEVL(MaybeEVL), MaybeStride(MaybeStride) {
46+
MaybeMask(MaybeMask), MaybeEVL(MaybeEVL), MaybeStride(MaybeStride),
47+
MaybeByteOffset(MaybeByteOffset) {
4348
const DataLayout &DL = I->getDataLayout();
4449
TypeStoreSize = DL.getTypeStoreSizeInBits(OpType);
4550
PtrUse = &I->getOperandUse(OperandNo);

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2785,6 +2785,44 @@ bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
27852785
Alignment, Mask, EVL, Stride);
27862786
return true;
27872787
}
2788+
case Intrinsic::riscv_vloxei_mask:
2789+
case Intrinsic::riscv_vluxei_mask:
2790+
case Intrinsic::riscv_vsoxei_mask:
2791+
case Intrinsic::riscv_vsuxei_mask:
2792+
HasMask = true;
2793+
[[fallthrough]];
2794+
case Intrinsic::riscv_vloxei:
2795+
case Intrinsic::riscv_vluxei:
2796+
case Intrinsic::riscv_vsoxei:
2797+
case Intrinsic::riscv_vsuxei: {
2798+
// Intrinsic interface (only listed ordered version):
2799+
// riscv_vloxei(merge, ptr, index, vl)
2800+
// riscv_vloxei_mask(merge, ptr, index, mask, vl, policy)
2801+
// riscv_vsoxei(val, ptr, index, vl)
2802+
// riscv_vsoxei_mask(val, ptr, index, mask, vl, policy)
2803+
bool IsWrite = Inst->getType()->isVoidTy();
2804+
Type *Ty = IsWrite ? Inst->getArgOperand(0)->getType() : Inst->getType();
2805+
const auto *RVVIInfo = RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IID);
2806+
unsigned VLIndex = RVVIInfo->VLOperand;
2807+
unsigned PtrOperandNo = VLIndex - 2 - HasMask;
2808+
Value *Mask;
2809+
if (HasMask) {
2810+
Mask = Inst->getArgOperand(VLIndex - 1);
2811+
} else {
2812+
// Mask cannot be nullptr here: vector GEP produces <vscale x N x ptr>,
2813+
// and casting that to scalar i64 triggers a vector/scalar mismatch
2814+
// assertion in CreatePointerCast. Use an all-true mask so ASan lowers it
2815+
// via extractelement instead.
2816+
Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C));
2817+
Mask = ConstantInt::getTrue(MaskType);
2818+
}
2819+
Value *EVL = Inst->getArgOperand(VLIndex);
2820+
Value *OffsetOp = Inst->getArgOperand(PtrOperandNo + 1);
2821+
Info.InterestingOperands.emplace_back(Inst, PtrOperandNo, IsWrite, Ty,
2822+
Align(1), Mask, EVL,
2823+
/* Stride */ nullptr, OffsetOp);
2824+
return true;
2825+
}
27882826
}
27892827
return false;
27902828
}

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,6 +1786,25 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
17861786
else
17871787
NumInstrumentedReads++;
17881788

1789+
if (O.MaybeByteOffset) {
1790+
Type *Ty = Type::getInt8Ty(*C);
1791+
IRBuilder IB(O.getInsn());
1792+
1793+
Value *OffsetOp = O.MaybeByteOffset;
1794+
if (TargetTriple.isRISCV()) {
1795+
Type *OffsetTy = OffsetOp->getType();
1796+
// RVV indexed loads/stores zero-extend offset operands which are narrower
1797+
// than XLEN to XLEN.
1798+
if (OffsetTy->getScalarType()->getIntegerBitWidth() <
1799+
static_cast<unsigned>(LongSize)) {
1800+
VectorType *OrigType = cast<VectorType>(OffsetTy);
1801+
Type *ExtendTy = VectorType::get(IntptrTy, OrigType);
1802+
OffsetOp = IB.CreateZExt(OffsetOp, ExtendTy);
1803+
}
1804+
}
1805+
Addr = IB.CreateGEP(Ty, Addr, {OffsetOp});
1806+
}
1807+
17891808
unsigned Granularity = 1 << Mapping.Scale;
17901809
if (O.MaybeMask) {
17911810
instrumentMaskedLoadOrStore(this, DL, IntptrTy, O.MaybeMask, O.MaybeEVL,

0 commit comments

Comments
 (0)