diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1331,8 +1331,10 @@ } else if (auto CI = dyn_cast(I)) { switch (CI->getIntrinsicID()) { case Intrinsic::masked_load: - case Intrinsic::masked_store: { - bool IsWrite = CI->getIntrinsicID() == Intrinsic::masked_store; + case Intrinsic::masked_store: + case Intrinsic::masked_gather: + case Intrinsic::masked_scatter: { + bool IsWrite = CI->getType()->isVoidTy(); // Masked store has an initial operand for the value. unsigned OpOffset = IsWrite ? 1 : 0; if (IsWrite ? !ClInstrumentWrites : !ClInstrumentReads) diff --git a/llvm/test/Instrumentation/AddressSanitizer/asan-masked-load-store.ll b/llvm/test/Instrumentation/AddressSanitizer/asan-masked-load-store.ll --- a/llvm/test/Instrumentation/AddressSanitizer/asan-masked-load-store.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/asan-masked-load-store.ll @@ -373,3 +373,67 @@ tail call void @llvm.masked.store.nxv4f32.p0( %arg, ptr %p, i32 4, %mask) ret void } + +; Test masked.gather/scatter. +declare @llvm.masked.gather.nxv4f32.nxv4p0(, i32, , ) +declare void @llvm.masked.scatter.nxv4f32.nxv4p0(, , i32, ) + +define @scalable.gather.nxv4f32( %vp, %mask, i32 %evl) sanitize_address { +; CHECK-LABEL: @scalable.gather.nxv4f32( +; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP1]], 4 +; CHECK-NEXT: br label [[DOTSPLIT:%.*]] +; CHECK: .split: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[TMP0:%.*]] ], [ [[IV_NEXT:%.*]], [[TMP7:%.*]] ] +; CHECK-NEXT: [[TMP3:%.*]] = extractelement [[MASK:%.*]], i64 [[IV]] +; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7]] +; CHECK: 4: +; CHECK-NEXT: [[TMP5:%.*]] = extractelement [[VP:%.*]], i64 [[IV]] +; CHECK-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64 +; CHECK-NEXT: call void @__asan_load4(i64 [[TMP6]]) +; CHECK-NEXT: br label [[TMP7]] +; CHECK: 7: +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 +; CHECK-NEXT: [[IV_CHECK:%.*]] = icmp eq i64 [[IV_NEXT]], [[TMP2]] +; CHECK-NEXT: br i1 [[IV_CHECK]], label [[DOTSPLIT_SPLIT:%.*]], label [[DOTSPLIT]] +; CHECK: .split.split: +; CHECK-NEXT: [[RES:%.*]] = tail call @llvm.masked.gather.nxv4f32.nxv4p0( [[VP]], i32 4, [[MASK]], undef) +; CHECK-NEXT: ret [[RES]] +; +; DISABLED-LABEL: @scalable.gather.nxv4f32( +; DISABLED-NEXT: [[RES:%.*]] = tail call @llvm.masked.gather.nxv4f32.nxv4p0( [[VP:%.*]], i32 4, [[MASK:%.*]], undef) +; DISABLED-NEXT: ret [[RES]] +; + %res = tail call @llvm.masked.gather.nxv4f32.nxv4p0( %vp, i32 4, %mask, undef) + ret %res +} + +define void @scalable.scatter.nxv4f32( %val, %vp, %mask, i32 %evl) sanitize_address { +; CHECK-LABEL: @scalable.scatter.nxv4f32( +; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP1]], 4 +; CHECK-NEXT: br label [[DOTSPLIT:%.*]] +; CHECK: .split: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[TMP0:%.*]] ], [ [[IV_NEXT:%.*]], [[TMP7:%.*]] ] +; CHECK-NEXT: [[TMP3:%.*]] = extractelement [[MASK:%.*]], i64 [[IV]] +; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7]] +; CHECK: 4: +; CHECK-NEXT: [[TMP5:%.*]] = extractelement [[VP:%.*]], i64 [[IV]] +; CHECK-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[TMP5]] to i64 +; CHECK-NEXT: call void @__asan_store4(i64 [[TMP6]]) +; CHECK-NEXT: br label [[TMP7]] +; CHECK: 7: +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 +; CHECK-NEXT: [[IV_CHECK:%.*]] = icmp eq i64 [[IV_NEXT]], [[TMP2]] +; CHECK-NEXT: br i1 [[IV_CHECK]], label [[DOTSPLIT_SPLIT:%.*]], label [[DOTSPLIT]] +; CHECK: .split.split: +; CHECK-NEXT: tail call void @llvm.masked.scatter.nxv4f32.nxv4p0( [[VAL:%.*]], [[VP]], i32 4, [[MASK]]) +; CHECK-NEXT: ret void +; +; DISABLED-LABEL: @scalable.scatter.nxv4f32( +; DISABLED-NEXT: tail call void @llvm.masked.scatter.nxv4f32.nxv4p0( [[VAL:%.*]], [[VP:%.*]], i32 4, [[MASK:%.*]]) +; DISABLED-NEXT: ret void +; + tail call void @llvm.masked.scatter.nxv4f32.nxv4p0( %val, %vp, i32 4, %mask) + ret void +}