OLD | NEW |
| (Empty) |
1 ; RUN: opt < %s -rewrite-asm-directives -S | FileCheck %s | |
2 ; RUN: opt < %s -O3 -rewrite-asm-directives -S | FileCheck %s | |
3 ; RUN: opt < %s -O3 -rewrite-asm-directives -S | FileCheck %s -check-prefix=ELIM | |
4 ; RUN: opt < %s -rewrite-asm-directives -S | FileCheck %s -check-prefix=CLEANED | |
5 | |
6 ; Test that asm("":::"memory"), a compiler barrier, gets rewritten to a | |
7 ; sequentially-consistent fence. The test is also run at O3 to make sure | |
8 ; that loads and stores don't get unexpectedly eliminated. | |
9 | |
10 ; CLEANED-NOT: asm | |
11 | |
12 @a = external global i32 | |
13 @b = external global i32 | |
14 | |
15 ; Different triples encode "touch everything" constraints differently. | |
16 define void @memory_assembly_encoding_test() { | |
17 ; CHECK: @memory_assembly_encoding_test() | |
18 call void asm sideeffect "", "~{memory}"() | |
19 call void asm sideeffect "", "~{memory},~{dirflag},~{fpsr},~{flags}"() | |
20 ; CHECK-NEXT: fence seq_cst | |
21 ; CHECK-NEXT: fence seq_cst | |
22 | |
23 ret void | |
24 ; CHECK-NEXT: ret void | |
25 } | |
26 | |
27 define void @memory_assembly_ordering_test() { | |
28 ; CHECK: @memory_assembly_ordering_test() | |
29 %1 = load i32* @a, align 4 | |
30 store i32 %1, i32* @b, align 4 | |
31 call void asm sideeffect "", "~{memory}"() | |
32 ; CHECK-NEXT: %1 = load i32* @a, align 4 | |
33 ; CHECK-NEXT: store i32 %1, i32* @b, align 4 | |
34 ; CHECK-NEXT: fence seq_cst | |
35 | |
36 ; Redundant load from the previous location, and store to the same | |
37 ; location (making the previous one dead). Shouldn't get eliminated | |
38 ; because of the fence. | |
39 %2 = load i32* @a, align 4 | |
40 store i32 %2, i32* @b, align 4 | |
41 call void asm sideeffect "", "~{memory}"() | |
42 ; CHECK-NEXT: %2 = load i32* @a, align 4 | |
43 ; CHECK-NEXT: store i32 %2, i32* @b, align 4 | |
44 ; CHECK-NEXT: fence seq_cst | |
45 | |
46 ; Same here. | |
47 %3 = load i32* @a, align 4 | |
48 store i32 %3, i32* @b, align 4 | |
49 ; CHECK-NEXT: %3 = load i32* @a, align 4 | |
50 ; CHECK-NEXT: store i32 %3, i32* @b, align 4 | |
51 | |
52 ret void | |
53 ; CHECK-NEXT: ret void | |
54 } | |
55 | |
56 ; Same function as above, but without the barriers. At O3 some loads and | |
57 ; stores should get eliminated. | |
58 define void @memory_ordering_test() { | |
59 ; ELIM: @memory_ordering_test() | |
60 %1 = load i32* @a, align 4 | |
61 store i32 %1, i32* @b, align 4 | |
62 %2 = load i32* @a, align 4 | |
63 store i32 %2, i32* @b, align 4 | |
64 %3 = load i32* @a, align 4 | |
65 store i32 %3, i32* @b, align 4 | |
66 ; ELIM-NEXT: %1 = load i32* @a, align 4 | |
67 ; ELIM-NEXT: store i32 %1, i32* @b, align 4 | |
68 | |
69 ret void | |
70 ; ELIM-NEXT: ret void | |
71 } | |
OLD | NEW |