Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 5052940

Browse files
author
Robin Morisset
committed
Restore "[ARM, Fix] Fix emitLeading/TrailingFence on old ARM processors"
Summary: This patch was originally in D5304 (I could not find a way to reopen that revision). It was accepted, commited and broke the build bots because the overloading of the constructor of ArrayRef for braced initializer lists is not supported by all toolchains. I then reverted it, and propose this fixed version that uses a plain C array instead in makeDMB (that array is then converted implicitly to an ArrayRef, but that is not behind an ifdef). Could someone confirm me whether initialization lists for plain C arrays are supported by every toolchain used to build llvm ? Otherwise I can just initialize the array in the old way: args[0] = ...; .. ; args[5] = ...; Below is the description of the original patch: ``` I had only tested this code for ARMv7 and ARMv8. This patch adds several fallback paths if the processor does not support dmb ish: - dmb sy if a cortex-M with support for dmb - mcr p15, #0, r0, c7, c10, #5 for ARMv6 (special instruction equivalent to a DMB) These fallback paths were chosen based on the code for fence seq_cst. Thanks to luqmana for having noticed this bug. ``` Test Plan: Added more cases to atomic-load-store.ll + make check-all Reviewers: jfb, t.p.northover, luqmana Subscribers: llvm-commits, aemerson Differential Revision: http://reviews.llvm.org/D5386 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218066 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c21e4e1 commit 5052940

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

lib/Target/ARM/ARMISelLowering.cpp

+26-4
Original file line numberDiff line numberDiff line change
@@ -10984,11 +10984,33 @@ bool ARMTargetLowering::shouldConvertConstantLoadToIntImm(const APInt &Imm,
1098410984

1098510985
bool ARMTargetLowering::hasLoadLinkedStoreConditional() const { return true; }
1098610986

10987-
static void makeDMB(IRBuilder<> &Builder, ARM_MB::MemBOpt Domain) {
10987+
Instruction* ARMTargetLowering::makeDMB(IRBuilder<> &Builder,
10988+
ARM_MB::MemBOpt Domain) const {
1098810989
Module *M = Builder.GetInsertBlock()->getParent()->getParent();
10989-
Function *DMB = llvm::Intrinsic::getDeclaration(M, Intrinsic::arm_dmb);
10990-
Constant *CDomain = Builder.getInt32(Domain);
10991-
Builder.CreateCall(DMB, CDomain);
10990+
10991+
// First, if the target has no DMB, see what fallback we can use.
10992+
if (!Subtarget->hasDataBarrier()) {
10993+
// Some ARMv6 cpus can support data barriers with an mcr instruction.
10994+
// Thumb1 and pre-v6 ARM mode use a libcall instead and should never get
10995+
// here.
10996+
if (Subtarget->hasV6Ops() && !Subtarget->isThumb()) {
10997+
Function *MCR = llvm::Intrinsic::getDeclaration(M, Intrinsic::arm_mcr);
10998+
Value* args[6] = {Builder.getInt32(15), Builder.getInt32(0),
10999+
Builder.getInt32(0), Builder.getInt32(7),
11000+
Builder.getInt32(10), Builder.getInt32(5)};
11001+
return Builder.CreateCall(MCR, args);
11002+
} else {
11003+
// Instead of using barriers, atomic accesses on these subtargets use
11004+
// libcalls.
11005+
llvm_unreachable("makeDMB on a target so old that it has no barriers");
11006+
}
11007+
} else {
11008+
Function *DMB = llvm::Intrinsic::getDeclaration(M, Intrinsic::arm_dmb);
11009+
// Only a full system barrier exists in the M-class architectures.
11010+
Domain = Subtarget->isMClass() ? ARM_MB::SY : Domain;
11011+
Constant *CDomain = Builder.getInt32(Domain);
11012+
return Builder.CreateCall(DMB, CDomain);
11013+
}
1099211014
}
1099311015

1099411016
// Based on http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

lib/Target/ARM/ARMISelLowering.h

+1
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ namespace llvm {
393393
Type *Ty, CallingConv::ID CallConv, bool isVarArg) const override;
394394

395395
bool hasLoadLinkedStoreConditional() const override;
396+
Instruction *makeDMB(IRBuilder<> &Builder, ARM_MB::MemBOpt Domain) const;
396397
Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
397398
AtomicOrdering Ord) const override;
398399
Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,

test/CodeGen/ARM/atomic-load-store.ll

+23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
; RUN: llc < %s -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s -check-prefix=THUMBTWO
44
; RUN: llc < %s -mtriple=thumbv6-apple-ios | FileCheck %s -check-prefix=THUMBONE
55
; RUN: llc < %s -mtriple=armv4-apple-ios | FileCheck %s -check-prefix=ARMV4
6+
; RUN: llc < %s -mtriple=armv6-apple-ios | FileCheck %s -check-prefix=ARMV6
7+
; RUN: llc < %s -mtriple=thumbv7m-apple-ios | FileCheck %s -check-prefix=THUMBM
68

79
define void @test1(i32* %ptr, i32 %val1) {
810
; ARM-LABEL: test1
@@ -15,6 +17,14 @@ define void @test1(i32* %ptr, i32 %val1) {
1517
; THUMBTWO: dmb {{ish$}}
1618
; THUMBTWO-NEXT: str
1719
; THUMBTWO-NEXT: dmb {{ish$}}
20+
; ARMV6-LABEL: test1
21+
; ARMV6: mcr p15, #0, {{r[0-9]*}}, c7, c10, #5
22+
; ARMV6: str
23+
; ARMV6: mcr p15, #0, {{r[0-9]*}}, c7, c10, #5
24+
; THUMBM-LABEL: test1
25+
; THUMBM: dmb sy
26+
; THUMBM: str
27+
; THUMBM: dmb sy
1828
store atomic i32 %val1, i32* %ptr seq_cst, align 4
1929
ret void
2030
}
@@ -28,6 +38,12 @@ define i32 @test2(i32* %ptr) {
2838
; THUMBTWO-LABEL: test2
2939
; THUMBTWO: ldr
3040
; THUMBTWO-NEXT: dmb {{ish$}}
41+
; ARMV6-LABEL: test2
42+
; ARMV6: ldr
43+
; ARMV6: mcr p15, #0, {{r[0-9]*}}, c7, c10, #5
44+
; THUMBM-LABEL: test2
45+
; THUMBM: ldr
46+
; THUMBM: dmb sy
3147
%val = load atomic i32* %ptr seq_cst, align 4
3248
ret i32 %val
3349
}
@@ -55,6 +71,11 @@ define void @test3(i8* %ptr1, i8* %ptr2) {
5571
; THUMBONE-NOT: dmb
5672
; THUMBONE: strb
5773
; THUMBONE-NOT: dmb
74+
75+
; ARMV6-LABEL: test3
76+
; ARMV6-NOT: mcr
77+
; THUMBM-LABEL: test3
78+
; THUMBM-NOT: dmb sy
5879
%val = load atomic i8* %ptr1 unordered, align 1
5980
store atomic i8 %val, i8* %ptr2 unordered, align 1
6081
ret void
@@ -64,6 +85,8 @@ define void @test4(i8* %ptr1, i8* %ptr2) {
6485
; THUMBONE-LABEL: test4
6586
; THUMBONE: ___sync_val_compare_and_swap_1
6687
; THUMBONE: ___sync_lock_test_and_set_1
88+
; ARMV6-LABEL: test4
89+
; THUMBM-LABEL: test4
6790
%val = load atomic i8* %ptr1 seq_cst, align 1
6891
store atomic i8 %val, i8* %ptr2 seq_cst, align 1
6992
ret void

0 commit comments

Comments
 (0)