Skip to content

Commit a6592dd

Browse files
authored
[AArch64] Mark neon.stN intrinsics as writeonly (#145289)
I found this peculiar comment in EarlyCSE: https://github.com/llvm/llvm-project/blob/1c78d8d9d7bcb4b20910047ad7db35f177a17c8c/llvm/lib/Transforms/Scalar/EarlyCSE.cpp#L1620-L1624 Looking back over history, this seems to be referring to the aarch64.neon.stN intrinsics, which are indeed not marked writeonly (though the ldN intrinsics are readonly). Possibly I'm missing something special about these intrinsics, but I think it is safe to mark them as writeonly.
1 parent 1fe993c commit a6592dd

File tree

5 files changed

+30
-19
lines changed

5 files changed

+30
-19
lines changed

llvm/include/llvm/IR/IntrinsicsAArch64.td

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
612612
[IntrReadMem, IntrArgMemOnly]>;
613613
class AdvSIMD_1Vec_Store_Lane_Intrinsic
614614
: DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty],
615-
[IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
615+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
616616

617617
class AdvSIMD_2Vec_Load_Intrinsic
618618
: DefaultAttrsIntrinsic<[LLVMMatchType<0>, llvm_anyvector_ty],
@@ -626,11 +626,11 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
626626
class AdvSIMD_2Vec_Store_Intrinsic
627627
: DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
628628
llvm_anyptr_ty],
629-
[IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
629+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
630630
class AdvSIMD_2Vec_Store_Lane_Intrinsic
631631
: DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
632632
llvm_i64_ty, llvm_anyptr_ty],
633-
[IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
633+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
634634

635635
class AdvSIMD_3Vec_Load_Intrinsic
636636
: DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
@@ -644,12 +644,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
644644
class AdvSIMD_3Vec_Store_Intrinsic
645645
: DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
646646
LLVMMatchType<0>, llvm_anyptr_ty],
647-
[IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
647+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
648648
class AdvSIMD_3Vec_Store_Lane_Intrinsic
649649
: DefaultAttrsIntrinsic<[], [llvm_anyvector_ty,
650650
LLVMMatchType<0>, LLVMMatchType<0>,
651651
llvm_i64_ty, llvm_anyptr_ty],
652-
[IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
652+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
653653

654654
class AdvSIMD_4Vec_Load_Intrinsic
655655
: DefaultAttrsIntrinsic<[LLVMMatchType<0>, LLVMMatchType<0>,
@@ -667,12 +667,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
667667
: DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
668668
LLVMMatchType<0>, LLVMMatchType<0>,
669669
llvm_anyptr_ty],
670-
[IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
670+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
671671
class AdvSIMD_4Vec_Store_Lane_Intrinsic
672672
: DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
673673
LLVMMatchType<0>, LLVMMatchType<0>,
674674
llvm_i64_ty, llvm_anyptr_ty],
675-
[IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
675+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
676676
}
677677

678678
// Memory ops

llvm/include/llvm/IR/IntrinsicsARM.td

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -742,32 +742,33 @@ def int_arm_neon_vld4dup : DefaultAttrsIntrinsic<
742742
// Interleaving vector stores from N-element structures.
743743
// Source operands are: the address, the N vectors, and the alignment.
744744
def int_arm_neon_vst1 : DefaultAttrsIntrinsic<
745-
[], [llvm_anyptr_ty, llvm_anyvector_ty, llvm_i32_ty], [IntrArgMemOnly]>;
745+
[], [llvm_anyptr_ty, llvm_anyvector_ty, llvm_i32_ty],
746+
[IntrWriteMem, IntrArgMemOnly]>;
746747
def int_arm_neon_vst2 : DefaultAttrsIntrinsic<
747748
[], [llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, llvm_i32_ty],
748-
[IntrArgMemOnly]>;
749+
[IntrWriteMem, IntrArgMemOnly]>;
749750
def int_arm_neon_vst3 : DefaultAttrsIntrinsic<
750751
[],
751752
[llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
752753
llvm_i32_ty],
753-
[IntrArgMemOnly]>;
754+
[IntrWriteMem, IntrArgMemOnly]>;
754755
def int_arm_neon_vst4 : DefaultAttrsIntrinsic<
755756
[],
756757
[llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
757758
LLVMMatchType<1>, llvm_i32_ty],
758-
[IntrArgMemOnly]>;
759+
[IntrWriteMem, IntrArgMemOnly]>;
759760

760761
def int_arm_neon_vst1x2 : DefaultAttrsIntrinsic<
761762
[], [llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>],
762-
[IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
763+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
763764
def int_arm_neon_vst1x3 : DefaultAttrsIntrinsic<
764765
[], [llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>],
765-
[IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
766+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
766767
def int_arm_neon_vst1x4 : DefaultAttrsIntrinsic<
767768
[],
768769
[llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
769770
LLVMMatchType<1>],
770-
[IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
771+
[IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
771772

772773
// Vector store N-element structure from one lane.
773774
// Source operands are: the address, the N vectors, the lane number, and
@@ -776,17 +777,17 @@ def int_arm_neon_vst2lane : DefaultAttrsIntrinsic<
776777
[],
777778
[llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, llvm_i32_ty,
778779
llvm_i32_ty],
779-
[IntrArgMemOnly]>;
780+
[IntrWriteMem, IntrArgMemOnly]>;
780781
def int_arm_neon_vst3lane : DefaultAttrsIntrinsic<
781782
[],
782783
[llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
783784
llvm_i32_ty, llvm_i32_ty],
784-
[IntrArgMemOnly]>;
785+
[IntrWriteMem, IntrArgMemOnly]>;
785786
def int_arm_neon_vst4lane : DefaultAttrsIntrinsic<
786787
[],
787788
[llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
788789
LLVMMatchType<1>, llvm_i32_ty, llvm_i32_ty],
789-
[IntrArgMemOnly]>;
790+
[IntrWriteMem, IntrArgMemOnly]>;
790791

791792
// Vector bitwise select.
792793
def int_arm_neon_vbsl : DefaultAttrsIntrinsic<

llvm/test/Analysis/BasicAA/cs-cs-arm.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ entry:
2424
; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0(ptr %p, i32 16)
2525
; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0(ptr %p, i32 16)
2626
; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.p0.v8i16(ptr %q, <8 x i16> %y, i32 16)
27-
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.p0.v8i16(ptr %q, <8 x i16> %y, i32 16)
27+
; CHECK: Just Mod: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.p0.v8i16(ptr %q, <8 x i16> %y, i32 16)
2828
; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0(ptr %p, i32 16)
2929
; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0(ptr %p, i32 16)
3030
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0(ptr %p, i32 16) #{{[0-9]+}} <-> call void @llvm.arm.neon.vst1.p0.v8i16(ptr %q, <8 x i16> %y, i32 16)

llvm/test/Analysis/BasicAA/intrinsics-arm.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ declare <8 x i16> @llvm.arm.neon.vld1.v8i16.p0(ptr, i32) nounwind readonly
2727
declare void @llvm.arm.neon.vst1.p0.v8i16(ptr, <8 x i16>, i32) nounwind
2828

2929
; CHECK: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }
30-
; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
30+
; CHECK: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
3131
; CHECK: attributes [[ATTR]] = { nounwind }

llvm/test/Assembler/aarch64-intrinsics-attributes.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,15 @@ declare <4 x i32> @llvm.aarch64.neon.shadd.v4i32(<4 x i32>, <4 x i32>)
2222
; CHECK: declare <vscale x 4 x i32> @llvm.aarch64.sve.dup.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i1>, i32) [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_READNONE_WILLRETURN]]
2323
declare <vscale x 4 x i32> @llvm.aarch64.sve.dup.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i1>, i32)
2424

25+
; CHECK: declare void @llvm.aarch64.neon.st2.v4i32.p0(<4 x i32>, <4 x i32>, ptr captures(none)) [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_WRITEONLY_WILLRETURN:#[0-9]+]]
26+
declare void @llvm.aarch64.neon.st2.v4i32.p0(<4 x i32>, <4 x i32>, ptr)
27+
28+
; CHECK: declare void @llvm.aarch64.neon.st2lane.v4i32.p0(<4 x i32>, <4 x i32>, i64, ptr captures(none)) [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_WRITEONLY_WILLRETURN:#[0-9]+]]
29+
declare void @llvm.aarch64.neon.st2lane.v4i32.p0(<4 x i32>, <4 x i32>, i64, ptr)
30+
31+
; CHECK: declare void @llvm.aarch64.neon.st1x2.v8i16.p0(<8 x i16>, <8 x i16>, ptr captures(none)) [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_WRITEONLY_WILLRETURN:#[0-9]+]]
32+
declare void @llvm.aarch64.neon.st1x2.v8i16.p0(<8 x i16>, <8 x i16>, ptr)
33+
2534
; CHECK: attributes [[NOFREE_NOUNWIND_WILLRETURN]] = { nofree nounwind willreturn }
2635
; CHECK: attributes [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_READNONE_WILLRETURN]] = { nocallback nofree nosync nounwind willreturn memory(none) }
36+
; CHECK: attributes [[NO_CALLBACK_NOFREE_NOSYNC_NOUNWIND_WRITEONLY_WILLRETURN]] = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }

0 commit comments

Comments
 (0)