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 5 ; For x86 see adv-switch-opt.ll 6 7 ; TODO(jvoung): Update to -02 once the phi assignments is done for ARM 8 ; RUN: %if --need=target_ARM32 \ 9 ; RUN: --command %p2i --filetype=obj --disassemble \ 10 ; RUN: --target arm32 -i %s --args -Om1 \ 11 ; RUN: | %if --need=target_ARM32 \ 12 ; RUN: --command FileCheck --check-prefix ARM32 %s 13 14 ; RUN: %if --need=target_MIPS32 --need=allow_dump \ 15 ; RUN: --command %p2i --filetype=asm --assemble --disassemble \ 16 ; RUN: --target mips32 -i %s --args -Om1 \ 17 ; RUN: -allow-externally-defined-symbols \ 18 ; RUN: | %if --need=target_MIPS32 --need=allow_dump \ 19 ; RUN: --command FileCheck --check-prefix MIPS32 %s 20 21 define internal i32 @testSwitch(i32 %a) { 22 entry: 23 switch i32 %a, label %sw.default [ 24 i32 1, label %sw.epilog 25 i32 2, label %sw.epilog 26 i32 3, label %sw.epilog 27 i32 7, label %sw.bb1 28 i32 8, label %sw.bb1 29 i32 15, label %sw.bb2 30 i32 14, label %sw.bb2 31 ] 32 33 sw.default: ; preds = %entry 34 %add = add i32 %a, 27 35 br label %sw.epilog 36 37 sw.bb1: ; preds = %entry, %entry 38 %phitmp = sub i32 21, %a 39 br label %sw.bb2 40 41 sw.bb2: ; preds = %sw.bb1, %entry, %entry 42 %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ] 43 br label %sw.epilog 44 45 sw.epilog: ; preds = %sw.bb2, %sw.default, %entry, %entry, %entry 46 %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ] 47 ret i32 %result.1 48 } 49 50 ; MIPS32-LABEL: testSwitch 51 ; MIPS32: li {{.*}},1 52 ; MIPS32: li {{.*}},17 53 ; MIPS32: li {{.*}},1 54 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <[[SW_EPILOG:.*]]> 55 ; MIPS32: li {{.*}},2 56 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <[[SW_EPILOG]]> 57 ; MIPS32: li {{.*}},3 58 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <[[SW_EPILOG]]> 59 ; MIPS32: li {{.*}},7 60 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <[[SW_BB1:.*]]> 61 ; MIPS32: li {{.*}},8 62 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <[[SW_BB1]]> 63 ; MIPS32: li {{.*}},15 64 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <[[SW_BB2:.*]]> 65 ; MIPS32: li {{.*}},14 66 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <[[SW_BB2]]> 67 ; MIPS32: b {{.*}} <[[SW_DEFAULT:.*]]> 68 ; MIPS32: <[[SW_DEFAULT]]> 69 ; MIPS32: addiu {{.*}},27 70 ; MIPS32: b {{.*}} <[[SW_EPILOG]]> 71 ; MIPS32: <[[SW_BB1]]> 72 ; MIPS32: li {{.*}},21 73 ; MIPS32: b {{.*}} <[[SW_BB2]]> 74 ; MIPS32: <[[SW_BB2]]> 75 ; MIPS32: b {{.*}} <[[SW_EPILOG]]> 76 ; MIPS32: <[[SW_EPILOG]]> 77 ; MIPS32: jr ra 78 79 ; Check for a valid addressing mode when the switch operand is an 80 ; immediate. It's important that there is exactly one case, because 81 ; for two or more cases the source operand is legalized into a 82 ; register. 83 define internal i32 @testSwitchImm() { 84 entry: 85 switch i32 10, label %sw.default [ 86 i32 1, label %sw.default 87 ] 88 89 sw.default: 90 ret i32 20 91 } 92 ; ARM32-LABEL: testSwitchImm 93 ; ARM32: cmp {{r[0-9]+}}, #1 94 ; ARM32-NEXT: beq 95 ; ARM32-NEXT: b 96 97 ; MIPS32-LABEL: testSwitchImm 98 ; MIPS32: li {{.*}},10 99 ; MIPS32: li {{.*}},1 100 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <.LtestSwitchImm$sw.default> 101 ; MIPS32: .LtestSwitchImm$sw.default 102 ; MIPS32: li v0,20 103 ; MIPS32: jr ra 104 105 ; Test for correct 64-bit lowering. 106 define internal i32 @testSwitch64(i64 %a) { 107 entry: 108 switch i64 %a, label %sw.default [ 109 i64 123, label %return 110 i64 234, label %sw.bb1 111 i64 345, label %sw.bb2 112 i64 78187493520, label %sw.bb3 113 ] 114 115 sw.bb1: ; preds = %entry 116 br label %return 117 118 sw.bb2: ; preds = %entry 119 br label %return 120 121 sw.bb3: ; preds = %entry 122 br label %return 123 124 sw.default: ; preds = %entry 125 br label %return 126 127 return: ; preds = %sw.default, %sw.bb3, %sw.bb2, %sw.bb1, %entry 128 %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, %sw.bb1 ], [ 1, %entry ] 129 ret i32 %retval.0 130 } 131 ; ARM32-LABEL: testSwitch64 132 ; ARM32: cmp {{r[0-9]+}}, #123 133 ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 134 ; ARM32-NEXT: beq 135 ; ARM32: cmp {{r[0-9]+}}, #234 136 ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 137 ; ARM32-NEXT: beq 138 ; ARM32: movw [[REG:r[0-9]+]], #345 139 ; ARM32-NEXT: cmp {{r[0-9]+}}, [[REG]] 140 ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 141 ; ARM32-NEXT: beq 142 ; ARM32: movw [[REG:r[0-9]+]], #30864 143 ; ARM32-NEXT: movt [[REG]], #13398 144 ; ARM32-NEXT: cmp {{r[0-9]+}}, [[REG]] 145 ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #18 146 ; ARM32-NEXT: beq 147 ; ARM32-NEXT: b 148 149 ; MIPS32-LABEL: testSwitch64 150 ; MIPS32: bne {{.*}},{{.*}},{{.*}} <.LtestSwitch64$local$__0> 151 ; MIPS32: li {{.*}},123 152 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <.LtestSwitch64$return> 153 ; MIPS32: .LtestSwitch64$local$__0 154 ; MIPS32: li {{.*}},0 155 ; MIPS32: bne {{.*}},{{.*}},{{.*}} <.LtestSwitch64$local$__1> 156 ; MIPS32: li {{.*}},234 157 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <.LtestSwitch64$sw.bb1> 158 ; MIPS32: .LtestSwitch64$local$__1 159 ; MIPS32: li {{.*}},0 160 ; MIPS32: bne {{.*}},{{.*}},{{.*}} <.LtestSwitch64$local$__2> 161 ; MIPS32: li {{.*}},345 162 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <.LtestSwitch64$sw.bb2> 163 ; MIPS32: .LtestSwitch64$local$__2 164 ; MIPS32: li {{.*}},18 165 ; MIPS32: bne {{.*}},{{.*}},{{.*}} <.LtestSwitch64$local$__3> 166 ; MIPS32: lui {{.*}},0x3456 167 ; MIPS32: ori {{.*}},{{.*}},0x7890 168 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <.LtestSwitch64$sw.bb3> 169 ; MIPS32: .LtestSwitch64$local$__3 170 ; MIPS32: b {{.*}} <.LtestSwitch64$sw.default> 171 ; MIPS32: .LtestSwitch64$sw.bb1 172 ; MIPS32: li {{.*}},2 173 ; MIPS32: b {{.*}} <.LtestSwitch64$return> 174 ; MIPS32: .LtestSwitch64$sw.bb2 175 ; MIPS32: li {{.*}},3 176 ; MIPS32: b {{.*}} <.LtestSwitch64$return> 177 ; MIPS32: .LtestSwitch64$sw.bb3 178 ; MIPS32: li {{.*}},4 179 ; MIPS32: b {{.*}} <.LtestSwitch64$return> 180 ; MIPS32: .LtestSwitch64$sw.default 181 ; MIPS32: li {{.*}},5 182 ; MIPS32: b {{.*}} <.LtestSwitch64$return> 183 ; MIPS32: .LtestSwitch64$return 184 ; MIPS32: jr ra 185 186 ; Similar to testSwitchImm, make sure proper addressing modes are 187 ; used. In reality, this is tested by running the output through the 188 ; assembler. 189 define internal i32 @testSwitchImm64() { 190 entry: 191 switch i64 10, label %sw.default [ 192 i64 1, label %sw.default 193 ] 194 195 sw.default: 196 ret i32 20 197 } 198 ; ARM32-LABEL: testSwitchImm64 199 ; ARM32: cmp {{r[0-9]+}}, #1 200 ; ARM32-NEXT: cmpeq {{r[0-9]+}}, #0 201 ; ARM32-NEXT: beq [[ADDR:[0-9a-f]+]] 202 ; ARM32-NEXT: b [[ADDR]] 203 204 ; MIPS32-LABEL: testSwitchImm64 205 ; MIPS32: li {{.*}},10 206 ; MIPS32: li {{.*}},0 207 ; MIPS32: li {{.*}},0 208 ; MIPS32: bne {{.*}},{{.*}},{{.*}} <.LtestSwitchImm64$local$__0> 209 ; MIPS32: li {{.*}},1 210 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <.LtestSwitchImm64$sw.default> 211 ; MIPS32: .LtestSwitchImm64$local$__0 212 ; MIPS32: b {{.*}} <.LtestSwitchImm64$sw.default> 213 ; MIPS32: .LtestSwitchImm64$sw.default 214 ; MIPS32: li {{.*}},20 215 ; MIPS32: jr ra 216 217 define internal i32 @testSwitchUndef64() { 218 entry: 219 switch i64 undef, label %sw.default [ 220 i64 1, label %sw.default 221 ] 222 223 sw.default: 224 ret i32 20 225 } 226 ; ARM32-LABEL: testSwitchUndef64 227 ; ARM32: mov {{.*}}, #0 228 ; ARM32: mov {{.*}}, #0 229 230 ; MIPS32-LABEL: testSwitchUndef64 231 ; MIPS32: li {{.*}},0 232 ; MIPS32: li {{.*}},0 233 ; MIPS32: li {{.*}},0 234 ; MIPS32: bne {{.*}},{{.*}},{{.*}} <.LtestSwitchUndef64$local$__0> 235 ; MIPS32: li {{.*}},1 236 ; MIPS32: beq {{.*}},{{.*}},{{.*}} <.LtestSwitchUndef64$sw.default> 237 ; MIPS32: .LtestSwitchUndef64$local$__0 238 ; MIPS32: b {{.*}} <.LtestSwitchUndef64$sw.default> 239 ; MIPS32: .LtestSwitchUndef64$sw.default 240 ; MIPS32: li {{.*}},20 241 ; MIPS32: jr ra 242