Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 1 | ; This tests a switch statement, including multiple branches to the |
| 2 | ; same label which also results in phi instructions with multiple |
| 3 | ; entries for the same incoming edge. |
| 4 | |
Andrew Scull | 86df4e9 | 2015-07-30 13:54:44 -0700 | [diff] [blame] | 5 | ; For x86 see adv-switch-opt.ll |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 6 | |
Andrew Scull | fdc54db | 2015-06-29 11:21:18 -0700 | [diff] [blame] | 7 | ; TODO(jvoung): Update to -02 once the phi assignments is done for ARM |
Jan Voung | 6ec369e | 2015-06-30 11:03:15 -0700 | [diff] [blame] | 8 | ; RUN: %if --need=target_ARM32 --need=allow_dump \ |
| 9 | ; RUN: --command %p2i --filetype=asm --assemble --disassemble \ |
| 10 | ; RUN: --target arm32 -i %s --args -Om1 --skip-unimplemented \ |
| 11 | ; RUN: | %if --need=target_ARM32 --need=allow_dump \ |
| 12 | ; RUN: --command FileCheck --check-prefix ARM32 %s |
Andrew Scull | fdc54db | 2015-06-29 11:21:18 -0700 | [diff] [blame] | 13 | |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 14 | define i32 @testSwitch(i32 %a) { |
| 15 | entry: |
| 16 | switch i32 %a, label %sw.default [ |
| 17 | i32 1, label %sw.epilog |
| 18 | i32 2, label %sw.epilog |
| 19 | i32 3, label %sw.epilog |
| 20 | i32 7, label %sw.bb1 |
| 21 | i32 8, label %sw.bb1 |
| 22 | i32 15, label %sw.bb2 |
| 23 | i32 14, label %sw.bb2 |
| 24 | ] |
| 25 | |
| 26 | sw.default: ; preds = %entry |
| 27 | %add = add i32 %a, 27 |
| 28 | br label %sw.epilog |
| 29 | |
| 30 | sw.bb1: ; preds = %entry, %entry |
| 31 | %phitmp = sub i32 21, %a |
| 32 | br label %sw.bb2 |
| 33 | |
| 34 | sw.bb2: ; preds = %sw.bb1, %entry, %entry |
| 35 | %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ] |
| 36 | br label %sw.epilog |
| 37 | |
| 38 | sw.epilog: ; preds = %sw.bb2, %sw.default, %entry, %entry, %entry |
| 39 | %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ] |
| 40 | ret i32 %result.1 |
| 41 | } |
| 42 | |
Jim Stichnoth | ef8cf0e | 2014-08-26 22:16:29 -0700 | [diff] [blame] | 43 | ; Check for a valid addressing mode when the switch operand is an |
| 44 | ; immediate. It's important that there is exactly one case, because |
| 45 | ; for two or more cases the source operand is legalized into a |
| 46 | ; register. |
| 47 | define i32 @testSwitchImm() { |
| 48 | entry: |
| 49 | switch i32 10, label %sw.default [ |
| 50 | i32 1, label %sw.default |
| 51 | ] |
| 52 | |
| 53 | sw.default: |
| 54 | ret i32 20 |
| 55 | } |
Andrew Scull | fdc54db | 2015-06-29 11:21:18 -0700 | [diff] [blame] | 56 | ; ARM32-LABEL: testSwitchImm |
| 57 | ; ARM32: cmp {{r[0-9]+}}, #1 |
| 58 | ; ARM32-NEXT: beq |
| 59 | ; ARM32-NEXT: b |
| 60 | |
Jim Stichnoth | 2daadb7 | 2014-11-03 19:57:24 -0800 | [diff] [blame] | 61 | ; Test for correct 64-bit lowering. |
| 62 | define internal i32 @testSwitch64(i64 %a) { |
| 63 | entry: |
| 64 | switch i64 %a, label %sw.default [ |
| 65 | i64 123, label %return |
| 66 | i64 234, label %sw.bb1 |
| 67 | i64 345, label %sw.bb2 |
| 68 | i64 78187493520, label %sw.bb3 |
| 69 | ] |
| 70 | |
| 71 | sw.bb1: ; preds = %entry |
| 72 | br label %return |
| 73 | |
| 74 | sw.bb2: ; preds = %entry |
| 75 | br label %return |
| 76 | |
| 77 | sw.bb3: ; preds = %entry |
| 78 | br label %return |
| 79 | |
| 80 | sw.default: ; preds = %entry |
| 81 | br label %return |
| 82 | |
| 83 | return: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %entry |
| 84 | %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, %sw.bb1 ], [ 1, %entry ] |
| 85 | ret i32 %retval.0 |
| 86 | } |
Andrew Scull | fdc54db | 2015-06-29 11:21:18 -0700 | [diff] [blame] | 87 | ; ARM32-LABEL: testSwitch64 |
| 88 | ; ARM32: cmp {{r[0-9]+}}, #123 |
| 89 | ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 |
| 90 | ; ARM32-NEXT: beq |
| 91 | ; ARM32: cmp {{r[0-9]+}}, #234 |
| 92 | ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 |
| 93 | ; ARM32-NEXT: beq |
| 94 | ; ARM32: movw [[REG:r[0-9]+]], #345 |
| 95 | ; ARM32-NEXT: cmp {{r[0-9]+}}, [[REG]] |
| 96 | ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 |
| 97 | ; ARM32-NEXT: beq |
| 98 | ; ARM32: movw [[REG:r[0-9]+]], #30864 |
| 99 | ; ARM32-NEXT: movt [[REG]], #13398 |
| 100 | ; ARM32-NEXT: cmp {{r[0-9]+}}, [[REG]] |
| 101 | ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #18 |
| 102 | ; ARM32-NEXT: beq |
| 103 | ; ARM32-NEXT: b |
| 104 | |
Jim Stichnoth | 2daadb7 | 2014-11-03 19:57:24 -0800 | [diff] [blame] | 105 | ; Similar to testSwitchImm, make sure proper addressing modes are |
| 106 | ; used. In reality, this is tested by running the output through the |
| 107 | ; assembler. |
| 108 | define i32 @testSwitchImm64() { |
| 109 | entry: |
| 110 | switch i64 10, label %sw.default [ |
| 111 | i64 1, label %sw.default |
| 112 | ] |
| 113 | |
| 114 | sw.default: |
| 115 | ret i32 20 |
| 116 | } |
Andrew Scull | fdc54db | 2015-06-29 11:21:18 -0700 | [diff] [blame] | 117 | ; ARM32-LABEL: testSwitchImm64 |
| 118 | ; ARM32: cmp {{r[0-9]+}}, #1 |
| 119 | ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 |
| 120 | ; ARM32-NEXT: beq [[ADDR:[0-9a-f]+]] |
| 121 | ; ARM32-NEXT: b [[ADDR]] |
| 122 | |
Jan Voung | fbdd244 | 2015-07-15 12:36:20 -0700 | [diff] [blame] | 123 | define i32 @testSwitchUndef64() { |
| 124 | entry: |
| 125 | switch i64 undef, label %sw.default [ |
| 126 | i64 1, label %sw.default |
| 127 | ] |
| 128 | |
| 129 | sw.default: |
| 130 | ret i32 20 |
| 131 | } |
Jan Voung | fbdd244 | 2015-07-15 12:36:20 -0700 | [diff] [blame] | 132 | ; ARM32-LABEL: testSwitchUndef64 |
| 133 | ; ARM32: movw {{.*}}, #0 |
| 134 | ; ARM32: movw {{.*}}, #0 |