llvm.org GIT mirror llvm / f33a30c
Port memory barriers intrinsics to AArch64 Memory barrier __builtin_arm_[dmb, dsb, isb] intrinsics are required to implement their corresponding ACLE and MSVC intrinsics. This patch ports ARM dmb, dsb, isb intrinsic to AArch64. Differential Revision: http://reviews.llvm.org/D4520 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213247 91177308-0d34-0410-b5e6-96231b3b80d8 Yi Kong 6 years ago
4 changed file(s) with 86 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
4141
4242 def int_aarch64_rbit : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>],
4343 [IntrNoMem]>;
44
45 //===----------------------------------------------------------------------===//
46 // Data Barrier Instructions
47
48 def int_aarch64_dmb : GCCBuiltin<"__builtin_arm_dmb">, Intrinsic<[], [llvm_i32_ty]>;
49 def int_aarch64_dsb : GCCBuiltin<"__builtin_arm_dsb">, Intrinsic<[], [llvm_i32_ty]>;
50 def int_aarch64_isb : GCCBuiltin<"__builtin_arm_isb">, Intrinsic<[], [llvm_i32_ty]>;
4451
4552 }
4653
537537 }]> {
538538 let ParserMatchClass = Imm0_7Operand;
539539 }
540
541 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
542 def imm32_0_15 : Operand, ImmLeaf
543 return ((uint32_t)Imm) < 16;
544 }]>;
540545
541546 // An arithmetic shifter operand:
542547 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
820825 let PrintMethod = "printBarrierOption";
821826 let ParserMatchClass = BarrierAsmOperand;
822827 }
823 class CRmSystemI opc, string asm>
824 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm">,
828 class CRmSystemI opc, string asm,
829 list pattern = []>
830 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
825831 Sched<[WriteBarrier]> {
826832 bits<4> CRm;
827833 let Inst{20-12} = 0b000110011;
330330 def : InstAlias<"sev", (HINT 0b100)>;
331331 def : InstAlias<"sevl", (HINT 0b101)>;
332332
333 // As far as LLVM is concerned this writes to the system's exclusive monitors.
333 // As far as LLVM is concerned this writes to the system's exclusive monitors.
334334 let mayLoad = 1, mayStore = 1 in
335335 def CLREX : CRmSystemI;
336336
337 def DMB : CRmSystemI;
338 def DSB : CRmSystemI;
339 def ISB : CRmSystemI;
337 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
338 // model patterns with sufficiently fine granularity.
339 let mayLoad = ?, mayStore = ? in {
340 def DMB : CRmSystemI
341 [(int_aarch64_dmb (i32 imm32_0_15:$CRm))]>;
342
343 def DSB : CRmSystemI
344 [(int_aarch64_dsb (i32 imm32_0_15:$CRm))]>;
345
346 def ISB : CRmSystemI
347 [(int_aarch64_isb (i32 imm32_0_15:$CRm))]>;
348 }
349
340350 def : InstAlias<"clrex", (CLREX 0xf)>;
341351 def : InstAlias<"isb", (ISB 0xf)>;
342352
0 ; RUN: llc < %s -mtriple=aarch64-eabi -O=3 | FileCheck %s
1
2 define void @test() {
3 ; CHECK: dmb sy
4 call void @llvm.aarch64.dmb(i32 15)
5 ; CHECK: dmb osh
6 call void @llvm.aarch64.dmb(i32 3)
7 ; CHECK: dsb sy
8 call void @llvm.aarch64.dsb(i32 15)
9 ; CHECK: dsb ishld
10 call void @llvm.aarch64.dsb(i32 9)
11 ; CHECK: isb
12 call void @llvm.aarch64.isb(i32 15)
13 ret void
14 }
15
16 ; Important point is that the compiler should not reorder memory access
17 ; instructions around DMB.
18 ; Failure to do so, two STRs will collapse into one STP.
19 define void @test_dmb_reordering(i32 %a, i32 %b, i32* %d) {
20 store i32 %a, i32* %d ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}]
21
22 call void @llvm.aarch64.dmb(i32 15); CHECK: dmb sy
23
24 %d1 = getelementptr i32* %d, i64 1
25 store i32 %b, i32* %d1 ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, #4]
26
27 ret void
28 }
29
30 ; Similarly for DSB.
31 define void @test_dsb_reordering(i32 %a, i32 %b, i32* %d) {
32 store i32 %a, i32* %d ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}]
33
34 call void @llvm.aarch64.dsb(i32 15); CHECK: dsb sy
35
36 %d1 = getelementptr i32* %d, i64 1
37 store i32 %b, i32* %d1 ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, #4]
38
39 ret void
40 }
41
42 ; And ISB.
43 define void @test_isb_reordering(i32 %a, i32 %b, i32* %d) {
44 store i32 %a, i32* %d ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}]
45
46 call void @llvm.aarch64.isb(i32 15); CHECK: isb
47
48 %d1 = getelementptr i32* %d, i64 1
49 store i32 %b, i32* %d1 ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, #4]
50
51 ret void
52 }
53
54 declare void @llvm.aarch64.dmb(i32)
55 declare void @llvm.aarch64.dsb(i32)
56 declare void @llvm.aarch64.isb(i32)