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
