Kyle Butt | 0846e56 | 2016-10-11 20:36:43 +0000 | [diff] [blame] | 1 | ; RUN: llc -outline-optional-branches -O2 < %s | FileCheck %s |
| 2 | target datalayout = "e-m:e-i64:64-n32:64" |
| 3 | target triple = "powerpc64le-grtev4-linux-gnu" |
| 4 | |
| 5 | ; Intended layout: |
| 6 | ; The outlining flag produces the layout |
| 7 | ; test1 |
| 8 | ; test2 |
| 9 | ; test3 |
| 10 | ; test4 |
| 11 | ; exit |
| 12 | ; optional1 |
| 13 | ; optional2 |
| 14 | ; optional3 |
| 15 | ; optional4 |
| 16 | ; Tail duplication puts test n+1 at the end of optional n |
| 17 | ; so optional1 includes a copy of test2 at the end, and branches |
| 18 | ; to test3 (at the top) or falls through to optional 2. |
| 19 | ; The CHECK statements check for the whole string of tests and exit block, |
| 20 | ; and then check that the correct test has been duplicated into the end of |
| 21 | ; the optional blocks and that the optional blocks are in the correct order. |
Kyle Butt | efe56fe | 2017-01-11 19:55:19 +0000 | [diff] [blame] | 22 | ;CHECK-LABEL: f: |
Kyle Butt | 0846e56 | 2016-10-11 20:36:43 +0000 | [diff] [blame] | 23 | ; test1 may have been merged with entry |
| 24 | ;CHECK: mr [[TAGREG:[0-9]+]], 3 |
| 25 | ;CHECK: andi. {{[0-9]+}}, [[TAGREG]], 1 |
| 26 | ;CHECK-NEXT: bc 12, 1, [[OPT1LABEL:[._0-9A-Za-z]+]] |
| 27 | ;CHECK-NEXT: [[TEST2LABEL:[._0-9A-Za-z]+]]: # %test2 |
| 28 | ;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30 |
| 29 | ;CHECK-NEXT: bne 0, [[OPT2LABEL:[._0-9A-Za-z]+]] |
| 30 | ;CHECK-NEXT: [[TEST3LABEL:[._0-9A-Za-z]+]]: # %test3 |
| 31 | ;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29 |
| 32 | ;CHECK-NEXT: bne 0, .[[OPT3LABEL:[._0-9A-Za-z]+]] |
| 33 | ;CHECK-NEXT: [[TEST4LABEL:[._0-9A-Za-z]+]]: # %test4 |
| 34 | ;CHECK-NEXT: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 28, 28 |
| 35 | ;CHECK-NEXT: bne 0, .[[OPT4LABEL:[._0-9A-Za-z]+]] |
| 36 | ;CHECK-NEXT: [[EXITLABEL:[._0-9A-Za-z]+]]: # %exit |
| 37 | ;CHECK: blr |
| 38 | ;CHECK-NEXT: [[OPT1LABEL]] |
| 39 | ;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 30, 30 |
| 40 | ;CHECK-NEXT: beq 0, [[TEST3LABEL]] |
| 41 | ;CHECK-NEXT: [[OPT2LABEL]] |
| 42 | ;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 29, 29 |
| 43 | ;CHECK-NEXT: beq 0, [[TEST4LABEL]] |
| 44 | ;CHECK-NEXT: [[OPT3LABEL]] |
| 45 | ;CHECK: rlwinm. {{[0-9]+}}, [[TAGREG]], 0, 28, 28 |
| 46 | ;CHECK-NEXT: beq 0, [[EXITLABEL]] |
| 47 | ;CHECK-NEXT: [[OPT4LABEL]] |
| 48 | ;CHECK: b [[EXITLABEL]] |
| 49 | |
Kyle Butt | efe56fe | 2017-01-11 19:55:19 +0000 | [diff] [blame] | 50 | define void @f(i32 %tag) { |
Kyle Butt | 0846e56 | 2016-10-11 20:36:43 +0000 | [diff] [blame] | 51 | entry: |
| 52 | br label %test1 |
| 53 | test1: |
| 54 | %tagbit1 = and i32 %tag, 1 |
| 55 | %tagbit1eq0 = icmp eq i32 %tagbit1, 0 |
| 56 | br i1 %tagbit1eq0, label %test2, label %optional1 |
| 57 | optional1: |
| 58 | call void @a() |
| 59 | call void @a() |
| 60 | call void @a() |
| 61 | call void @a() |
| 62 | br label %test2 |
| 63 | test2: |
| 64 | %tagbit2 = and i32 %tag, 2 |
| 65 | %tagbit2eq0 = icmp eq i32 %tagbit2, 0 |
| 66 | br i1 %tagbit2eq0, label %test3, label %optional2 |
| 67 | optional2: |
| 68 | call void @b() |
| 69 | call void @b() |
| 70 | call void @b() |
| 71 | call void @b() |
| 72 | br label %test3 |
| 73 | test3: |
| 74 | %tagbit3 = and i32 %tag, 4 |
| 75 | %tagbit3eq0 = icmp eq i32 %tagbit3, 0 |
| 76 | br i1 %tagbit3eq0, label %test4, label %optional3 |
| 77 | optional3: |
| 78 | call void @c() |
| 79 | call void @c() |
| 80 | call void @c() |
| 81 | call void @c() |
| 82 | br label %test4 |
| 83 | test4: |
| 84 | %tagbit4 = and i32 %tag, 8 |
| 85 | %tagbit4eq0 = icmp eq i32 %tagbit4, 0 |
| 86 | br i1 %tagbit4eq0, label %exit, label %optional4 |
| 87 | optional4: |
| 88 | call void @d() |
| 89 | call void @d() |
| 90 | call void @d() |
| 91 | call void @d() |
| 92 | br label %exit |
| 93 | exit: |
| 94 | ret void |
| 95 | } |
| 96 | |
| 97 | declare void @a() |
| 98 | declare void @b() |
| 99 | declare void @c() |
| 100 | declare void @d() |