[llvm] [ASan][RISCV] Teach AddressSanitizer to support indexed load/store. (PR #160443)

Hank Chang via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 26 03:00:57 PDT 2025


================
@@ -2774,6 +2774,40 @@ bool RISCVTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
                                           Alignment, Mask, EVL, Stride);
     return true;
   }
+  case Intrinsic::riscv_vloxei_mask:
+  case Intrinsic::riscv_vluxei_mask:
+  case Intrinsic::riscv_vsoxei_mask:
+  case Intrinsic::riscv_vsuxei_mask:
+    HasMask = true;
+    [[fallthrough]];
+  case Intrinsic::riscv_vloxei:
+  case Intrinsic::riscv_vluxei:
+  case Intrinsic::riscv_vsoxei:
+  case Intrinsic::riscv_vsuxei: {
+    // Intrinsic interface (only listed ordered version):
+    // riscv_vloxei(merge, ptr, index, vl)
+    // riscv_vloxei_mask(merge, ptr, index, mask, vl, policy)
+    // riscv_vsoxei(val, ptr, index, vl)
+    // riscv_vsoxei_mask(val, ptr, index, 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;
+    Value *Mask;
+    if (HasMask) {
+      Mask = Inst->getArgOperand(VLIndex - 1);
+    } else {
+      Type *MaskType = Ty->getWithNewType(Type::getInt1Ty(C));
+      Mask = ConstantInt::getTrue(MaskType);
----------------
HankChang736 wrote:

If we set `Mask = nullptr`, AddressSanitizer would directly call `doInstrumentAddress`. However, in our case the address is computed via a `getelementptr`
```
%5 = getelementptr i8, ptr %0, <vscale x 1 x i64> %4  
```
which uses a vector index and therefore produces a `VectorType` of pointers. When this value is passed to `CreatePointerCast`, the assertion in `llvm/lib/IR/Instructions.cpp` is triggered because the source is a `VectorType` while the target `IntptrTy` is a scalar `i64`. In other words, the vector/scalar type mismatch is what causes the crash, so we cannot use `nullptr` here.

If we set the mask to `<vscale x 1 x i1> splat (i1 true)`, AddressSanitizer will take the `instrumentMaskedLoadOrStore` path. In this case it generates
```
%12 = extractelement <vscale x 1 x ptr> %5, i64 %iv
```

to extract the element, which avoids the assertion.

https://github.com/llvm/llvm-project/pull/160443


More information about the llvm-commits mailing list