[clang] [llvm] [AArch64] Add CMH hints to store_with_hint intrinsic (PR #227326)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 03:55:57 PDT 2026
https://github.com/Lukacma updated https://github.com/llvm/llvm-project/pull/227326
>From ea8313ea0030b8838d8b212b9771d025ffd11b3c Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Wed, 16 Sep 2026 12:37:14 +0000
Subject: [PATCH 1/4] [AArch64] Add CMH hints to store_with_hint intrinsic
---
clang/lib/Headers/arm_acle.h | 3 +
clang/test/CodeGen/builtins-arm64.c | 19 ++++-
clang/test/Sema/builtins-arm64.c | 3 +-
.../include/llvm/Support/AArch64MemoryHints.h | 11 ++-
.../Target/AArch64/AArch64ISelDAGToDAG.cpp | 18 +++++
.../lib/Target/AArch64/AArch64InstrAtomics.td | 9 +++
.../Atomics/aarch64-atomic-store-hint.ll | 80 ++++++++++++++++++-
.../Atomics/aarch64-relaxed-store-hint.ll | 18 +++--
8 files changed, 150 insertions(+), 11 deletions(-)
diff --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h
index 715fe851b0c3229..395b760e7dbf096 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 fb297cd3eec2c70..9c3d810d5597488 100644
--- a/clang/test/CodeGen/builtins-arm64.c
+++ b/clang/test/CodeGen/builtins-arm64.c
@@ -230,9 +230,18 @@ 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
- // CHECK: store atomic i64 {{.*}}, ptr {{.*}} monotonic, align 8
+ __builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_RELAXED, 5); // Invalid Hint
+ // CHECK: store atomic i64 {{.*}}, ptr {{.*}} monotonic, align 8{{$}}
}
// CHECK: ![[M0]] = !{!"1:2:3:4:5"}
@@ -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 9a6e0715c4c7886..a79fb9177cec88b 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 b917191499cac12..f47eb0c945d1b16 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 48c0e37151b9c4d..aa07673673ce26d 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -520,6 +520,9 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
AArch64MemoryHint decodeMemoryHintFlags(MachineMemOperand *MMO) const;
bool isAtomicSTSHH_KEEP(SDNode *N) const;
bool isAtomicSTSHH_STRM(SDNode *N) const;
+ bool isAtomicSTCPH(SDNode *N) const;
+ bool isAtomicSHUH(SDNode *N) const;
+ bool isAtomicSHUH_PH(SDNode *N) const;
bool SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift,
bool Negate);
@@ -4647,6 +4650,21 @@ bool AArch64DAGToDAGISel::isAtomicSTSHH_STRM(SDNode *N) const {
AArch64MemoryHint::STSHH_STRM;
}
+bool AArch64DAGToDAGISel::isAtomicSTCPH(SDNode *N) const {
+ return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
+ AArch64MemoryHint::STCPH;
+}
+
+bool AArch64DAGToDAGISel::isAtomicSHUH(SDNode *N) const {
+ return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
+ AArch64MemoryHint::SHUH;
+}
+
+bool AArch64DAGToDAGISel::isAtomicSHUH_PH(SDNode *N) const {
+ return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
+ AArch64MemoryHint::SHUH_PH;
+}
+
bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm,
SDValue &Shift, bool Negate) {
if (!isa<ConstantSDNode>(N))
diff --git a/llvm/lib/Target/AArch64/AArch64InstrAtomics.td b/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
index 7e0e75c7a3c6b87..56e4821fc20b8d4 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
@@ -425,11 +425,20 @@ 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 : AtomicHintPatternsAddrMode<52, [{ return isAtomicSTCPH(N); }]>;
+ defm : AtomicHintPatternsAddrMode<50, [{ return isAtomicSHUH(N); }]>;
+ defm : AtomicHintPatternsAddrMode<51, [{ return isAtomicSHUH_PH(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 : AtomicHintPatterns<1, 52, [{ return isAtomicSTCPH(N); }]>;
+ defm : AtomicHintPatterns<0, 52, [{ return isAtomicSTCPH(N); }]>;
+ defm : AtomicHintPatterns<1, 50, [{ return isAtomicSHUH(N); }]>;
+ defm : AtomicHintPatterns<0, 50, [{ return isAtomicSHUH(N); }]>;
+ defm : AtomicHintPatterns<1, 51, [{ return isAtomicSHUH_PH(N); }]>;
+ defm : AtomicHintPatterns<0, 51, [{ return isAtomicSHUH_PH(N); }]>;
}
//===----------------------------------
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 bfa9fc49cf7522a..b015d020dc07f85 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,78 @@ define void @test_atomic_store_stream_seqcst_double(ptr %ptr, double %val) nounw
ret void
}
+;
+; STCPH
+;
+
+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_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
+}
+
+;
+; SHUH
+;
+
+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_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 PH
+;
+
+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_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
+}
+
;
; Invalid Hint
;
@@ -327,7 +399,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 +409,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 5f5bc430397782f..b862ae7f4a15d6a 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}
>From 9181f1536f6916aa58893abad6ba0a1dba0c323a Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Wed, 30 Sep 2026 11:39:27 +0000
Subject: [PATCH 2/4] refactor isAtomic* functions and address review comments
---
clang/test/CodeGen/builtins-arm64.c | 2 +-
.../Target/AArch64/AArch64ISelDAGToDAG.cpp | 32 +++----------------
.../lib/Target/AArch64/AArch64InstrAtomics.td | 32 +++++++++----------
.../Atomics/aarch64-atomic-store-hint.ll | 30 +++++++++++++++++
.../Atomics/aarch64-relaxed-store-hint.ll | 2 +-
5 files changed, 52 insertions(+), 46 deletions(-)
diff --git a/clang/test/CodeGen/builtins-arm64.c b/clang/test/CodeGen/builtins-arm64.c
index 9c3d810d5597488..b1002362585803b 100644
--- a/clang/test/CodeGen/builtins-arm64.c
+++ b/clang/test/CodeGen/builtins-arm64.c
@@ -241,7 +241,7 @@ void atomic_store_with_hint(int64_t *a, int64_t b) {
// Invalid hint should be dropped
__builtin_arm_atomic_store_with_hint(a, b, __ATOMIC_RELAXED, 5); // Invalid Hint
- // CHECK: store atomic i64 {{.*}}, ptr {{.*}} monotonic, align 8{{$}}
+ // CHECK: store atomic i64 {{.*}}, ptr {{.*}} monotonic, align 8
}
// CHECK: ![[M0]] = !{!"1:2:3:4:5"}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index aa07673673ce26d..2416936309923ab 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -518,11 +518,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 isAtomicSTCPH(SDNode *N) const;
- bool isAtomicSHUH(SDNode *N) const;
- bool isAtomicSHUH_PH(SDNode *N) const;
+ bool isAtomicMemoryHint(SDNode *N, AArch64MemoryHint Hint) const;
bool SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift,
bool Negate);
@@ -4640,29 +4636,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::isAtomicSTCPH(SDNode *N) const {
- return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
- AArch64MemoryHint::STCPH;
-}
-
-bool AArch64DAGToDAGISel::isAtomicSHUH(SDNode *N) const {
- return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
- AArch64MemoryHint::SHUH;
-}
-
-bool AArch64DAGToDAGISel::isAtomicSHUH_PH(SDNode *N) const {
- return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) ==
- AArch64MemoryHint::SHUH_PH;
+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 56e4821fc20b8d4..09464116b2bfb4e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrAtomics.td
@@ -423,22 +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 : AtomicHintPatternsAddrMode<52, [{ return isAtomicSTCPH(N); }]>;
- defm : AtomicHintPatternsAddrMode<50, [{ return isAtomicSHUH(N); }]>;
- defm : AtomicHintPatternsAddrMode<51, [{ return isAtomicSHUH_PH(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 : AtomicHintPatterns<1, 52, [{ return isAtomicSTCPH(N); }]>;
- defm : AtomicHintPatterns<0, 52, [{ return isAtomicSTCPH(N); }]>;
- defm : AtomicHintPatterns<1, 50, [{ return isAtomicSHUH(N); }]>;
- defm : AtomicHintPatterns<0, 50, [{ return isAtomicSHUH(N); }]>;
- defm : AtomicHintPatterns<1, 51, [{ return isAtomicSHUH_PH(N); }]>;
- defm : AtomicHintPatterns<0, 51, [{ return isAtomicSHUH_PH(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 b015d020dc07f85..c989a5e40e09168 100644
--- a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
+++ b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
@@ -342,6 +342,16 @@ define void @test_atomic_store_stcph_release_i64(ptr %ptr, i64 %val) nounwind {
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
;
@@ -366,6 +376,16 @@ define void @test_atomic_store_shuh_release_i64(ptr %ptr, i64 %val) nounwind {
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
;
@@ -390,6 +410,16 @@ define void @test_atomic_store_shuh_ph_release_i64(ptr %ptr, i64 %val) nounwind
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
;
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 b862ae7f4a15d6a..74d50efa988bde9 100644
--- a/llvm/test/CodeGen/AArch64/Atomics/aarch64-relaxed-store-hint.ll
+++ b/llvm/test/CodeGen/AArch64/Atomics/aarch64-relaxed-store-hint.ll
@@ -124,7 +124,7 @@ 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: shuh{{$}}
+; CHECK-NEXT: shuh
; CHECK-NEXT: strb w2, [x0, x1]
; CHECK-NEXT: ret
%addr = getelementptr i8, ptr %ptr, i64 %offset
>From 52d0edcdfbd5ec15dc236be83bd56fe8e9ff35ea Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Wed, 30 Sep 2026 11:44:39 +0000
Subject: [PATCH 3/4] formatting
---
llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 2416936309923ab..43d3027d5bafad5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -4637,7 +4637,7 @@ AArch64DAGToDAGISel::decodeMemoryHintFlags(MachineMemOperand *MMO) const {
}
bool AArch64DAGToDAGISel::isAtomicMemoryHint(SDNode *N,
- AArch64MemoryHint Hint) const {
+ AArch64MemoryHint Hint) const {
return decodeMemoryHintFlags(cast<MemSDNode>(N)->getMemOperand()) == Hint;
}
>From 5fda50e9abfae92a04e8ec4ec33d839dd77cc2fa Mon Sep 17 00:00:00 2001
From: Marian Lukac <Marian.Lukac at arm.com>
Date: Thu, 1 Oct 2026 10:55:30 +0000
Subject: [PATCH 4/4] Add tests
---
.../Atomics/aarch64-atomic-store-hint.ll | 300 +++++++++++++++++-
1 file changed, 297 insertions(+), 3 deletions(-)
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 c989a5e40e09168..2528a4079b03207 100644
--- a/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
+++ b/llvm/test/CodeGen/AArch64/Atomics/aarch64-atomic-store-hint.ll
@@ -319,7 +319,7 @@ define void @test_atomic_store_stream_seqcst_double(ptr %ptr, double %val) nounw
}
;
-; STCPH
+; STCPH, Relaxed
;
define void @test_atomic_store_stcph_relaxed_i8(ptr %ptr, i8 %val) nounwind {
@@ -332,6 +332,70 @@ define void @test_atomic_store_stcph_relaxed_i8(ptr %ptr, i8 %val) nounwind {
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:
@@ -342,6 +406,40 @@ define void @test_atomic_store_stcph_release_i64(ptr %ptr, i64 %val) nounwind {
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:
@@ -353,7 +451,7 @@ define void @test_atomic_store_stcph_seqcst_i64(ptr %ptr, i64 %val) nounwind {
}
;
-; SHUH
+; SHUH, Relaxed
;
define void @test_atomic_store_shuh_relaxed_i8(ptr %ptr, i8 %val) nounwind {
@@ -366,6 +464,70 @@ define void @test_atomic_store_shuh_relaxed_i8(ptr %ptr, i8 %val) nounwind {
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:
@@ -376,6 +538,40 @@ define void @test_atomic_store_shuh_release_i64(ptr %ptr, i64 %val) nounwind {
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:
@@ -387,7 +583,7 @@ define void @test_atomic_store_shuh_seqcst_i64(ptr %ptr, i64 %val) nounwind {
}
;
-; SHUH PH
+; SHUH PH, Relaxed
;
define void @test_atomic_store_shuh_ph_relaxed_i8(ptr %ptr, i8 %val) nounwind {
@@ -400,6 +596,70 @@ define void @test_atomic_store_shuh_ph_relaxed_i8(ptr %ptr, i8 %val) nounwind {
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:
@@ -410,6 +670,40 @@ define void @test_atomic_store_shuh_ph_release_i64(ptr %ptr, i64 %val) nounwind
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:
More information about the llvm-commits
mailing list