Skip to content

Conversation

@paulwalker-arm
Copy link
Collaborator

Exceptions include intrinsics that:

  • take or return floating point data
  • read or write FFR
  • read or write memory
  • read or write SME state

There's several way to implement this but I settled on the approach of requiring each intrinsic definition to explicitly opt-in to be speculatable rather than trying to reduce the patch size by folding the option into the parent classes when possible. I've done this because it'll be hard to track down cases where an intrinsic is erroneously marked as speculatable so by having it on the same line as the intrinsic definition makes it easier to validate by eye.

The level of testing is another problematic area. The patch doesn't add any new functionality beyond allowing existing code to work when presented with SVE intrinsics. For this reason I opted for just two tests, one with an effect and one without. Let me know if you disagree but I cannot see any value in writing tests for all the intrinsics because they're likely to be harder to verify than just looking at IntrinsicsAArch64.td, plus we wouldn't have written such tests if the flag was added at the same time as the intrinsics.

Exceptions include intrinsics that:
* take or return floating point data
* read or write FFR
* read or write memory
* read or write SME state
@llvmbot
Copy link
Member

llvmbot commented Nov 13, 2025

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-llvm-ir

Author: Paul Walker (paulwalker-arm)

Changes

Exceptions include intrinsics that:

  • take or return floating point data
  • read or write FFR
  • read or write memory
  • read or write SME state

There's several way to implement this but I settled on the approach of requiring each intrinsic definition to explicitly opt-in to be speculatable rather than trying to reduce the patch size by folding the option into the parent classes when possible. I've done this because it'll be hard to track down cases where an intrinsic is erroneously marked as speculatable so by having it on the same line as the intrinsic definition makes it easier to validate by eye.

The level of testing is another problematic area. The patch doesn't add any new functionality beyond allowing existing code to work when presented with SVE intrinsics. For this reason I opted for just two tests, one with an effect and one without. Let me know if you disagree but I cannot see any value in writing tests for all the intrinsics because they're likely to be harder to verify than just looking at IntrinsicsAArch64.td, plus we wouldn't have written such tests if the flag was added at the same time as the intrinsics.


Patch is 113.68 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/167915.diff

3 Files Affected:

  • (modified) llvm/include/llvm/IR/IntrinsicsAArch64.td (+644-645)
  • (modified) llvm/test/Assembler/aarch64-intrinsics-attributes.ll (+2-1)
  • (added) llvm/test/Transforms/LICM/AArch64/speculative-intrinsic-hoisting.ll (+73)
diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index 4cab6e05ba79f..d3ba9955f814b 100644
--- a/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -126,8 +126,8 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
     : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>;
   class AdvSIMD_1FloatArg_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-  class AdvSIMD_1VectorArg_Intrinsic
-    : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
+    : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], !listconcat(Attrs, [IntrNoMem])>;
   class AdvSIMD_1VectorArg_Expand_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
   class AdvSIMD_1IntArg_Narrow_Intrinsic
@@ -145,9 +145,9 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
   class AdvSIMD_2FloatArg_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
                 [IntrNoMem]>;
-  class AdvSIMD_2VectorArg_Intrinsic
+  class AdvSIMD_2VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
   class AdvSIMD_2Arg_FloatCompare_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>],
                 [IntrNoMem]>;
@@ -175,15 +175,14 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
     : DefaultAttrsIntrinsic<[llvm_anyint_ty],
                 [LLVMMatchType<0>, llvm_anyint_ty, llvm_i32_ty],
                 [IntrNoMem]>;
-
   class AdvSIMD_3IntArg_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyint_ty],
                 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
                 [IntrNoMem]>;
-  class AdvSIMD_3VectorArg_Intrinsic
+  class AdvSIMD_3VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
-               [IntrNoMem]>;
+               !listconcat(Attrs, [IntrNoMem])>;
   class AdvSIMD_3VectorArg_Scalar_Intrinsic
       : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
@@ -1108,124 +1107,124 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                    LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_ptr_ty],
                   [IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
 
-  class AdvSIMD_SVE_Index_Intrinsic
+  class AdvSIMD_SVE_Index_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMVectorElementType<0>,
                  LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_Merged1VectorArg_Intrinsic
+  class AdvSIMD_Merged1VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_2VectorArgIndexed_Intrinsic
+  class AdvSIMD_2VectorArgIndexed_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_3VectorArgIndexed_Intrinsic
+  class AdvSIMD_3VectorArgIndexed_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>])>;
 
-  class AdvSIMD_Pred1VectorArg_Intrinsic
+  class AdvSIMD_Pred1VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_Pred2VectorArg_Intrinsic
+  class AdvSIMD_Pred2VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_Pred3VectorArg_Intrinsic
+  class AdvSIMD_Pred3VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_Compare_Intrinsic
+  class AdvSIMD_SVE_Compare_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  llvm_anyvector_ty,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_CompareWide_Intrinsic
+  class AdvSIMD_SVE_CompareWide_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  llvm_anyvector_ty,
                  llvm_nxv2i64_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_Saturating_Intrinsic
+  class AdvSIMD_SVE_Saturating_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_SaturatingWithPattern_Intrinsic
+  class AdvSIMD_SVE_SaturatingWithPattern_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  llvm_i32_ty,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_SVE_Saturating_N_Intrinsic<LLVMType T>
+  class AdvSIMD_SVE_Saturating_N_Intrinsic<LLVMType T, list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[T],
                 [T, llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_SaturatingWithPattern_N_Intrinsic<LLVMType T>
+  class AdvSIMD_SVE_SaturatingWithPattern_N_Intrinsic<LLVMType T, list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[T],
                 [T, llvm_i32_ty, llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_SVE_CNT_Intrinsic
+  class AdvSIMD_SVE_CNT_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMVectorOfBitcastsToInt<0>],
                 [LLVMVectorOfBitcastsToInt<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_ReduceWithInit_Intrinsic
+  class AdvSIMD_SVE_ReduceWithInit_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMVectorElementType<0>,
                  llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_ShiftByImm_Intrinsic
+  class AdvSIMD_SVE_ShiftByImm_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_SVE_ShiftWide_Intrinsic
+  class AdvSIMD_SVE_ShiftWide_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  llvm_nxv2i64_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_Unpack_Intrinsic
+  class AdvSIMD_SVE_Unpack_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                [LLVMSubdivide2VectorType<0>],
-               [IntrNoMem]>;
+               !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_CADD_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
@@ -1244,31 +1243,31 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                  llvm_i32_ty],
                 [IntrNoMem, ImmArg<ArgIndex<4>>]>;
 
-  class AdvSIMD_SVE_CMLA_LANE_Intrinsic
+  class AdvSIMD_SVE_CMLA_LANE_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  llvm_i32_ty,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>])>;
 
-  class AdvSIMD_SVE_DUP_Intrinsic
+  class AdvSIMD_SVE_DUP_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DUP_Unpred_Intrinsic
+  class AdvSIMD_SVE_DUP_Unpred_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DUPQ_Intrinsic
+  class AdvSIMD_SVE_DUPQ_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  llvm_i64_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_EXPA_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
@@ -1289,21 +1288,21 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                  llvm_anyvector_ty],
                 [IntrNoMem]>;
 
-  class AdvSIMD_SVE_INSR_Intrinsic
+  class AdvSIMD_SVE_INSR_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_PTRUE_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [llvm_i32_ty],
                 [IntrNoMem, ImmArg<ArgIndex<0>>]>;
 
-  class AdvSIMD_SVE_PUNPKHI_Intrinsic
+  class AdvSIMD_SVE_PUNPKHI_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMOneNthElementsVectorType<0, 2>],
                 [llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_SCALE_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
@@ -1325,191 +1324,192 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                  LLVMVectorOfBitcastsToInt<0>],
                 [IntrNoMem]>;
 
-  class AdvSIMD_SVE_CNTB_Intrinsic
+  class AdvSIMD_SVE_CNTB_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_i64_ty],
                 [llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<0>>])>;
 
-  class AdvSIMD_SVE_CNTP_Intrinsic
+  class AdvSIMD_SVE_CNTP_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_i64_ty],
                 [llvm_anyvector_ty, LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DOT_Intrinsic
+  class AdvSIMD_SVE_DOT_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide4VectorType<0>,
                  LLVMSubdivide4VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DOT_Indexed_Intrinsic
+  class AdvSIMD_SVE_DOT_Indexed_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide4VectorType<0>,
                  LLVMSubdivide4VectorType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>])>;
 
-  class AdvSIMD_SVE_PTEST_Intrinsic
+  class AdvSIMD_SVE_PTEST_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_i1_ty],
                 [llvm_anyvector_ty,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_TBL_Intrinsic
+  class AdvSIMD_SVE_TBL_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMVectorOfBitcastsToInt<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE2_TBX_Intrinsic
+  class AdvSIMD_SVE2_TBX_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMVectorOfBitcastsToInt<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_LUTI_Inrinsic
+  class SVE2_LUTI_Inrinsic<list<IntrinsicProperty> Attrs = []>
     :  DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  llvm_nxv16i8_ty,
                  llvm_i32_ty],
-                 [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+                 !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class SVE2_1VectorArg_Long_Intrinsic
+  class SVE2_1VectorArg_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMSubdivide2VectorType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>])>;
 
-  class SVE2_2VectorArg_Long_Intrinsic
+  class SVE2_2VectorArg_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMSubdivide2VectorType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_2VectorArgIndexed_Long_Intrinsic
+  class SVE2_2VectorArgIndexed_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
   : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
               [LLVMSubdivide2VectorType<0>,
                LLVMSubdivide2VectorType<0>,
                llvm_i32_ty],
-              [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+              !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class SVE2_2VectorArg_Wide_Intrinsic
+  class SVE2_2VectorArg_Wide_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_2VectorArg_Pred_Long_Intrinsic
+  class SVE2_2VectorArg_Pred_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_3VectorArg_Long_Intrinsic
+  class SVE2_3VectorArg_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_3VectorArgIndexed_Long_Intrinsic
+  class SVE2_3VectorArgIndexed_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>,
                  LLVMSubdivide2VectorType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>])>;
 
-  class SVE2_1VectorArg_Narrowing_Intrinsic
+  class SVE2_1VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
                 [llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_Merged1VectorArg_Narrowing_Intrinsic
+  class SVE2_Merged1VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
                 [LLVMSubdivide2VectorType<0>,
                  llvm_anyvector_ty],
-                [IntrNoMem]>;
-  class SVE2_2VectorArg_Narrowing_Intrinsic
+                !listconcat(Attrs, [IntrNoMem])>;
+
+  class SVE2_2VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<
             [LLVMSubdivide2VectorType<0>],
             [llvm_anyvector_ty, LLVMMatchType<0>],
-            [IntrNoMem]>;
+            !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_Merged2VectorArg_Narrowing_Intrinsic
+  class SVE2_Merged2VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<
             [LLVMSubdivide2VectorType<0>],
             [LLVMSubdivide2VectorType<0>, llvm_anyvector_ty, LLVMMatchType<0>],
-            [IntrNoMem]>;
+            !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_1VectorArg_Imm_Narrowing_Intrinsic
+  class SVE2_1VectorArg_Imm_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
                   [llvm_anyvector_ty, llvm_i32_ty],
-                  [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+                  !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>])>;
 
-  class SVE2_2VectorArg_Imm_Narrowing_Intrinsic
+  class SVE2_2VectorArg_Imm_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
        ...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Nov 13, 2025

@llvm/pr-subscribers-backend-aarch64

Author: Paul Walker (paulwalker-arm)

Changes

Exceptions include intrinsics that:

  • take or return floating point data
  • read or write FFR
  • read or write memory
  • read or write SME state

There's several way to implement this but I settled on the approach of requiring each intrinsic definition to explicitly opt-in to be speculatable rather than trying to reduce the patch size by folding the option into the parent classes when possible. I've done this because it'll be hard to track down cases where an intrinsic is erroneously marked as speculatable so by having it on the same line as the intrinsic definition makes it easier to validate by eye.

The level of testing is another problematic area. The patch doesn't add any new functionality beyond allowing existing code to work when presented with SVE intrinsics. For this reason I opted for just two tests, one with an effect and one without. Let me know if you disagree but I cannot see any value in writing tests for all the intrinsics because they're likely to be harder to verify than just looking at IntrinsicsAArch64.td, plus we wouldn't have written such tests if the flag was added at the same time as the intrinsics.


Patch is 113.68 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/167915.diff

3 Files Affected:

  • (modified) llvm/include/llvm/IR/IntrinsicsAArch64.td (+644-645)
  • (modified) llvm/test/Assembler/aarch64-intrinsics-attributes.ll (+2-1)
  • (added) llvm/test/Transforms/LICM/AArch64/speculative-intrinsic-hoisting.ll (+73)
diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index 4cab6e05ba79f..d3ba9955f814b 100644
--- a/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -126,8 +126,8 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
     : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>;
   class AdvSIMD_1FloatArg_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-  class AdvSIMD_1VectorArg_Intrinsic
-    : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+  class AdvSIMD_1VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
+    : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], !listconcat(Attrs, [IntrNoMem])>;
   class AdvSIMD_1VectorArg_Expand_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
   class AdvSIMD_1IntArg_Narrow_Intrinsic
@@ -145,9 +145,9 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
   class AdvSIMD_2FloatArg_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
                 [IntrNoMem]>;
-  class AdvSIMD_2VectorArg_Intrinsic
+  class AdvSIMD_2VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
   class AdvSIMD_2Arg_FloatCompare_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>],
                 [IntrNoMem]>;
@@ -175,15 +175,14 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
     : DefaultAttrsIntrinsic<[llvm_anyint_ty],
                 [LLVMMatchType<0>, llvm_anyint_ty, llvm_i32_ty],
                 [IntrNoMem]>;
-
   class AdvSIMD_3IntArg_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyint_ty],
                 [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
                 [IntrNoMem]>;
-  class AdvSIMD_3VectorArg_Intrinsic
+  class AdvSIMD_3VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
-               [IntrNoMem]>;
+               !listconcat(Attrs, [IntrNoMem])>;
   class AdvSIMD_3VectorArg_Scalar_Intrinsic
       : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
@@ -1108,124 +1107,124 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                    LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_ptr_ty],
                   [IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
 
-  class AdvSIMD_SVE_Index_Intrinsic
+  class AdvSIMD_SVE_Index_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMVectorElementType<0>,
                  LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_Merged1VectorArg_Intrinsic
+  class AdvSIMD_Merged1VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_2VectorArgIndexed_Intrinsic
+  class AdvSIMD_2VectorArgIndexed_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_3VectorArgIndexed_Intrinsic
+  class AdvSIMD_3VectorArgIndexed_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>])>;
 
-  class AdvSIMD_Pred1VectorArg_Intrinsic
+  class AdvSIMD_Pred1VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_Pred2VectorArg_Intrinsic
+  class AdvSIMD_Pred2VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_Pred3VectorArg_Intrinsic
+  class AdvSIMD_Pred3VectorArg_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_Compare_Intrinsic
+  class AdvSIMD_SVE_Compare_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  llvm_anyvector_ty,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_CompareWide_Intrinsic
+  class AdvSIMD_SVE_CompareWide_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  llvm_anyvector_ty,
                  llvm_nxv2i64_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_Saturating_Intrinsic
+  class AdvSIMD_SVE_Saturating_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_SaturatingWithPattern_Intrinsic
+  class AdvSIMD_SVE_SaturatingWithPattern_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  llvm_i32_ty,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_SVE_Saturating_N_Intrinsic<LLVMType T>
+  class AdvSIMD_SVE_Saturating_N_Intrinsic<LLVMType T, list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[T],
                 [T, llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_SaturatingWithPattern_N_Intrinsic<LLVMType T>
+  class AdvSIMD_SVE_SaturatingWithPattern_N_Intrinsic<LLVMType T, list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[T],
                 [T, llvm_i32_ty, llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_SVE_CNT_Intrinsic
+  class AdvSIMD_SVE_CNT_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMVectorOfBitcastsToInt<0>],
                 [LLVMVectorOfBitcastsToInt<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_ReduceWithInit_Intrinsic
+  class AdvSIMD_SVE_ReduceWithInit_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMVectorElementType<0>,
                  llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_ShiftByImm_Intrinsic
+  class AdvSIMD_SVE_ShiftByImm_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class AdvSIMD_SVE_ShiftWide_Intrinsic
+  class AdvSIMD_SVE_ShiftWide_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  llvm_nxv2i64_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_Unpack_Intrinsic
+  class AdvSIMD_SVE_Unpack_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                [LLVMSubdivide2VectorType<0>],
-               [IntrNoMem]>;
+               !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_CADD_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
@@ -1244,31 +1243,31 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                  llvm_i32_ty],
                 [IntrNoMem, ImmArg<ArgIndex<4>>]>;
 
-  class AdvSIMD_SVE_CMLA_LANE_Intrinsic
+  class AdvSIMD_SVE_CMLA_LANE_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  llvm_i32_ty,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>])>;
 
-  class AdvSIMD_SVE_DUP_Intrinsic
+  class AdvSIMD_SVE_DUP_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DUP_Unpred_Intrinsic
+  class AdvSIMD_SVE_DUP_Unpred_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DUPQ_Intrinsic
+  class AdvSIMD_SVE_DUPQ_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  llvm_i64_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_EXPA_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
@@ -1289,21 +1288,21 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                  llvm_anyvector_ty],
                 [IntrNoMem]>;
 
-  class AdvSIMD_SVE_INSR_Intrinsic
+  class AdvSIMD_SVE_INSR_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMVectorElementType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_PTRUE_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [llvm_i32_ty],
                 [IntrNoMem, ImmArg<ArgIndex<0>>]>;
 
-  class AdvSIMD_SVE_PUNPKHI_Intrinsic
+  class AdvSIMD_SVE_PUNPKHI_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMOneNthElementsVectorType<0, 2>],
                 [llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
   class AdvSIMD_SVE_SCALE_Intrinsic
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
@@ -1325,191 +1324,192 @@ let TargetPrefix = "aarch64" in {  // All intrinsics start with "llvm.aarch64.".
                  LLVMVectorOfBitcastsToInt<0>],
                 [IntrNoMem]>;
 
-  class AdvSIMD_SVE_CNTB_Intrinsic
+  class AdvSIMD_SVE_CNTB_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_i64_ty],
                 [llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<0>>])>;
 
-  class AdvSIMD_SVE_CNTP_Intrinsic
+  class AdvSIMD_SVE_CNTP_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_i64_ty],
                 [llvm_anyvector_ty, LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DOT_Intrinsic
+  class AdvSIMD_SVE_DOT_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide4VectorType<0>,
                  LLVMSubdivide4VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_DOT_Indexed_Intrinsic
+  class AdvSIMD_SVE_DOT_Indexed_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide4VectorType<0>,
                  LLVMSubdivide4VectorType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>])>;
 
-  class AdvSIMD_SVE_PTEST_Intrinsic
+  class AdvSIMD_SVE_PTEST_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_i1_ty],
                 [llvm_anyvector_ty,
                  LLVMMatchType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE_TBL_Intrinsic
+  class AdvSIMD_SVE_TBL_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMVectorOfBitcastsToInt<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class AdvSIMD_SVE2_TBX_Intrinsic
+  class AdvSIMD_SVE2_TBX_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMMatchType<0>,
                  LLVMVectorOfBitcastsToInt<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_LUTI_Inrinsic
+  class SVE2_LUTI_Inrinsic<list<IntrinsicProperty> Attrs = []>
     :  DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  llvm_nxv16i8_ty,
                  llvm_i32_ty],
-                 [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+                 !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class SVE2_1VectorArg_Long_Intrinsic
+  class SVE2_1VectorArg_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMSubdivide2VectorType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>])>;
 
-  class SVE2_2VectorArg_Long_Intrinsic
+  class SVE2_2VectorArg_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMSubdivide2VectorType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_2VectorArgIndexed_Long_Intrinsic
+  class SVE2_2VectorArgIndexed_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
   : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
               [LLVMSubdivide2VectorType<0>,
                LLVMSubdivide2VectorType<0>,
                llvm_i32_ty],
-              [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+              !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<2>>])>;
 
-  class SVE2_2VectorArg_Wide_Intrinsic
+  class SVE2_2VectorArg_Wide_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_2VectorArg_Pred_Long_Intrinsic
+  class SVE2_2VectorArg_Pred_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
                  LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_3VectorArg_Long_Intrinsic
+  class SVE2_3VectorArg_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>,
                  LLVMSubdivide2VectorType<0>],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_3VectorArgIndexed_Long_Intrinsic
+  class SVE2_3VectorArgIndexed_Long_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
                 [LLVMMatchType<0>,
                  LLVMSubdivide2VectorType<0>,
                  LLVMSubdivide2VectorType<0>,
                  llvm_i32_ty],
-                [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+                !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<3>>])>;
 
-  class SVE2_1VectorArg_Narrowing_Intrinsic
+  class SVE2_1VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
                 [llvm_anyvector_ty],
-                [IntrNoMem]>;
+                !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_Merged1VectorArg_Narrowing_Intrinsic
+  class SVE2_Merged1VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
     : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
                 [LLVMSubdivide2VectorType<0>,
                  llvm_anyvector_ty],
-                [IntrNoMem]>;
-  class SVE2_2VectorArg_Narrowing_Intrinsic
+                !listconcat(Attrs, [IntrNoMem])>;
+
+  class SVE2_2VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<
             [LLVMSubdivide2VectorType<0>],
             [llvm_anyvector_ty, LLVMMatchType<0>],
-            [IntrNoMem]>;
+            !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_Merged2VectorArg_Narrowing_Intrinsic
+  class SVE2_Merged2VectorArg_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<
             [LLVMSubdivide2VectorType<0>],
             [LLVMSubdivide2VectorType<0>, llvm_anyvector_ty, LLVMMatchType<0>],
-            [IntrNoMem]>;
+            !listconcat(Attrs, [IntrNoMem])>;
 
-  class SVE2_1VectorArg_Imm_Narrowing_Intrinsic
+  class SVE2_1VectorArg_Imm_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
                   [llvm_anyvector_ty, llvm_i32_ty],
-                  [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+                  !listconcat(Attrs, [IntrNoMem, ImmArg<ArgIndex<1>>])>;
 
-  class SVE2_2VectorArg_Imm_Narrowing_Intrinsic
+  class SVE2_2VectorArg_Imm_Narrowing_Intrinsic<list<IntrinsicProperty> Attrs = []>
       : DefaultAttrsIntrinsic<[LLVMSubdivide2VectorType<0>],
        ...
[truncated]

Copy link
Member

@MacDue MacDue left a comment

Choose a reason for hiding this comment

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

I can't say I've checked every intrinsic in detail, but I've looked over the list (and checked a few that I was unsure about), and this looks fine to me.

@paulwalker-arm paulwalker-arm merged commit 591c463 into llvm:main Nov 18, 2025
14 checks passed
@paulwalker-arm paulwalker-arm deleted the sve-mark-intrinsics-speculatable branch November 18, 2025 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants