Home | History | Annotate | Download | only in reader_tests
      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