Home | History | Annotate | Download | only in Hexagon
      1 ; RUN: llc -march=hexagon < %s | FileCheck %s
      2 ; This test checks for the generation of 64b mul instruction
      3 ; (dpmpyss_s0 and dpmpyuu_s0).
      4 
      5 ; Checks for unsigned multiplication.
      6 
      7 ; 16 x 16 = 64
      8 ; CHECK-LABEL: f0:
      9 ; CHECK: r1:0 = mpyu(
     10 define i64 @f0(i16 zeroext %a0, i16 zeroext %a1) local_unnamed_addr #0 {
     11 b0:
     12   %v0 = zext i16 %a0 to i64
     13   %v1 = zext i16 %a1 to i64
     14   %v2 = mul nuw nsw i64 %v1, %v0
     15   ret i64 %v2
     16 }
     17 
     18 ; 32 x 32 = 64
     19 ; CHECK-LABEL: f1:
     20 ; CHECK: r1:0 = mpyu(
     21 define i64 @f1(i32 %a0, i32 %a1) local_unnamed_addr #0 {
     22 b0:
     23   %v0 = zext i32 %a0 to i64
     24   %v1 = zext i32 %a1 to i64
     25   %v2 = mul nuw nsw i64 %v1, %v0
     26   ret i64 %v2
     27 }
     28 
     29 ; Given int w[2], short h[4], signed char c[8], the below tests check for the
     30 ; generation of dpmpyuu_s0.
     31 ; w[0] * h[0]
     32 ; CHECK-LABEL: f2:
     33 ; CHECK: = sxth
     34 ; CHECK: r1:0 = mpyu(
     35 define i64 @f2(i64 %a0, i64 %a1) local_unnamed_addr #0 {
     36 b0:
     37   %v0 = and i64 %a0, 4294967295
     38   %v1 = trunc i64 %a1 to i32
     39   %v2 = shl i32 %v1, 16
     40   %v3 = ashr exact i32 %v2, 16
     41   %v4 = zext i32 %v3 to i64
     42   %v5 = mul nuw i64 %v0, %v4
     43   ret i64 %v5
     44 }
     45 
     46 ; w[0] * h[1]
     47 ; CHECK-LABEL: f3:
     48 ; CHECK: = asrh
     49 ; CHECK: r1:0 = mpyu(
     50 define i64 @f3(i64 %a0, i64 %a1) local_unnamed_addr #0 {
     51 b0:
     52   %v0 = and i64 %a0, 4294967295
     53   %v1 = trunc i64 %a1 to i32
     54   %v2 = ashr i32 %v1, 16
     55   %v3 = zext i32 %v2 to i64
     56   %v4 = mul nuw i64 %v0, %v3
     57   ret i64 %v4
     58 }
     59 
     60 ; w[0] * h[2]
     61 ; CHECK-LABEL: f4:
     62 ; CHECK: = extract(
     63 ; CHECK: r1:0 = mpyu(
     64 define i64 @f4(i64 %a0, i64 %a1) local_unnamed_addr #0 {
     65 b0:
     66   %v0 = and i64 %a0, 4294967295
     67   %v1 = lshr i64 %a1, 32
     68   %v2 = shl nuw nsw i64 %v1, 16
     69   %v3 = trunc i64 %v2 to i32
     70   %v4 = ashr exact i32 %v3, 16
     71   %v5 = zext i32 %v4 to i64
     72   %v6 = mul nuw i64 %v0, %v5
     73   ret i64 %v6
     74 }
     75 
     76 ; w[0] * h[3]
     77 ; CHECK-LABEL: f5:
     78 ; CHECK: = extractu(
     79 ; CHECK: r1:0 = mpyu(
     80 define i64 @f5(i64 %a0, i64 %a1) local_unnamed_addr #0 {
     81 b0:
     82   %v0 = and i64 %a0, 4294967295
     83   %v1 = lshr i64 %a1, 48
     84   %v2 = shl nuw nsw i64 %v1, 16
     85   %v3 = trunc i64 %v2 to i32
     86   %v4 = ashr exact i32 %v3, 16
     87   %v5 = zext i32 %v4 to i64
     88   %v6 = mul nuw i64 %v0, %v5
     89   ret i64 %v6
     90 }
     91 
     92 ; w[1] * h[0]
     93 ; CHECK-LABEL: f6:
     94 ; CHECK: = sxth(
     95 ; CHECK: r1:0 = mpyu(
     96 define i64 @f6(i64 %a0, i64 %a1) local_unnamed_addr #0 {
     97 b0:
     98   %v0 = lshr i64 %a0, 32
     99   %v1 = trunc i64 %a1 to i32
    100   %v2 = shl i32 %v1, 16
    101   %v3 = ashr exact i32 %v2, 16
    102   %v4 = zext i32 %v3 to i64
    103   %v5 = mul nuw i64 %v0, %v4
    104   ret i64 %v5
    105 }
    106 
    107 ; w[0] * c[0]
    108 ; CHECK-LABEL: f7:
    109 ; CHECK: = and({{.*}}#255)
    110 ; CHECK: r1:0 = mpyu(
    111 define i64 @f7(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    112 b0:
    113   %v0 = and i64 %a0, 4294967295
    114   %v1 = and i64 %a1, 255
    115   %v2 = mul nuw nsw i64 %v1, %v0
    116   ret i64 %v2
    117 }
    118 
    119 ; w[0] * c[2]
    120 ; CHECK-LABEL: f8:
    121 ; CHECK: = extractu(
    122 ; CHECK: r1:0 = mpyu(
    123 define i64 @f8(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    124 b0:
    125   %v0 = and i64 %a0, 4294967295
    126   %v1 = lshr i64 %a1, 16
    127   %v2 = and i64 %v1, 255
    128   %v3 = mul nuw nsw i64 %v2, %v0
    129   ret i64 %v3
    130 }
    131 
    132 ; w[0] * c[7]
    133 ; CHECK-LABEL: f9:
    134 ; CHECK: = lsr(
    135 ; CHECK: r1:0 = mpyu(
    136 define i64 @f9(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    137 b0:
    138   %v0 = and i64 %a0, 4294967295
    139   %v1 = lshr i64 %a1, 56
    140   %v2 = mul nuw nsw i64 %v1, %v0
    141   ret i64 %v2
    142 }
    143 
    144 
    145 ; Checks for signed multiplication.
    146 
    147 ; 16 x 16 = 64
    148 ; CHECK-LABEL: f10:
    149 ; CHECK: r1:0 = mpy(
    150 define i64 @f10(i16 signext %a0, i16 signext %a1) local_unnamed_addr #0 {
    151 b0:
    152   %v0 = sext i16 %a0 to i64
    153   %v1 = sext i16 %a1 to i64
    154   %v2 = mul nsw i64 %v1, %v0
    155   ret i64 %v2
    156 }
    157 
    158 ; 32 x 32 = 64
    159 ; CHECK-LABEL: f11:
    160 ; CHECK: r1:0 = mpy(
    161 define i64 @f11(i32 %a0, i32 %a1) local_unnamed_addr #0 {
    162 b0:
    163   %v0 = sext i32 %a0 to i64
    164   %v1 = sext i32 %a1 to i64
    165   %v2 = mul nsw i64 %v1, %v0
    166   ret i64 %v2
    167 }
    168 
    169 ; Given unsigned int w[2], unsigned short h[4], unsigned char c[8], the below
    170 ; tests check for the generation of dpmpyss_s0.
    171 ; w[0] * h[0]
    172 ; CHECK-LABEL: f12:
    173 ; CHECK: = sxth
    174 ; CHECK: r1:0 = mpy(
    175 define i64 @f12(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    176 b0:
    177   %v0 = shl i64 %a0, 32
    178   %v1 = ashr exact i64 %v0, 32
    179   %v2 = shl i64 %a1, 48
    180   %v3 = ashr exact i64 %v2, 48
    181   %v4 = mul nsw i64 %v3, %v1
    182   ret i64 %v4
    183 }
    184 
    185 ; w[0] * h[1]
    186 ; CHECK-LABEL: f13:
    187 ; CHECK: = asrh
    188 ; CHECK: r1:0 = mpy(
    189 define i64 @f13(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    190 b0:
    191   %v0 = shl i64 %a0, 32
    192   %v1 = ashr exact i64 %v0, 32
    193   %v2 = trunc i64 %a1 to i32
    194   %v3 = ashr i32 %v2, 16
    195   %v4 = sext i32 %v3 to i64
    196   %v5 = mul nsw i64 %v1, %v4
    197   ret i64 %v5
    198 }
    199 
    200 ; w[0] * h[2]
    201 ; CHECK-LABEL: f14:
    202 ; CHECK: = extract(
    203 ; CHECK: r1:0 = mpy(
    204 define i64 @f14(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    205 b0:
    206   %v0 = shl i64 %a0, 32
    207   %v1 = ashr exact i64 %v0, 32
    208   %v2 = lshr i64 %a1, 32
    209   %v3 = shl nuw nsw i64 %v2, 16
    210   %v4 = trunc i64 %v3 to i32
    211   %v5 = ashr exact i32 %v4, 16
    212   %v6 = sext i32 %v5 to i64
    213   %v7 = mul nsw i64 %v1, %v6
    214   ret i64 %v7
    215 }
    216 
    217 ; w[0] * h[3]
    218 ; CHECK-LABEL: f15:
    219 ; CHECK: = sxth(
    220 ; CHECK: r1:0 = mpy(
    221 define i64 @f15(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    222 b0:
    223   %v0 = ashr i64 %a0, 32
    224   %v1 = shl i64 %a1, 48
    225   %v2 = ashr exact i64 %v1, 48
    226   %v3 = mul nsw i64 %v2, %v0
    227   ret i64 %v3
    228 }
    229 
    230 ; w[1] * h[0]
    231 ; CHECK-LABEL: f16:
    232 ; CHECK: = asrh(
    233 ; CHECK: r1:0 = mpy(
    234 define i64 @f16(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    235 b0:
    236   %v0 = ashr i64 %a0, 32
    237   %v1 = trunc i64 %a1 to i32
    238   %v2 = ashr i32 %v1, 16
    239   %v3 = sext i32 %v2 to i64
    240   %v4 = mul nsw i64 %v0, %v3
    241   ret i64 %v4
    242 }
    243 
    244 ; w[0] * c[0]
    245 ; CHECK-LABEL: f17:
    246 ; CHECK: = sxtb(
    247 ; CHECK: r1:0 = mpy(
    248 define i64 @f17(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    249 b0:
    250   %v0 = shl i64 %a0, 32
    251   %v1 = ashr exact i64 %v0, 32
    252   %v2 = shl i64 %a1, 56
    253   %v3 = ashr exact i64 %v2, 56
    254   %v4 = mul nsw i64 %v3, %v1
    255   ret i64 %v4
    256 }
    257 
    258 ; w[0] * c[2]
    259 ; CHECK-LABEL: f18:
    260 ; CHECK: = extract(
    261 ; CHECK: r1:0 = mpy(
    262 define i64 @f18(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    263 b0:
    264   %v0 = shl i64 %a0, 32
    265   %v1 = ashr exact i64 %v0, 32
    266   %v2 = lshr i64 %a1, 16
    267   %v3 = shl i64 %v2, 24
    268   %v4 = trunc i64 %v3 to i32
    269   %v5 = ashr exact i32 %v4, 24
    270   %v6 = sext i32 %v5 to i64
    271   %v7 = mul nsw i64 %v1, %v6
    272   ret i64 %v7
    273 }
    274 
    275 ; w[0] * c[7]
    276 ; CHECK-LABEL: f19:
    277 ; CHECK: = sxtb(
    278 ; CHECK: r1:0 = mpy(
    279 define i64 @f19(i64 %a0, i64 %a1) local_unnamed_addr #0 {
    280 b0:
    281   %v0 = shl i64 %a0, 32
    282   %v1 = ashr exact i64 %v0, 32
    283   %v2 = lshr i64 %a1, 56
    284   %v3 = shl nuw nsw i64 %v2, 24
    285   %v4 = trunc i64 %v3 to i32
    286   %v5 = ashr exact i32 %v4, 24
    287   %v6 = sext i32 %v5 to i64
    288   %v7 = mul nsw i64 %v1, %v6
    289   ret i64 %v7
    290 }
    291 
    292 attributes #0 = { norecurse nounwind readnone "target-cpu"="hexagonv60" "target-features"="-hvx" }
    293