Home | History | Annotate | Download | only in AMDGPU
      1 ; RUN: opt -S -mtriple=amdgcn-- -codegenprepare < %s | FileCheck -check-prefix=OPT %s
      2 ; RUN: opt -S -mtriple=amdgcn-- -mcpu=tonga -codegenprepare < %s | FileCheck -check-prefix=OPT %s
      3 ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s
      4 ; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
      5 
      6 ; This particular case will actually be worse in terms of code size
      7 ; from sinking into both.
      8 
      9 ; OPT-LABEL: @sink_ubfe_i32(
     10 ; OPT: entry:
     11 ; OPT-NEXT: br i1
     12 
     13 ; OPT: bb0:
     14 ; OPT: %0 = lshr i32 %arg1, 8
     15 ; OPT-NEXT: %val0 = and i32 %0, 255
     16 ; OPT: br label
     17 
     18 ; OPT: bb1:
     19 ; OPT: %1 = lshr i32 %arg1, 8
     20 ; OPT-NEXT: %val1 = and i32 %1, 127
     21 ; OPT: br label
     22 
     23 ; OPT: ret:
     24 ; OPT: store
     25 ; OPT: ret
     26 
     27 
     28 ; GCN-LABEL: {{^}}sink_ubfe_i32:
     29 ; GCN-NOT: lshr
     30 ; GCN: s_cbranch_vccnz
     31 
     32 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80008
     33 ; GCN: BB0_2:
     34 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70008
     35 
     36 ; GCN: BB0_3:
     37 ; GCN: buffer_store_dword
     38 ; GCN: s_endpgm
     39 define void @sink_ubfe_i32(i32 addrspace(1)* %out, i32 %arg1) #0 {
     40 entry:
     41   %shr = lshr i32 %arg1, 8
     42   br i1 undef, label %bb0, label %bb1
     43 
     44 bb0:
     45   %val0 = and i32 %shr, 255
     46   store volatile i32 0, i32 addrspace(1)* undef
     47   br label %ret
     48 
     49 bb1:
     50   %val1 = and i32 %shr, 127
     51   store volatile i32 0, i32 addrspace(1)* undef
     52   br label %ret
     53 
     54 ret:
     55   %phi = phi i32 [ %val0, %bb0 ], [ %val1, %bb1 ]
     56   store i32 %phi, i32 addrspace(1)* %out
     57   ret void
     58 }
     59 
     60 ; OPT-LABEL: @sink_sbfe_i32(
     61 ; OPT: entry:
     62 ; OPT-NEXT: br i1
     63 
     64 ; OPT: bb0:
     65 ; OPT: %0 = ashr i32 %arg1, 8
     66 ; OPT-NEXT: %val0 = and i32 %0, 255
     67 ; OPT: br label
     68 
     69 ; OPT: bb1:
     70 ; OPT: %1 = ashr i32 %arg1, 8
     71 ; OPT-NEXT: %val1 = and i32 %1, 127
     72 ; OPT: br label
     73 
     74 ; OPT: ret:
     75 ; OPT: store
     76 ; OPT: ret
     77 
     78 ; GCN-LABEL: {{^}}sink_sbfe_i32:
     79 define void @sink_sbfe_i32(i32 addrspace(1)* %out, i32 %arg1) #0 {
     80 entry:
     81   %shr = ashr i32 %arg1, 8
     82   br i1 undef, label %bb0, label %bb1
     83 
     84 bb0:
     85   %val0 = and i32 %shr, 255
     86   store volatile i32 0, i32 addrspace(1)* undef
     87   br label %ret
     88 
     89 bb1:
     90   %val1 = and i32 %shr, 127
     91   store volatile i32 0, i32 addrspace(1)* undef
     92   br label %ret
     93 
     94 ret:
     95   %phi = phi i32 [ %val0, %bb0 ], [ %val1, %bb1 ]
     96   store i32 %phi, i32 addrspace(1)* %out
     97   ret void
     98 }
     99 
    100 
    101 ; OPT-LABEL: @sink_ubfe_i16(
    102 ; OPT: entry:
    103 ; OPT-NEXT: br i1
    104 
    105 ; OPT: bb0:
    106 ; OPT: %0 = lshr i16 %arg1, 4
    107 ; OPT-NEXT: %val0 = and i16 %0, 255
    108 ; OPT: br label
    109 
    110 ; OPT: bb1:
    111 ; OPT: %1 = lshr i16 %arg1, 4
    112 ; OPT-NEXT: %val1 = and i16 %1, 127
    113 ; OPT: br label
    114 
    115 ; OPT: ret:
    116 ; OPT: store
    117 ; OPT: ret
    118 
    119 
    120 ; GCN-LABEL: {{^}}sink_ubfe_i16:
    121 ; GCN-NOT: lshr
    122 ; GCN: s_cbranch_vccnz
    123 
    124 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80004
    125 ; GCN: BB2_2:
    126 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70004
    127 
    128 ; GCN: BB2_3:
    129 ; GCN: buffer_store_short
    130 ; GCN: s_endpgm
    131 define void @sink_ubfe_i16(i16 addrspace(1)* %out, i16 %arg1) #0 {
    132 entry:
    133   %shr = lshr i16 %arg1, 4
    134   br i1 undef, label %bb0, label %bb1
    135 
    136 bb0:
    137   %val0 = and i16 %shr, 255
    138   store volatile i16 0, i16 addrspace(1)* undef
    139   br label %ret
    140 
    141 bb1:
    142   %val1 = and i16 %shr, 127
    143   store volatile i16 0, i16 addrspace(1)* undef
    144   br label %ret
    145 
    146 ret:
    147   %phi = phi i16 [ %val0, %bb0 ], [ %val1, %bb1 ]
    148   store i16 %phi, i16 addrspace(1)* %out
    149   ret void
    150 }
    151 
    152 ; We don't really want to sink this one since it isn't reducible to a
    153 ; 32-bit BFE on one half of the integer.
    154 
    155 ; OPT-LABEL: @sink_ubfe_i64_span_midpoint(
    156 ; OPT: entry:
    157 ; OPT-NOT: lshr
    158 ; OPT: br i1
    159 
    160 ; OPT: bb0:
    161 ; OPT: %0 = lshr i64 %arg1, 30
    162 ; OPT-NEXT: %val0 = and i64 %0, 255
    163 
    164 ; OPT: bb1:
    165 ; OPT: %1 = lshr i64 %arg1, 30
    166 ; OPT-NEXT: %val1 = and i64 %1, 127
    167 
    168 ; OPT: ret:
    169 ; OPT: store
    170 ; OPT: ret
    171 
    172 ; GCN-LABEL: {{^}}sink_ubfe_i64_span_midpoint:
    173 ; GCN: s_cbranch_vccnz BB3_2
    174 
    175 ; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 30
    176 ; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0xff
    177 
    178 ; GCN: BB3_2:
    179 ; GCN: s_lshr_b64 s{{\[}}[[LO:[0-9]+]]:{{[0-9]+}}], s{{\[[0-9]+:[0-9]+\]}}, 30
    180 ; GCN: s_and_b32 s{{[0-9]+}}, s[[LO]], 0x7f
    181 
    182 ; GCN: BB3_3:
    183 ; GCN: buffer_store_dwordx2
    184 define void @sink_ubfe_i64_span_midpoint(i64 addrspace(1)* %out, i64 %arg1) #0 {
    185 entry:
    186   %shr = lshr i64 %arg1, 30
    187   br i1 undef, label %bb0, label %bb1
    188 
    189 bb0:
    190   %val0 = and i64 %shr, 255
    191   store volatile i32 0, i32 addrspace(1)* undef
    192   br label %ret
    193 
    194 bb1:
    195   %val1 = and i64 %shr, 127
    196   store volatile i32 0, i32 addrspace(1)* undef
    197   br label %ret
    198 
    199 ret:
    200   %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
    201   store i64 %phi, i64 addrspace(1)* %out
    202   ret void
    203 }
    204 
    205 ; OPT-LABEL: @sink_ubfe_i64_low32(
    206 ; OPT: entry:
    207 ; OPT-NOT: lshr
    208 ; OPT: br i1
    209 
    210 ; OPT: bb0:
    211 ; OPT: %0 = lshr i64 %arg1, 15
    212 ; OPT-NEXT: %val0 = and i64 %0, 255
    213 
    214 ; OPT: bb1:
    215 ; OPT: %1 = lshr i64 %arg1, 15
    216 ; OPT-NEXT: %val1 = and i64 %1, 127
    217 
    218 ; OPT: ret:
    219 ; OPT: store
    220 ; OPT: ret
    221 
    222 ; GCN-LABEL: {{^}}sink_ubfe_i64_low32:
    223 
    224 ; GCN: s_cbranch_vccnz BB4_2
    225 
    226 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x8000f
    227 
    228 ; GCN: BB4_2:
    229 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x7000f
    230 
    231 ; GCN: BB4_3:
    232 ; GCN: buffer_store_dwordx2
    233 define void @sink_ubfe_i64_low32(i64 addrspace(1)* %out, i64 %arg1) #0 {
    234 entry:
    235   %shr = lshr i64 %arg1, 15
    236   br i1 undef, label %bb0, label %bb1
    237 
    238 bb0:
    239   %val0 = and i64 %shr, 255
    240   store volatile i32 0, i32 addrspace(1)* undef
    241   br label %ret
    242 
    243 bb1:
    244   %val1 = and i64 %shr, 127
    245   store volatile i32 0, i32 addrspace(1)* undef
    246   br label %ret
    247 
    248 ret:
    249   %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
    250   store i64 %phi, i64 addrspace(1)* %out
    251   ret void
    252 }
    253 
    254 ; OPT-LABEL: @sink_ubfe_i64_high32(
    255 ; OPT: entry:
    256 ; OPT-NOT: lshr
    257 ; OPT: br i1
    258 
    259 ; OPT: bb0:
    260 ; OPT: %0 = lshr i64 %arg1, 35
    261 ; OPT-NEXT: %val0 = and i64 %0, 255
    262 
    263 ; OPT: bb1:
    264 ; OPT: %1 = lshr i64 %arg1, 35
    265 ; OPT-NEXT: %val1 = and i64 %1, 127
    266 
    267 ; OPT: ret:
    268 ; OPT: store
    269 ; OPT: ret
    270 
    271 ; GCN-LABEL: {{^}}sink_ubfe_i64_high32:
    272 ; GCN: s_cbranch_vccnz BB5_2
    273 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80003
    274 
    275 ; GCN: BB5_2:
    276 ; GCN: s_bfe_u32 s{{[0-9]+}}, s{{[0-9]+}}, 0x70003
    277 
    278 ; GCN: BB5_3:
    279 ; GCN: buffer_store_dwordx2
    280 define void @sink_ubfe_i64_high32(i64 addrspace(1)* %out, i64 %arg1) #0 {
    281 entry:
    282   %shr = lshr i64 %arg1, 35
    283   br i1 undef, label %bb0, label %bb1
    284 
    285 bb0:
    286   %val0 = and i64 %shr, 255
    287   store volatile i32 0, i32 addrspace(1)* undef
    288   br label %ret
    289 
    290 bb1:
    291   %val1 = and i64 %shr, 127
    292   store volatile i32 0, i32 addrspace(1)* undef
    293   br label %ret
    294 
    295 ret:
    296   %phi = phi i64 [ %val0, %bb0 ], [ %val1, %bb1 ]
    297   store i64 %phi, i64 addrspace(1)* %out
    298   ret void
    299 }
    300 
    301 attributes #0 = { nounwind }
    302