OLD | NEW |
1 ; RUN: llc -mtriple=x86_64-linux-gnu %s -o - | FileCheck %s | 1 ; RUN: llc -mtriple=i386-unknown-linux %s -o - | FileCheck %s |
2 ; RUN: llc -mtriple=x86_64-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s | 2 ; RUN: llc -mtriple=i386-unknown-linux -pre-RA-sched=fast %s -o - | FileCheck %s |
| 3 ; RUN: llc -mtriple=x86_64-unknown-linux %s -o - | FileCheck %s |
| 4 ; RUN: llc -mtriple=x86_64-unknown-linux -pre-RA-sched=fast %s -o - | FileCheck
%s |
| 5 ; RUN: llc -mtriple=i386-unknown-nacl %s -o - | FileCheck %s -check-prefix=NACL |
| 6 ; RUN: llc -mtriple=i386-unknown-nacl -pre-RA-sched=fast %s -o - | FileCheck %s
-check-prefix=NACL |
| 7 ; RUN: llc -mtriple=x86_64-unknown-nacl %s -o - | FileCheck %s -check-prefix=NAC
L |
| 8 ; RUN: llc -mtriple=x86_64-unknown-nacl -pre-RA-sched=fast %s -o - | FileCheck %
s -check-prefix=NACL |
3 | 9 |
4 declare i32 @bar() | 10 declare i32 @bar() |
5 | 11 |
6 define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) { | 12 define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) { |
7 ; CHECK-LABEL: test_intervening_call: | 13 ; CHECK-LABEL: test_intervening_call: |
8 ; CHECK: cmpxchg | 14 ; CHECK: cmpxchg |
9 ; CHECK: pushfq | 15 ; CHECK: pushf[[LQ:[lq]]] |
10 ; CHECK: popq [[FLAGS:%.*]] | 16 ; CHECK-NEXT: pop[[LQ]] [[FLAGS:%.*]] |
11 | 17 |
12 ; CHECK: callq bar | 18 ; CHECK-NEXT: call[[LQ]] bar |
13 | 19 |
14 ; CHECK: pushq [[FLAGS]] | 20 ; CHECK-NEXT: push[[LQ]] [[FLAGS]] |
15 ; CHECK: popfq | 21 ; CHECK-NEXT: popf[[LQ]] |
16 ; CHECK: jne | 22 ; CHECK-NEXT: jne |
| 23 |
| 24 |
| 25 ; NACL-LABEL: test_intervening_call: |
| 26 ; NACL: cmpxchg |
| 27 ; NACL: push[[LQ:[lq]]] [[AX:%.*]] |
| 28 ; NACL-NEXT: lahf |
| 29 ; NACL-NEXT: mov[[LQ]] [[AX]], [[FLAGS:%.*]] |
| 30 ; NACL-NEXT: pop[[LQ]] [[AX]] |
| 31 |
| 32 ; NACL-NEXT: call[[LQ]] bar |
| 33 |
| 34 ; NACL-NEXT: push[[LQ]] [[AX]] |
| 35 ; NACL-NEXT: mov[[LQ]] [[FLAGS]], [[AX]] |
| 36 ; NACL-NEXT: sahf |
| 37 ; NACL-NEXT: pop[[LQ]] [[AX]] |
| 38 ; NACL-NEXT: jne |
| 39 |
17 %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst | 40 %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst |
18 %p = extractvalue { i64, i1 } %cx, 1 | 41 %p = extractvalue { i64, i1 } %cx, 1 |
19 call i32 @bar() | 42 call i32 @bar() |
20 br i1 %p, label %t, label %f | 43 br i1 %p, label %t, label %f |
21 | 44 |
22 t: | 45 t: |
23 ret i64 42 | 46 ret i64 42 |
24 | 47 |
25 f: | 48 f: |
26 ret i64 0 | 49 ret i64 0 |
27 } | 50 } |
28 | 51 |
29 ; Interesting in producing a clobber without any function calls. | 52 ; Interesting in producing a clobber without any function calls. |
30 define i32 @test_control_flow(i32* %p, i32 %i, i32 %j) { | 53 define i32 @test_control_flow(i32* %p, i32 %i, i32 %j) { |
31 ; CHECK-LABEL: test_control_flow: | 54 ; CHECK-LABEL: test_control_flow: |
32 | |
33 ; CHECK: cmpxchg | 55 ; CHECK: cmpxchg |
34 ; CHECK-NEXT: jne | 56 ; CHECK-NEXT: jne |
| 57 |
| 58 ; NACL-LABEL: test_control_flow: |
| 59 ; NACL: cmpxchg |
| 60 ; NACL-NEXT: jne |
| 61 |
35 entry: | 62 entry: |
36 %cmp = icmp sgt i32 %i, %j | 63 %cmp = icmp sgt i32 %i, %j |
37 br i1 %cmp, label %loop_start, label %cond.end | 64 br i1 %cmp, label %loop_start, label %cond.end |
38 | 65 |
39 loop_start: | 66 loop_start: |
40 br label %while.condthread-pre-split.i | 67 br label %while.condthread-pre-split.i |
41 | 68 |
42 while.condthread-pre-split.i: | 69 while.condthread-pre-split.i: |
43 %.pr.i = load i32* %p, align 4 | 70 %.pr.i = load i32* %p, align 4 |
44 br label %while.cond.i | 71 br label %while.cond.i |
(...skipping 14 matching lines...) Expand all Loading... |
59 | 86 |
60 cond.end: | 87 cond.end: |
61 %cond = phi i32 [ %i, %entry ], [ 0, %cond.end.loopexit ] | 88 %cond = phi i32 [ %i, %entry ], [ 0, %cond.end.loopexit ] |
62 ret i32 %cond | 89 ret i32 %cond |
63 } | 90 } |
64 | 91 |
65 ; This one is an interesting case because CMOV doesn't have a chain | 92 ; This one is an interesting case because CMOV doesn't have a chain |
66 ; operand. Naive attempts to limit cmpxchg EFLAGS use are likely to fail here. | 93 ; operand. Naive attempts to limit cmpxchg EFLAGS use are likely to fail here. |
67 define i32 @test_feed_cmov(i32* %addr, i32 %desired, i32 %new) { | 94 define i32 @test_feed_cmov(i32* %addr, i32 %desired, i32 %new) { |
68 ; CHECK-LABEL: test_feed_cmov: | 95 ; CHECK-LABEL: test_feed_cmov: |
| 96 ; CHECK: cmpxchg |
| 97 ; CHECK: pushf[[LQ:[lq]]] |
| 98 ; CHECK-NEXT: pop[[LQ]] [[FLAGS:%.*]] |
69 | 99 |
70 ; CHECK: cmpxchg | 100 ; CHECK-NEXT: call[[LQ]] bar |
71 ; CHECK: pushfq | |
72 ; CHECK: popq [[FLAGS:%.*]] | |
73 | 101 |
74 ; CHECK: callq bar | 102 ; CHECK-NEXT: push[[LQ]] [[FLAGS]] |
| 103 ; CHECK-NEXT: popf[[LQ]] |
75 | 104 |
76 ; CHECK: pushq [[FLAGS]] | 105 |
77 ; CHECK: popfq | 106 ; NACL-LABEL: test_feed_cmov: |
| 107 ; NACL: cmpxchg |
| 108 ; NACL: push[[LQ:[lq]]] [[AX:%.*]] |
| 109 ; NACL-NEXT: lahf |
| 110 ; NACL-NEXT: mov[[LQ]] [[AX]], [[FLAGS:%.*]] |
| 111 ; NACL-NEXT: pop[[LQ]] [[AX]] |
| 112 |
| 113 ; NACL-NEXT: call[[LQ]] bar |
| 114 |
| 115 ; NACL-NEXT: push[[LQ]] [[AX]] |
| 116 ; NACL-NEXT: mov[[LQ]] [[FLAGS]], [[AX]] |
| 117 ; NACL-NEXT: sahf |
| 118 ; NACL-NEXT: pop[[LQ]] [[AX]] |
78 | 119 |
79 %res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst | 120 %res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst |
80 %success = extractvalue { i32, i1 } %res, 1 | 121 %success = extractvalue { i32, i1 } %res, 1 |
81 | 122 |
82 %rhs = call i32 @bar() | 123 %rhs = call i32 @bar() |
83 | 124 |
84 %ret = select i1 %success, i32 %new, i32 %rhs | 125 %ret = select i1 %success, i32 %new, i32 %rhs |
85 ret i32 %ret | 126 ret i32 %ret |
86 } | 127 } |
OLD | NEW |