1 ; Test switch instructions. 2 3 ; RUN: %p2i -i %s --insts | FileCheck %s 4 ; RUN: %p2i -i %s --args -notranslate -timing | \ 5 ; RUN: FileCheck --check-prefix=NOIR %s 6 7 define internal void @testDefaultSwitch(i32 %a) { 8 entry: 9 switch i32 %a, label %exit [ 10 ] 11 exit: 12 ret void 13 } 14 15 ; CHECK: define internal void @testDefaultSwitch(i32 %a) { 16 ; CHECK-NEXT: entry: 17 ; CHECK-NEXT: switch i32 %a, label %exit [ 18 ; CHECK-NEXT: ] 19 ; CHECK-NEXT: exit: 20 ; CHECK-NEXT: ret void 21 ; CHECK-NEXT: } 22 23 define internal i32 @testSwitch(i32 %a) { 24 entry: 25 switch i32 %a, label %sw.default [ 26 i32 1, label %sw.epilog 27 i32 2, label %sw.epilog 28 i32 3, label %sw.epilog 29 i32 7, label %sw.bb1 30 i32 8, label %sw.bb1 31 i32 15, label %sw.bb2 32 i32 14, label %sw.bb2 33 ] 34 35 sw.default: ; preds = %entry 36 %add = add i32 %a, 27 37 br label %sw.epilog 38 39 sw.bb1: ; preds = %entry, %entry 40 %phitmp = sub i32 21, %a 41 br label %sw.bb2 42 43 sw.bb2: ; preds = %sw.bb1, %entry, %entry 44 %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ] 45 br label %sw.epilog 46 47 sw.epilog: ; preds = %sw.bb2, %sw.default, %entry, %entry, %entry 48 %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ] 49 ret i32 %result.1 50 } 51 52 ; CHECK-NEXT: define internal i32 @testSwitch(i32 %a) { 53 ; CHECK-NEXT: entry: 54 ; CHECK-NEXT: switch i32 %a, label %sw.default [ 55 ; CHECK-NEXT: i32 1, label %sw.epilog 56 ; CHECK-NEXT: i32 2, label %sw.epilog 57 ; CHECK-NEXT: i32 3, label %sw.epilog 58 ; CHECK-NEXT: i32 7, label %sw.bb1 59 ; CHECK-NEXT: i32 8, label %sw.bb1 60 ; CHECK-NEXT: i32 15, label %sw.bb2 61 ; CHECK-NEXT: i32 14, label %sw.bb2 62 ; CHECK-NEXT: ] 63 ; CHECK-NEXT: sw.default: 64 ; CHECK-NEXT: %add = add i32 %a, 27 65 ; CHECK-NEXT: br label %sw.epilog 66 ; CHECK-NEXT: sw.bb1: 67 ; CHECK-NEXT: %phitmp = sub i32 21, %a 68 ; CHECK-NEXT: br label %sw.bb2 69 ; CHECK-NEXT: sw.bb2: 70 ; CHECK-NEXT: %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ] 71 ; CHECK-NEXT: br label %sw.epilog 72 ; CHECK-NEXT: sw.epilog: 73 ; CHECK-NEXT: %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ] 74 ; CHECK-NEXT: ret i32 %result.1 75 ; CHECK-NEXT: } 76 77 define internal void @testSignedI32Values(i32 %a) { 78 entry: 79 switch i32 %a, label %labelDefault [ 80 i32 0, label %label0 81 i32 -1, label %labelM1 82 i32 3, label %labelOther 83 i32 -3, label %labelOther 84 i32 -2147483648, label %labelMin ; min signed i32 85 i32 2147483647, label %labelMax ; max signed i32 86 ] 87 labelDefault: 88 ret void 89 label0: 90 ret void 91 labelM1: 92 ret void 93 labelMin: 94 ret void 95 labelMax: 96 ret void 97 labelOther: 98 ret void 99 } 100 101 ; CHECK-NEXT: define internal void @testSignedI32Values(i32 %a) { 102 ; CHECK-NEXT: entry: 103 ; CHECK-NEXT: switch i32 %a, label %labelDefault [ 104 ; CHECK-NEXT: i32 0, label %label0 105 ; CHECK-NEXT: i32 -1, label %labelM1 106 ; CHECK-NEXT: i32 3, label %labelOther 107 ; CHECK-NEXT: i32 -3, label %labelOther 108 ; CHECK-NEXT: i32 -2147483648, label %labelMin 109 ; CHECK-NEXT: i32 2147483647, label %labelMax 110 ; CHECK-NEXT: ] 111 ; CHECK-NEXT: labelDefault: 112 ; CHECK-NEXT: ret void 113 ; CHECK-NEXT: label0: 114 ; CHECK-NEXT: ret void 115 ; CHECK-NEXT: labelM1: 116 ; CHECK-NEXT: ret void 117 ; CHECK-NEXT: labelMin: 118 ; CHECK-NEXT: ret void 119 ; CHECK-NEXT: labelMax: 120 ; CHECK-NEXT: ret void 121 ; CHECK-NEXT: labelOther: 122 ; CHECK-NEXT: ret void 123 ; CHECK-NEXT: } 124 125 ; Test values that cross signed i32 size boundaries. 126 define internal void @testSignedI32Boundary(i32 %a) { 127 entry: 128 switch i32 %a, label %exit [ 129 i32 -2147483649, label %exit ; min signed i32 - 1 130 i32 2147483648, label %exit ; max signed i32 + 1 131 ] 132 exit: 133 ret void 134 } 135 136 ; CHECK-NEXT: define internal void @testSignedI32Boundary(i32 %a) { 137 ; CHECK-NEXT: entry: 138 ; CHECK-NEXT: switch i32 %a, label %exit [ 139 ; CHECK-NEXT: i32 2147483647, label %exit 140 ; CHECK-NEXT: i32 -2147483648, label %exit 141 ; CHECK-NEXT: ] 142 ; CHECK-NEXT: exit: 143 ; CHECK-NEXT: ret void 144 ; CHECK-NEXT: } 145 146 define internal void @testUnsignedI32Values(i32 %a) { 147 entry: 148 switch i32 %a, label %exit [ 149 i32 0, label %exit 150 i32 2147483647, label %exit ; max signed i32 151 i32 4294967295, label %exit ; max unsigned i32 152 ] 153 exit: 154 ret void 155 } 156 157 ; CHECK-NEXT: define internal void @testUnsignedI32Values(i32 %a) { 158 ; CHECK-NEXT: entry: 159 ; CHECK-NEXT: switch i32 %a, label %exit [ 160 ; CHECK-NEXT: i32 0, label %exit 161 ; CHECK-NEXT: i32 2147483647, label %exit 162 ; ; Note that -1 is signed version of 4294967295 163 ; CHECK-NEXT: i32 -1, label %exit 164 ; CHECK-NEXT: ] 165 ; CHECK-NEXT: exit: 166 ; CHECK-NEXT: ret void 167 ; CHECK-NEXT: } 168 169 ; Test values that cross unsigned i32 boundaries. 170 define internal void @testUnsignedI32Boundary(i32 %a) { 171 entry: 172 switch i32 %a, label %exit [ 173 i32 4294967296, label %exit ; max unsigned i32 + 1 174 ] 175 exit: 176 ret void 177 } 178 179 ; CHECK-NEXT: define internal void @testUnsignedI32Boundary(i32 %a) { 180 ; CHECK-NEXT: entry: 181 ; CHECK-NEXT: switch i32 %a, label %exit [ 182 ; CHECK-NEXT: i32 0, label %exit 183 ; CHECK-NEXT: ] 184 ; CHECK-NEXT: exit: 185 ; CHECK-NEXT: ret void 186 ; CHECK-NEXT: } 187 188 define internal void @testSignedI64Values(i64 %a) { 189 entry: 190 switch i64 %a, label %exit [ 191 i64 0, label %exit 192 i64 -9223372036854775808, label %exit ; min signed i64 193 i64 9223372036854775807, label %exit ; max signed i64 194 ] 195 exit: 196 ret void 197 } 198 199 ; CHECK-NEXT: define internal void @testSignedI64Values(i64 %a) { 200 ; CHECK-NEXT: entry: 201 ; CHECK-NEXT: switch i64 %a, label %exit [ 202 ; CHECK-NEXT: i64 0, label %exit 203 ; CHECK-NEXT: i64 -9223372036854775808, label %exit 204 ; CHECK-NEXT: i64 9223372036854775807, label %exit 205 ; CHECK-NEXT: ] 206 ; CHECK-NEXT: exit: 207 ; CHECK-NEXT: ret void 208 ; CHECK-NEXT: } 209 210 ; Test values that cross signed i64 size boundaries. 211 define internal void @testSignedI64Boundary(i64 %a) { 212 entry: 213 switch i64 %a, label %exit [ 214 i64 0, label %exit 215 i64 -9223372036854775809, label %exit ; min signed i64 - 1 216 i64 9223372036854775808, label %exit ; max signed i64 + 1 217 ] 218 exit: 219 ret void 220 } 221 222 ; CHECK-NEXT: define internal void @testSignedI64Boundary(i64 %a) { 223 ; CHECK-NEXT: entry: 224 ; CHECK-NEXT: switch i64 %a, label %exit [ 225 ; CHECK-NEXT: i64 0, label %exit 226 ; CHECK-NEXT: i64 9223372036854775807, label %exit 227 ; CHECK-NEXT: i64 -9223372036854775808, label %exit 228 ; CHECK-NEXT: ] 229 ; CHECK-NEXT: exit: 230 ; CHECK-NEXT: ret void 231 ; CHECK-NEXT: } 232 233 define internal void @testUnsignedI64Values(i64 %a) { 234 entry: 235 switch i64 %a, label %exit [ 236 i64 0, label %exit 237 i64 9223372036854775807, label %exit ; max signed i64 238 i64 18446744073709551615, label %exit ; max unsigned i64 239 ] 240 exit: 241 ret void 242 } 243 244 ; CHECK-NEXT: define internal void @testUnsignedI64Values(i64 %a) { 245 ; CHECK-NEXT: entry: 246 ; CHECK-NEXT: switch i64 %a, label %exit [ 247 ; CHECK-NEXT: i64 0, label %exit 248 ; CHECK-NEXT: i64 9223372036854775807, label %exit 249 ; CHECK-NEXT: i64 -1, label %exit 250 ; CHECK-NEXT: ] 251 ; CHECK-NEXT: exit: 252 ; CHECK-NEXT: ret void 253 ; CHECK-NEXT: } 254 255 ; Test values that cross unsigned i64 size boundaries. 256 define internal void @testUnsignedI64Boundary(i64 %a) { 257 entry: 258 switch i64 %a, label %exit [ 259 i64 18446744073709551616, label %exit ; max unsigned i64 + 1 260 ] 261 exit: 262 ret void 263 } 264 265 ; CHECK-NEXT: define internal void @testUnsignedI64Boundary(i64 %a) { 266 ; CHECK-NEXT: entry: 267 ; CHECK-NEXT: switch i64 %a, label %exit [ 268 ; CHECK-NEXT: i64 0, label %exit 269 ; CHECK-NEXT: ] 270 ; CHECK-NEXT: exit: 271 ; CHECK-NEXT: ret void 272 ; CHECK-NEXT: } 273 274 define internal void @testSignedI16Values(i32 %p) { 275 entry: 276 %a = trunc i32 %p to i16 277 switch i16 %a, label %exit [ 278 i16 0, label %exit 279 i16 -1, label %exit 280 i16 3, label %exit 281 i16 -3, label %exit 282 i16 -32768, label %exit ; min signed i16 283 i16 32767, label %exit ; max unsigned i16 284 ] 285 exit: 286 ret void 287 } 288 289 ; CHECK-NEXT: define internal void @testSignedI16Values(i32 %p) { 290 ; CHECK-NEXT: entry: 291 ; CHECK-NEXT: %a = trunc i32 %p to i16 292 ; CHECK-NEXT: switch i16 %a, label %exit [ 293 ; CHECK-NEXT: i16 0, label %exit 294 ; CHECK-NEXT: i16 -1, label %exit 295 ; CHECK-NEXT: i16 3, label %exit 296 ; CHECK-NEXT: i16 -3, label %exit 297 ; CHECK-NEXT: i16 -32768, label %exit 298 ; CHECK-NEXT: i16 32767, label %exit 299 ; CHECK-NEXT: ] 300 ; CHECK-NEXT: exit: 301 ; CHECK-NEXT: ret void 302 ; CHECK-NEXT: } 303 304 ; Test values that cross signed i16 size boundaries. 305 define internal void @testSignedI16Boundary(i32 %p) { 306 entry: 307 %a = trunc i32 %p to i16 308 switch i16 %a, label %exit [ 309 i16 -32769, label %exit ; min signed i16 - 1 310 i16 32768, label %exit ; max unsigned i16 + 1 311 ] 312 exit: 313 ret void 314 } 315 316 ; CHECK-NEXT: define internal void @testSignedI16Boundary(i32 %p) { 317 ; CHECK-NEXT: entry: 318 ; CHECK-NEXT: %a = trunc i32 %p to i16 319 ; CHECK-NEXT: switch i16 %a, label %exit [ 320 ; CHECK-NEXT: i16 32767, label %exit 321 ; CHECK-NEXT: i16 -32768, label %exit 322 ; CHECK-NEXT: ] 323 ; CHECK-NEXT: exit: 324 ; CHECK-NEXT: ret void 325 ; CHECK-NEXT: } 326 327 define internal void @testUnsignedI16Values(i32 %p) { 328 entry: 329 %a = trunc i32 %p to i16 330 switch i16 %a, label %exit [ 331 i16 0, label %exit 332 i16 32767, label %exit ; max signed i16 333 i16 65535, label %exit ; max unsigned i16 334 ] 335 exit: 336 ret void 337 } 338 339 ; CHECK-NEXT: define internal void @testUnsignedI16Values(i32 %p) { 340 ; CHECK-NEXT: entry: 341 ; CHECK-NEXT: %a = trunc i32 %p to i16 342 ; CHECK-NEXT: switch i16 %a, label %exit [ 343 ; CHECK-NEXT: i16 0, label %exit 344 ; CHECK-NEXT: i16 32767, label %exit 345 ; ; Note that -1 is signed version of 65535 346 ; CHECK-NEXT: i16 -1, label %exit 347 ; CHECK-NEXT: ] 348 ; CHECK-NEXT: exit: 349 ; CHECK-NEXT: ret void 350 ; CHECK-NEXT: } 351 352 ; Test values that cross unsigned i16 size boundaries. 353 define internal void @testUnsignedI16Boundary(i32 %p) { 354 entry: 355 %a = trunc i32 %p to i16 356 switch i16 %a, label %exit [ 357 i16 65536, label %exit ; max unsigned i16 + 1 358 ] 359 exit: 360 ret void 361 } 362 363 ; CHECK-NEXT: define internal void @testUnsignedI16Boundary(i32 %p) { 364 ; CHECK-NEXT: entry: 365 ; CHECK-NEXT: %a = trunc i32 %p to i16 366 ; CHECK-NEXT: switch i16 %a, label %exit [ 367 ; CHECK-NEXT: i16 0, label %exit 368 ; CHECK-NEXT: ] 369 ; CHECK-NEXT: exit: 370 ; CHECK-NEXT: ret void 371 ; CHECK-NEXT: } 372 373 define internal void @testSignedI8Values(i32 %p) { 374 entry: 375 %a = trunc i32 %p to i8 376 switch i8 %a, label %exit [ 377 i8 0, label %exit 378 i8 -1, label %exit 379 i8 3, label %exit 380 i8 -3, label %exit 381 i8 -128, label %exit ; min signed i8 382 i8 127, label %exit ; max unsigned i8 383 ] 384 exit: 385 ret void 386 } 387 388 ; CHECK-NEXT: define internal void @testSignedI8Values(i32 %p) { 389 ; CHECK-NEXT: entry: 390 ; CHECK-NEXT: %a = trunc i32 %p to i8 391 ; CHECK-NEXT: switch i8 %a, label %exit [ 392 ; CHECK-NEXT: i8 0, label %exit 393 ; CHECK-NEXT: i8 -1, label %exit 394 ; CHECK-NEXT: i8 3, label %exit 395 ; CHECK-NEXT: i8 -3, label %exit 396 ; CHECK-NEXT: i8 -128, label %exit 397 ; CHECK-NEXT: i8 127, label %exit 398 ; CHECK-NEXT: ] 399 ; CHECK-NEXT: exit: 400 ; CHECK-NEXT: ret void 401 ; CHECK-NEXT: } 402 403 ; Test values that cross signed i8 size boundaries. 404 define internal void @testSignedI8Boundary(i32 %p) { 405 entry: 406 %a = trunc i32 %p to i8 407 switch i8 %a, label %exit [ 408 i8 -129, label %exit ; min signed i8 - 1 409 i8 128, label %exit ; max unsigned i8 + 1 410 ] 411 exit: 412 ret void 413 } 414 415 ; CHECK-NEXT: define internal void @testSignedI8Boundary(i32 %p) { 416 ; CHECK-NEXT: entry: 417 ; CHECK-NEXT: %a = trunc i32 %p to i8 418 ; CHECK-NEXT: switch i8 %a, label %exit [ 419 ; CHECK-NEXT: i8 127, label %exit 420 ; CHECK-NEXT: i8 -128, label %exit 421 ; CHECK-NEXT: ] 422 ; CHECK-NEXT: exit: 423 ; CHECK-NEXT: ret void 424 ; CHECK-NEXT: } 425 426 427 define internal void @testUnsignedI8Values(i32 %p) { 428 entry: 429 %a = trunc i32 %p to i8 430 switch i8 %a, label %exit [ 431 i8 0, label %exit 432 i8 127, label %exit ; max signed i8 433 i8 255, label %exit ; max unsigned i8 434 ] 435 exit: 436 ret void 437 } 438 439 ; CHECK-NEXT: define internal void @testUnsignedI8Values(i32 %p) { 440 ; CHECK-NEXT: entry: 441 ; CHECK-NEXT: %a = trunc i32 %p to i8 442 ; CHECK-NEXT: switch i8 %a, label %exit [ 443 ; CHECK-NEXT: i8 0, label %exit 444 ; CHECK-NEXT: i8 127, label %exit 445 ; ; Note that -1 is signed version of 255 446 ; CHECK-NEXT: i8 -1, label %exit 447 ; CHECK-NEXT: ] 448 ; CHECK-NEXT: exit: 449 ; CHECK-NEXT: ret void 450 ; CHECK-NEXT: } 451 452 ; Test values that cross unsigned i8 size boundaries. 453 define internal void @testUnsignedI8Boundary(i32 %p) { 454 entry: 455 %a = trunc i32 %p to i8 456 switch i8 %a, label %exit [ 457 i8 256, label %exit ; max unsigned i8 458 ] 459 exit: 460 ret void 461 } 462 463 ; CHECK-NEXT: define internal void @testUnsignedI8Boundary(i32 %p) { 464 ; CHECK-NEXT: entry: 465 ; CHECK-NEXT: %a = trunc i32 %p to i8 466 ; CHECK-NEXT: switch i8 %a, label %exit [ 467 ; CHECK-NEXT: i8 0, label %exit 468 ; CHECK-NEXT: ] 469 ; CHECK-NEXT: exit: 470 ; CHECK-NEXT: ret void 471 ; CHECK-NEXT: } 472 473 define internal void @testI1Values(i32 %p) { 474 entry: 475 %a = trunc i32 %p to i1 476 switch i1 %a, label %exit [ 477 i1 true, label %exit 478 i1 false, label %exit 479 ] 480 exit: 481 ret void 482 } 483 484 ; CHECK-NEXT: define internal void @testI1Values(i32 %p) { 485 ; CHECK-NEXT: entry: 486 ; CHECK-NEXT: %a = trunc i32 %p to i1 487 ; CHECK-NEXT: switch i1 %a, label %exit [ 488 ; CHECK-NEXT: i1 -1, label %exit 489 ; CHECK-NEXT: i1 0, label %exit 490 ; CHECK-NEXT: ] 491 ; CHECK-NEXT: exit: 492 ; CHECK-NEXT: ret void 493 ; CHECK-NEXT: } 494 495 ; NOIR: Total across all functions 496