Author: Lukacma
Date: 2026-10-05T10:56:03+01:00
New Revision: 042302b03bd4de1ed59a9f945f4b2565dba1b7e8

URL: 
https://github.com/llvm/llvm-project/commit/042302b03bd4de1ed59a9f945f4b2565dba1b7e8
DIFF: 
https://github.com/llvm/llvm-project/commit/042302b03bd4de1ed59a9f945f4b2565dba1b7e8.diff

LOG: [AArch64] Add CMH hints to store_with_hint intrinsic (#227326)

This patch extends __arm_atomic_store_with_hint intrinsic with new CMH
hints defined in
[ACLE](https://arm-software.github.io/acle/main/acle.html#atomic-store-with-hints-intrinsics)

Added: 
    

Modified: 
    clang/lib/Headers/arm_acle.h
    clang/test/CodeGen/builtins-arm64.c
    clang/test/Sema/builtins-arm64.c
    llvm/include/llvm/Support/AArch64MemoryHints.h
    llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
    llvm/lib/Target/AArch64/AArch64InstrAtomics.td
    llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
    llvm/test/CodeGen/AArch64/Atomics/aarch64-relaxed-store-hint.ll

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h
index 715fe851b0c32..395b760e7dbf0 100644
--- a/clang/lib/Headers/arm_acle.h
+++ b/clang/lib/Headers/arm_acle.h
@@ -746,6 +746,9 @@ __arm_st64bv0(void *__addr, data512_t __value) {
 #if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
 #define HINT_STSHH_KEEP 0
 #define HINT_STSHH_STRM 1
+#define HINT_STCPH 2
+#define HINT_SHUH 3
+#define HINT_SHUH_PH 4
 #define __arm_atomic_store_with_hint(ptr, data, memory_order, hint)            
\
   __builtin_arm_atomic_store_with_hint(ptr, data, memory_order, hint)
 #endif

diff  --git a/clang/test/CodeGen/builtins-arm64.c 
b/clang/test/CodeGen/builtins-arm64.c
index fb297cd3eec2c..b100236258580 100644
--- a/clang/test/CodeGen/builtins-arm64.c
+++ b/clang/test/CodeGen/builtins-arm64.c
@@ -230,8 +230,17 @@ void atomic_store_with_hint(int64_t *a, int64_t b) {
     __builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_RELEASE, 
HINT_STSHH_STRM);
   // CHECK: store atomic i64 {{.*}}, ptr {{.*}} release, align 8, 
!mem.cache_hint ![[M3:[0-9]+]]
 
+  __builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_RELAXED, HINT_STCPH);
+  // CHECK: store atomic i64 {{.*}}, ptr {{.*}} monotonic, align 8, 
!mem.cache_hint ![[M5:[0-9]+]]
+
+  __builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_RELEASE, HINT_SHUH);
+  // CHECK: store atomic i64 {{.*}}, ptr {{.*}} release, align 8, 
!mem.cache_hint ![[M7:[0-9]+]]
+
+  __builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_SEQ_CST, HINT_SHUH_PH);
+  // CHECK: store atomic i64 {{.*}}, ptr {{.*}} seq_cst, align 8, 
!mem.cache_hint ![[M9:[0-9]+]]
+
   // Invalid hint should be dropped
-  __builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_RELAXED, 2); // Invalid 
Hint
+  __builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_RELAXED, 5); // Invalid 
Hint
   // CHECK: store atomic i64 {{.*}}, ptr {{.*}} monotonic, align 8
 }
 
@@ -240,3 +249,9 @@ void atomic_store_with_hint(int64_t *a, int64_t b) {
 // CHECK: ![[M2]] = !{!"aarch64.mem_hint", i32 0}
 // CHECK: ![[M3]] = !{i32 1, ![[M4:[0-9]+]]}
 // CHECK: ![[M4]] = !{!"aarch64.mem_hint", i32 1}
+// CHECK: ![[M5]] = !{i32 1, ![[M6:[0-9]+]]}
+// CHECK: ![[M6]] = !{!"aarch64.mem_hint", i32 2}
+// CHECK: ![[M7]] = !{i32 1, ![[M8:[0-9]+]]}
+// CHECK: ![[M8]] = !{!"aarch64.mem_hint", i32 3}
+// CHECK: ![[M9]] = !{i32 1, ![[M10:[0-9]+]]}
+// CHECK: ![[M10]] = !{!"aarch64.mem_hint", i32 4}

diff  --git a/clang/test/Sema/builtins-arm64.c 
b/clang/test/Sema/builtins-arm64.c
index 9a6e0715c4c78..a79fb9177cec8 100644
--- a/clang/test/Sema/builtins-arm64.c
+++ b/clang/test/Sema/builtins-arm64.c
@@ -73,7 +73,8 @@ void test_atomic_store_hint(char *c_ptr, __int128 *inv_ptr, 
float *f_ptr,
   __builtin_arm_atomic_store_with_hint(c_ptr, c_data, inv_int, 0); // 
expected-error {{invalid memory order argument to atomic hint operation ('int' 
invalid)}}
   __builtin_arm_atomic_store_with_hint(c_ptr, c_data, 2, 0); // expected-error 
{{invalid memory order argument to atomic hint operation (2 invalid)}}
 
-  __builtin_arm_atomic_store_with_hint(c_ptr, c_data, 0, 3); // 
expected-warning {{unrecognised hint type argument to atomic hint operation 
(3)}}
+  __builtin_arm_atomic_store_with_hint(c_ptr, c_data, 0, 5); // 
expected-warning {{unrecognised hint type argument to atomic hint operation 
(5)}}
+
   __builtin_arm_atomic_store_with_hint(c_ptr, c_data, 0, inv_int); // 
expected-error {{invalid hint type argument to atomic hint operation ('int')}}
 
   __builtin_arm_atomic_store_with_hint(c_ptr, c_data, 0, "h"); // 
expected-error {{incompatible pointer to integer conversion passing 'char *' to 
parameter of type 'int'}}

diff  --git a/llvm/include/llvm/Support/AArch64MemoryHints.h 
b/llvm/include/llvm/Support/AArch64MemoryHints.h
index b917191499cac..f47eb0c945d1b 100644
--- a/llvm/include/llvm/Support/AArch64MemoryHints.h
+++ b/llvm/include/llvm/Support/AArch64MemoryHints.h
@@ -14,11 +14,14 @@ enum class AArch64MemoryHint {
   NONE = 0,
   STSHH_KEEP = 1,
   STSHH_STRM = 2,
+  STCPH = 3,
+  SHUH = 4,
+  SHUH_PH = 5,
 };
 
 template <typename Int> inline bool isValidAArch64MemoryHintValue(Int I) {
   return (Int)AArch64MemoryHint::STSHH_KEEP <= I &&
-         I <= (Int)AArch64MemoryHint::STSHH_STRM;
+         I <= (Int)AArch64MemoryHint::SHUH_PH;
 }
 
 template <typename Int> inline AArch64MemoryHint toAArch64MemoryHint(Int I) {
@@ -27,6 +30,12 @@ template <typename Int> inline AArch64MemoryHint 
toAArch64MemoryHint(Int I) {
     return AArch64MemoryHint::STSHH_KEEP;
   case 1:
     return AArch64MemoryHint::STSHH_STRM;
+  case 2:
+    return AArch64MemoryHint::STCPH;
+  case 3:
+    return AArch64MemoryHint::SHUH;
+  case 4:
+    return AArch64MemoryHint::SHUH_PH;
   default:
     return AArch64MemoryHint::NONE;
   }

diff  --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp 
b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 31bedd86859a9..bd1f06554aebd 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -521,8 +521,7 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
   bool SelectCMP_SWAP(SDNode *N);
 
   AArch64MemoryHint decodeMemoryHintFlags(MachineMemOperand *MMO) const;
-  bool isAtomicSTSHH_KEEP(SDNode *N) const;
-  bool isAtomicSTSHH_STRM(SDNode *N) const;
+  bool isAtomicMemoryHint(SDNode *N, AArch64MemoryHint Hint) const;
 
   bool SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift,
                           bool Negate);
@@ -4697,14 +4696,9 @@ 
AArch64DAGToDAGISel::decodeMemoryHintFlags(MachineMemOperand *MMO) const {
   return toAArch64MemoryHint(MemoryHint);
 }
 
-bool AArch64DAGToDAGISel::isAtomicSTSHH_KEEP(SDNode *N) const {
-  return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
-         AArch64MemoryHint::STSHH_KEEP;
-}
-
-bool AArch64DAGToDAGISel::isAtomicSTSHH_STRM(SDNode *N) const {
-  return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
-         AArch64MemoryHint::STSHH_STRM;
+bool AArch64DAGToDAGISel::isAtomicMemoryHint(SDNode *N,
+                                             AArch64MemoryHint Hint) const {
+  return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) == Hint;
 }
 
 bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm,

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrAtomics.td 
b/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
index 7e0e75c7a3c6b..09464116b2bfb 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
@@ -423,13 +423,22 @@ multiclass AtomicHintPatterns<int Relaxed, int Hint, code 
Pred> {
 }
 
 let AddedComplexity = 15 in {
-  defm : AtomicHintPatternsAddrMode<48, [{ return isAtomicSTSHH_KEEP(N); }]>;
-  defm : AtomicHintPatternsAddrMode<49, [{ return isAtomicSTSHH_STRM(N); }]>;
-
-  defm : AtomicHintPatterns<1, 48, [{ return isAtomicSTSHH_KEEP(N); }]>;
-  defm : AtomicHintPatterns<0, 48, [{ return isAtomicSTSHH_KEEP(N); }]>;
-  defm : AtomicHintPatterns<1, 49, [{ return isAtomicSTSHH_STRM(N); }]>;
-  defm : AtomicHintPatterns<0, 49, [{ return isAtomicSTSHH_STRM(N); }]>;
+  defm : AtomicHintPatternsAddrMode<48, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_KEEP); }]>;
+  defm : AtomicHintPatternsAddrMode<49, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_STRM); }]>;
+  defm : AtomicHintPatternsAddrMode<52, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STCPH); }]>;
+  defm : AtomicHintPatternsAddrMode<50, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH); }]>;
+  defm : AtomicHintPatternsAddrMode<51, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH_PH); }]>;
+
+  defm : AtomicHintPatterns<1, 48, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_KEEP); }]>;
+  defm : AtomicHintPatterns<0, 48, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_KEEP); }]>;
+  defm : AtomicHintPatterns<1, 49, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_STRM); }]>;
+  defm : AtomicHintPatterns<0, 49, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STSHH_STRM); }]>;
+  defm : AtomicHintPatterns<1, 52, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STCPH); }]>;
+  defm : AtomicHintPatterns<0, 52, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::STCPH); }]>;
+  defm : AtomicHintPatterns<1, 50, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH); }]>;
+  defm : AtomicHintPatterns<0, 50, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH); }]>;
+  defm : AtomicHintPatterns<1, 51, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH_PH); }]>;
+  defm : AtomicHintPatterns<0, 51, [{ return isAtomicMemoryHint(N, 
AArch64MemoryHint::SHUH_PH); }]>;
 }
 
 //===----------------------------------

diff  --git a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll 
b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
index bfa9fc49cf752..2528a4079b032 100644
--- a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
+++ b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
@@ -318,6 +318,402 @@ define void @test_atomic_store_stream_seqcst_double(ptr 
%ptr, double %val) nounw
   ret void
 }
 
+;
+; STCPH, Relaxed
+;
+
+define void @test_atomic_store_stcph_relaxed_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_relaxed_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    strb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_relaxed_i16(ptr %ptr, i16 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_relaxed_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    strh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_relaxed_i32(ptr %ptr, i32 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_relaxed_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    str w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_relaxed_i64(ptr %ptr, i64 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_relaxed_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    str x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !4
+  ret void
+}
+
+;
+; STCPH, Release
+;
+
+define void @test_atomic_store_stcph_release_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_release_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlrb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr release, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_release_i16(ptr %ptr, i16 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_release_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlrh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr release, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_release_i32(ptr %ptr, i32 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_release_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlr w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr release, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_release_i64(ptr %ptr, i64 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_release_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlr x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr release, align 8, !mem.cache_hint !4
+  ret void
+}
+
+;
+; STCPH, SequentiallyConsistent
+;
+
+define void @test_atomic_store_stcph_seqcst_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_seqcst_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlrb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_seqcst_i16(ptr %ptr, i16 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_seqcst_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlrh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_seqcst_i32(ptr %ptr, i32 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_seqcst_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlr w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !4
+  ret void
+}
+
+define void @test_atomic_store_stcph_seqcst_i64(ptr %ptr, i64 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_stcph_seqcst_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stcph
+; CHECK-NEXT:    stlr x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !4
+  ret void
+}
+
+;
+; SHUH, Relaxed
+;
+
+define void @test_atomic_store_shuh_relaxed_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_relaxed_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh{{$}}
+; CHECK-NEXT:    strb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_relaxed_i16(ptr %ptr, i16 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_relaxed_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    strh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_relaxed_i32(ptr %ptr, i32 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_relaxed_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    str w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_relaxed_i64(ptr %ptr, i64 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_relaxed_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    str x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !6
+  ret void
+}
+
+;
+; SHUH, Release
+;
+
+define void @test_atomic_store_shuh_release_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_release_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    stlrb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr release, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_release_i16(ptr %ptr, i16 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_release_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    stlrh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr release, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_release_i32(ptr %ptr, i32 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_release_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    stlr w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr release, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_release_i64(ptr %ptr, i64 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_release_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh{{$}}
+; CHECK-NEXT:    stlr x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr release, align 8, !mem.cache_hint !6
+  ret void
+}
+
+;
+; SHUH, SequentiallyConsistent
+;
+
+define void @test_atomic_store_shuh_seqcst_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_seqcst_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    stlrb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_seqcst_i16(ptr %ptr, i16 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_seqcst_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    stlrh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_seqcst_i32(ptr %ptr, i32 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_seqcst_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    stlr w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !6
+  ret void
+}
+
+define void @test_atomic_store_shuh_seqcst_i64(ptr %ptr, i64 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_seqcst_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh
+; CHECK-NEXT:    stlr x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !6
+  ret void
+}
+
+;
+; SHUH PH, Relaxed
+;
+
+define void @test_atomic_store_shuh_ph_relaxed_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_relaxed_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    strb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_relaxed_i16(ptr %ptr, i16 %val) 
nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_relaxed_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    strh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_relaxed_i32(ptr %ptr, i32 %val) 
nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_relaxed_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    str w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_relaxed_i64(ptr %ptr, i64 %val) 
nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_relaxed_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    str x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr monotonic, align 8, !mem.cache_hint !8
+  ret void
+}
+
+;
+; SHUH PH, Release
+;
+
+define void @test_atomic_store_shuh_ph_release_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_release_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlrb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr release, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_release_i16(ptr %ptr, i16 %val) 
nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_release_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlrh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr release, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_release_i32(ptr %ptr, i32 %val) 
nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_release_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlr w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr release, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_release_i64(ptr %ptr, i64 %val) 
nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_release_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlr x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr release, align 8, !mem.cache_hint !8
+  ret void
+}
+
+;
+; SHUH PH, SequentiallyConsistent
+;
+
+define void @test_atomic_store_shuh_ph_seqcst_i8(ptr %ptr, i8 %val) nounwind {
+; CHECK-LABEL: test_atomic_store_shuh_ph_seqcst_i8:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlrb w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i8 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_seqcst_i16(ptr %ptr, i16 %val) nounwind 
{
+; CHECK-LABEL: test_atomic_store_shuh_ph_seqcst_i16:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlrh w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i16 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_seqcst_i32(ptr %ptr, i32 %val) nounwind 
{
+; CHECK-LABEL: test_atomic_store_shuh_ph_seqcst_i32:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlr w1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i32 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !8
+  ret void
+}
+
+define void @test_atomic_store_shuh_ph_seqcst_i64(ptr %ptr, i64 %val) nounwind 
{
+; CHECK-LABEL: test_atomic_store_shuh_ph_seqcst_i64:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    shuh ph
+; CHECK-NEXT:    stlr x1, [x0]
+; CHECK-NEXT:    ret
+  store atomic i64 %val, ptr %ptr seq_cst, align 8, !mem.cache_hint !8
+  ret void
+}
+
 ;
 ; Invalid Hint
 ;
@@ -327,7 +723,7 @@ define void @test_atomic_store_invalid_hint(ptr %ptr, i8 
%val) nounwind {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    stlrb w1, [x0]
 ; CHECK-NEXT:    ret
-  store atomic i8 %val, ptr %ptr release, align 8, !mem.cache_hint !4
+  store atomic i8 %val, ptr %ptr release, align 8, !mem.cache_hint !10
   ret void
 }
 
@@ -337,3 +733,9 @@ define void @test_atomic_store_invalid_hint(ptr %ptr, i8 
%val) nounwind {
 !3 = !{!"aarch64.mem_hint", i32 1}
 !4 = !{i32 1, !5}
 !5 = !{!"aarch64.mem_hint", i32 2}
+!6 = !{i32 1, !7}
+!7 = !{!"aarch64.mem_hint", i32 3}
+!8 = !{i32 1, !9}
+!9 = !{!"aarch64.mem_hint", i32 4}
+!10 = !{i32 1, !11}
+!11 = !{!"aarch64.mem_hint", i32 5}

diff  --git a/llvm/test/CodeGen/AArch64/Atomics/aarch64-relaxed-store-hint.ll 
b/llvm/test/CodeGen/AArch64/Atomics/aarch64-relaxed-store-hint.ll
index 5f5bc43039778..74d50efa988bd 100644
--- a/llvm/test/CodeGen/AArch64/Atomics/aarch64-relaxed-store-hint.ll
+++ b/llvm/test/CodeGen/AArch64/Atomics/aarch64-relaxed-store-hint.ll
@@ -11,11 +11,11 @@
 define void @relaxed_store_hint_roW_i8(ptr %ptr, i32 %offset, i8 %val) 
nounwind {
 ; CHECK-LABEL: relaxed_store_hint_roW_i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    stshh keep
+; CHECK-NEXT:    stcph
 ; CHECK-NEXT:    strb w2, [x0, w1, sxtw]
 ; CHECK-NEXT:    ret
   %addr = getelementptr i8, ptr %ptr, i32 %offset
-  store atomic i8 %val, ptr %addr monotonic, align 8, !mem.cache_hint !0
+  store atomic i8 %val, ptr %addr monotonic, align 8, !mem.cache_hint !4
   ret void
 }
 
@@ -124,11 +124,11 @@ define void @relaxed_store_hint_roW_double(ptr %ptr, i32 
%offset, double %val) n
 define void @relaxed_store_hint_roX_i8(ptr %ptr, i64 %offset, i8 %val) 
nounwind {
 ; CHECK-LABEL: relaxed_store_hint_roX_i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    stshh strm
+; CHECK-NEXT:    shuh
 ; CHECK-NEXT:    strb w2, [x0, x1]
 ; CHECK-NEXT:    ret
   %addr = getelementptr i8, ptr %ptr, i64 %offset
-  store atomic i8 %val, ptr %addr monotonic, align 8, !mem.cache_hint !2
+  store atomic i8 %val, ptr %addr monotonic, align 8, !mem.cache_hint !6
   ret void
 }
 
@@ -237,11 +237,11 @@ define void @relaxed_store_hint_roX_double(ptr %ptr, i64 
%offset, double %val) n
 define void @relaxed_store_hint_uimm_i8(ptr %ptr, i8 %val) nounwind {
 ; CHECK-LABEL: relaxed_store_hint_uimm_i8:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    stshh strm
+; CHECK-NEXT:    shuh ph
 ; CHECK-NEXT:    strb w1, [x0, #4095]
 ; CHECK-NEXT:    ret
   %addr = getelementptr i8, ptr %ptr, i32 4095
-  store atomic i8 %val, ptr %addr monotonic, align 8, !mem.cache_hint !2
+  store atomic i8 %val, ptr %addr monotonic, align 8, !mem.cache_hint !8
   ret void
 }
 
@@ -460,3 +460,9 @@ define void @relaxed_store_hint_imm_double(ptr %ptr, double 
%val) nounwind {
 !1 = !{!"aarch64.mem_hint", i32 0}
 !2 = !{i32 1, !3}
 !3 = !{!"aarch64.mem_hint", i32 1}
+!4 = !{i32 1, !5}
+!5 = !{!"aarch64.mem_hint", i32 2}
+!6 = !{i32 1, !7}
+!7 = !{!"aarch64.mem_hint", i32 3}
+!8 = !{i32 1, !9}
+!9 = !{!"aarch64.mem_hint", i32 4}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to