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