| 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 |