Home | History | Annotate | Download | only in PowerPC
      1 ; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs | FileCheck %s
      2 ; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs | FileCheck %s
      3 ; RUN: llc < %s -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-PWR8 -implicit-check-not mod[us][wd]
      4 
      5 @mod_resultsw = common local_unnamed_addr global i32 0, align 4
      6 @mod_resultud = common local_unnamed_addr global i64 0, align 8
      7 @div_resultsw = common local_unnamed_addr global i32 0, align 4
      8 @mod_resultuw = common local_unnamed_addr global i32 0, align 4
      9 @div_resultuw = common local_unnamed_addr global i32 0, align 4
     10 @div_resultsd = common local_unnamed_addr global i64 0, align 8
     11 @mod_resultsd = common local_unnamed_addr global i64 0, align 8
     12 @div_resultud = common local_unnamed_addr global i64 0, align 8
     13 
     14 ; Function Attrs: norecurse nounwind
     15 define void @modulo_sw(i32 signext %a, i32 signext %b) local_unnamed_addr {
     16 entry:
     17   %rem = srem i32 %a, %b
     18   store i32 %rem, i32* @mod_resultsw, align 4
     19   ret void
     20 ; CHECK-LABEL: modulo_sw
     21 ; CHECK: modsw {{[0-9]+}}, 3, 4
     22 ; CHECK: blr
     23 ; CHECK-PWR8-LABEL: modulo_sw
     24 ; CHECK-PWR8: div
     25 ; CHECK-PWR8: mull
     26 ; CHECK-PWR8: sub
     27 ; CHECK-PWR8: blr
     28 }
     29 
     30 ; Function Attrs: norecurse nounwind readnone
     31 define zeroext i32 @modulo_uw(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr {
     32 entry:
     33   %rem = urem i32 %a, %b
     34   ret i32 %rem
     35 ; CHECK-LABEL: modulo_uw
     36 ; CHECK: moduw {{[0-9]+}}, 3, 4
     37 ; CHECK: blr
     38 ; CHECK-PWR8-LABEL: modulo_uw
     39 ; CHECK-PWR8: div
     40 ; CHECK-PWR8: mull
     41 ; CHECK-PWR8: sub
     42 ; CHECK-PWR8: blr
     43 }
     44 
     45 ; Function Attrs: norecurse nounwind readnone
     46 define i64 @modulo_sd(i64 %a, i64 %b) local_unnamed_addr {
     47 entry:
     48   %rem = srem i64 %a, %b
     49   ret i64 %rem
     50 ; CHECK-LABEL: modulo_sd
     51 ; CHECK: modsd {{[0-9]+}}, 3, 4
     52 ; CHECK: blr
     53 ; CHECK-PWR8-LABEL: modulo_sd
     54 ; CHECK-PWR8: div
     55 ; CHECK-PWR8: mull
     56 ; CHECK-PWR8: sub
     57 ; CHECK-PWR8: blr
     58 }
     59 
     60 ; Function Attrs: norecurse nounwind
     61 define void @modulo_ud(i64 %a, i64 %b) local_unnamed_addr {
     62 entry:
     63   %rem = urem i64 %a, %b
     64   store i64 %rem, i64* @mod_resultud, align 8
     65   ret void
     66 ; CHECK-LABEL: modulo_ud
     67 ; CHECK: modud {{[0-9]+}}, 3, 4
     68 ; CHECK: blr
     69 ; CHECK-PWR8-LABEL: modulo_ud
     70 ; CHECK-PWR8: div
     71 ; CHECK-PWR8: mull
     72 ; CHECK-PWR8: sub
     73 ; CHECK-PWR8: blr
     74 }
     75 
     76 ; Function Attrs: norecurse nounwind
     77 define void @modulo_div_sw(i32 signext %a, i32 signext %b) local_unnamed_addr {
     78 entry:
     79   %rem = srem i32 %a, %b
     80   store i32 %rem, i32* @mod_resultsw, align 4
     81   %div = sdiv i32 %a, %b
     82   store i32 %div, i32* @div_resultsw, align 4
     83   ret void
     84 ; CHECK-LABEL: modulo_div_sw
     85 ; CHECK-NOT: modsw
     86 ; CHECK: div
     87 ; CHECK-NOT: modsw
     88 ; CHECK: mull
     89 ; CHECK-NOT: modsw
     90 ; CHECK: sub
     91 ; CHECK: blr
     92 ; CHECK-PWR8-LABEL: modulo_div_sw
     93 ; CHECK-PWR8: div
     94 ; CHECK-PWR8: mull
     95 ; CHECK-PWR8: sub
     96 ; CHECK-PWR8: blr
     97 }
     98 
     99 ; Function Attrs: norecurse nounwind
    100 define void @modulo_div_abc_sw(i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr {
    101 entry:
    102   %rem = srem i32 %a, %c
    103   store i32 %rem, i32* @mod_resultsw, align 4
    104   %div = sdiv i32 %b, %c
    105   store i32 %div, i32* @div_resultsw, align 4
    106   ret void
    107 ; CHECK-LABEL: modulo_div_abc_sw
    108 ; CHECK: modsw {{[0-9]+}}, 3, 5
    109 ; CHECK: blr
    110 ; CHECK-PWR8-LABEL: modulo_div_abc_sw
    111 ; CHECK-PWR8: div
    112 ; CHECK-PWR8: mull
    113 ; CHECK-PWR8: sub
    114 ; CHECK-PWR8: blr
    115 }
    116 
    117 ; Function Attrs: norecurse nounwind
    118 define void @modulo_div_uw(i32 zeroext %a, i32 zeroext %b) local_unnamed_addr {
    119 entry:
    120   %rem = urem i32 %a, %b
    121   store i32 %rem, i32* @mod_resultuw, align 4
    122   %div = udiv i32 %a, %b
    123   store i32 %div, i32* @div_resultuw, align 4
    124   ret void
    125 ; CHECK-LABEL: modulo_div_uw
    126 ; CHECK-NOT: modsw
    127 ; CHECK: div
    128 ; CHECK-NOT: modsw
    129 ; CHECK: mull
    130 ; CHECK-NOT: modsw
    131 ; CHECK: sub
    132 ; CHECK: blr
    133 ; CHECK-PWR8-LABEL: modulo_div_uw
    134 ; CHECK-PWR8: div
    135 ; CHECK-PWR8: mull
    136 ; CHECK-PWR8: sub
    137 ; CHECK-PWR8: blr
    138 }
    139 
    140 ; Function Attrs: norecurse nounwind
    141 define void @modulo_div_swuw(i32 signext %a, i32 signext %b) local_unnamed_addr {
    142 entry:
    143   %rem = srem i32 %a, %b
    144   store i32 %rem, i32* @mod_resultsw, align 4
    145   %div = udiv i32 %a, %b
    146   store i32 %div, i32* @div_resultsw, align 4
    147   ret void
    148 ; CHECK-LABEL: modulo_div_swuw
    149 ; CHECK: modsw {{[0-9]+}}, 3, 4
    150 ; CHECK: blr
    151 ; CHECK-PWR8-LABEL: modulo_div_swuw
    152 ; CHECK-PWR8: div
    153 ; CHECK-PWR8: mull
    154 ; CHECK-PWR8: sub
    155 ; CHECK-PWR8: blr
    156 }
    157 
    158 ; Function Attrs: norecurse nounwind
    159 define void @modulo_div_udsd(i64 %a, i64 %b) local_unnamed_addr {
    160 entry:
    161   %rem = urem i64 %a, %b
    162   store i64 %rem, i64* @mod_resultud, align 8
    163   %div = sdiv i64 %a, %b
    164   store i64 %div, i64* @div_resultsd, align 8
    165   ret void
    166 ; CHECK-LABEL: modulo_div_udsd
    167 ; CHECK: modud {{[0-9]+}}, 3, 4
    168 ; CHECK: blr
    169 ; CHECK-PWR8-LABEL: modulo_div_udsd
    170 ; CHECK-PWR8: div
    171 ; CHECK-PWR8: mull
    172 ; CHECK-PWR8: sub
    173 ; CHECK-PWR8: blr
    174 }
    175 
    176 ; Function Attrs: norecurse nounwind
    177 define void @modulo_const32_sw(i32 signext %a) local_unnamed_addr {
    178 entry:
    179   %rem = srem i32 %a, 32
    180   store i32 %rem, i32* @mod_resultsw, align 4
    181   ret void
    182 ; CHECK-LABEL: modulo_const32_sw
    183 ; CHECK-NOT: modsw
    184 ; CHECK: srawi
    185 ; CHECK-NOT: modsw
    186 ; CHECK: addze
    187 ; CHECK-NOT: modsw
    188 ; CHECK: slwi
    189 ; CHECK-NOT: modsw
    190 ; CHECK: subf
    191 ; CHECK-NOT: modsw
    192 ; CHECK: blr
    193 ; CHECK-PWR8-LABEL: modulo_const32_sw
    194 ; CHECK-PWR8: srawi
    195 ; CHECK-PWR8: addze
    196 ; CHECK-PWR8: slwi
    197 ; CHECK-PWR8: subf
    198 ; CHECK-PWR8: blr
    199 }
    200 
    201 ; Function Attrs: norecurse nounwind readnone
    202 define signext i32 @modulo_const3_sw(i32 signext %a) local_unnamed_addr {
    203 entry:
    204   %rem = srem i32 %a, 3
    205   ret i32 %rem
    206 ; CHECK-LABEL: modulo_const3_sw
    207 ; CHECK-NOT: modsw
    208 ; CHECK: mull
    209 ; CHECK-NOT: modsw
    210 ; CHECK: sub
    211 ; CHECK-NOT: modsw
    212 ; CHECK: blr
    213 ; CHECK-PWR8-LABEL: modulo_const3_sw
    214 ; CHECK-PWR8: mull
    215 ; CHECK-PWR8: sub
    216 ; CHECK-PWR8: blr
    217 }
    218 
    219 ; Function Attrs: norecurse nounwind readnone
    220 define signext i32 @const2_modulo_sw(i32 signext %a) local_unnamed_addr {
    221 entry:
    222   %rem = srem i32 2, %a
    223   ret i32 %rem
    224 ; CHECK-LABEL: const2_modulo_sw
    225 ; CHECK: modsw {{[0-9]+}}, {{[0-9]+}}, 3
    226 ; CHECK: blr
    227 ; CHECK-PWR8-LABEL: const2_modulo_sw
    228 ; CHECK-PWR8: div
    229 ; CHECK-PWR8: mull
    230 ; CHECK-PWR8: sub
    231 ; CHECK-PWR8: blr
    232 }
    233 
    234 ; Function Attrs: norecurse nounwind
    235 ; FIXME On power 9 this test will still produce modsw because the divide is in
    236 ; a different block than the remainder. Due to the nature of the SDAG we cannot
    237 ; see the div in the other block.
    238 define void @blocks_modulo_div_sw(i32 signext %a, i32 signext %b, i32 signext %c) local_unnamed_addr {
    239 entry:
    240   %div = sdiv i32 %a, %b
    241   store i32 %div, i32* @div_resultsw, align 4
    242   %cmp = icmp sgt i32 %c, 0
    243   br i1 %cmp, label %if.then, label %if.end
    244 
    245 if.then:                                          ; preds = %entry
    246   %rem = srem i32 %a, %b
    247   store i32 %rem, i32* @mod_resultsw, align 4
    248   br label %if.end
    249 
    250 if.end:                                           ; preds = %if.then, %entry
    251   ret void
    252 ; CHECK-LABEL: blocks_modulo_div_sw
    253 ; CHECK: div
    254 ; CHECK: modsw {{[0-9]+}}, 3, 4
    255 ; CHECK: blr
    256 ; CHECK-PWR8-LABEL: blocks_modulo_div_sw
    257 ; CHECK-PWR8: div
    258 ; CHECK-PWR8: mull
    259 ; CHECK-PWR8: sub
    260 ; CHECK-PWR8: blr
    261 }
    262 
    263 
    264