| ; RUN: llc -O1 < %s -mtriple=armv7 -mattr=+db | FileCheck %s | |
| @x1 = global i32 0, align 4 | |
| @x2 = global i32 0, align 4 | |
| define void @test() { | |
| entry: | |
| br label %for.body | |
| for.body: ; preds = %for.body, %entry | |
| %i.013 = phi i32 [ 1, %entry ], [ %inc6, %for.body ] | |
| store atomic i32 %i.013, i32* @x1 seq_cst, align 4 | |
| store atomic i32 %i.013, i32* @x1 seq_cst, align 4 | |
| store atomic i32 %i.013, i32* @x2 seq_cst, align 4 | |
| %inc6 = add nsw i32 %i.013, 1 | |
| %exitcond = icmp eq i32 %inc6, 2 | |
| br i1 %exitcond, label %for.end, label %for.body | |
| for.end: ; preds = %for.body | |
| ret void | |
| ; The for.body contains 3 seq_cst stores. | |
| ; Hence it should have 3 dmb;str;dmb sequences with the middle dmbs collapsed | |
| ; CHECK: %for.body | |
| ; CHECK-NOT: str | |
| ; CHECK: dmb | |
| ; CHECK-NOT: dmb | |
| ; CHECK: str | |
| ; CHECK-NOT: str | |
| ; CHECK: dmb | |
| ; CHECK-NOT: dmb | |
| ; CHECK: str | |
| ; CHECK-NOT: str | |
| ; CHECK: dmb | |
| ; CHECK-NOT: dmb | |
| ; CHECK: str | |
| ; CHECK-NOT: str | |
| ; CHECK: dmb | |
| ; CHECK-NOT: dmb | |
| ; CHECK-NOT: str | |
| ; CHECK: %for.end | |
| } | |
| define void @test2() { | |
| call void @llvm.arm.dmb(i32 11) | |
| tail call void @test() | |
| call void @llvm.arm.dmb(i32 11) | |
| ret void | |
| ; the call should prevent the two dmbs from collapsing | |
| ; CHECK: test2: | |
| ; CHECK: dmb | |
| ; CHECK-NEXT: bl | |
| ; CHECK-NEXT: dmb | |
| } | |
| define void @test3() { | |
| call void @llvm.arm.dmb(i32 11) | |
| call void @llvm.arm.dsb(i32 9) | |
| call void @llvm.arm.dmb(i32 11) | |
| ret void | |
| ; the call should prevent the two dmbs from collapsing | |
| ; CHECK: test3: | |
| ; CHECK: dmb | |
| ; CHECK-NEXT: dsb | |
| ; CHECK-NEXT: dmb | |
| } | |
| declare void @llvm.arm.dmb(i32) | |
| declare void @llvm.arm.dsb(i32) |