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