1 ; RUN: opt < %s -instcombine -S | FileCheck %s 2 3 ; Check that instcombine rewrites multiply by a vector 4 ; of known constant power-of-2 elements with vector shift. 5 6 define <4 x i8> @Zero_i8(<4 x i8> %InVec) { 7 entry: 8 %mul = mul <4 x i8> %InVec, <i8 0, i8 0, i8 0, i8 0> 9 ret <4 x i8> %mul 10 } 11 12 ; CHECK-LABEL: @Zero_i8( 13 ; CHECK: ret <4 x i8> zeroinitializer 14 15 define <4 x i8> @Identity_i8(<4 x i8> %InVec) { 16 entry: 17 %mul = mul <4 x i8> %InVec, <i8 1, i8 1, i8 1, i8 1> 18 ret <4 x i8> %mul 19 } 20 21 ; CHECK-LABEL: @Identity_i8( 22 ; CHECK: ret <4 x i8> %InVec 23 24 define <4 x i8> @AddToSelf_i8(<4 x i8> %InVec) { 25 entry: 26 %mul = mul <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2> 27 ret <4 x i8> %mul 28 } 29 30 ; CHECK-LABEL: @AddToSelf_i8( 31 ; CHECK: shl <4 x i8> %InVec, <i8 1, i8 1, i8 1, i8 1> 32 ; CHECK: ret 33 34 define <4 x i8> @SplatPow2Test1_i8(<4 x i8> %InVec) { 35 entry: 36 %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 4, i8 4> 37 ret <4 x i8> %mul 38 } 39 40 ; CHECK-LABEL: @SplatPow2Test1_i8( 41 ; CHECK: shl <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2> 42 ; CHECK: ret 43 44 define <4 x i8> @SplatPow2Test2_i8(<4 x i8> %InVec) { 45 entry: 46 %mul = mul <4 x i8> %InVec, <i8 8, i8 8, i8 8, i8 8> 47 ret <4 x i8> %mul 48 } 49 50 ; CHECK-LABEL: @SplatPow2Test2_i8( 51 ; CHECK: shl <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3> 52 ; CHECK: ret 53 54 define <4 x i8> @MulTest1_i8(<4 x i8> %InVec) { 55 entry: 56 %mul = mul <4 x i8> %InVec, <i8 1, i8 2, i8 4, i8 8> 57 ret <4 x i8> %mul 58 } 59 60 ; CHECK-LABEL: @MulTest1_i8( 61 ; CHECK: shl <4 x i8> %InVec, <i8 0, i8 1, i8 2, i8 3> 62 ; CHECK: ret 63 64 define <4 x i8> @MulTest2_i8(<4 x i8> %InVec) { 65 entry: 66 %mul = mul <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3> 67 ret <4 x i8> %mul 68 } 69 70 ; CHECK-LABEL: @MulTest2_i8( 71 ; CHECK: mul <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3> 72 ; CHECK: ret 73 74 define <4 x i8> @MulTest3_i8(<4 x i8> %InVec) { 75 entry: 76 %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 2, i8 2> 77 ret <4 x i8> %mul 78 } 79 80 ; CHECK-LABEL: @MulTest3_i8( 81 ; CHECK: shl <4 x i8> %InVec, <i8 2, i8 2, i8 1, i8 1> 82 ; CHECK: ret 83 84 85 define <4 x i8> @MulTest4_i8(<4 x i8> %InVec) { 86 entry: 87 %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 0, i8 1> 88 ret <4 x i8> %mul 89 } 90 91 ; CHECK-LABEL: @MulTest4_i8( 92 ; CHECK: mul <4 x i8> %InVec, <i8 4, i8 4, i8 0, i8 1> 93 ; CHECK: ret 94 95 define <4 x i16> @Zero_i16(<4 x i16> %InVec) { 96 entry: 97 %mul = mul <4 x i16> %InVec, <i16 0, i16 0, i16 0, i16 0> 98 ret <4 x i16> %mul 99 } 100 101 ; CHECK-LABEL: @Zero_i16( 102 ; CHECK: ret <4 x i16> zeroinitializer 103 104 define <4 x i16> @Identity_i16(<4 x i16> %InVec) { 105 entry: 106 %mul = mul <4 x i16> %InVec, <i16 1, i16 1, i16 1, i16 1> 107 ret <4 x i16> %mul 108 } 109 110 ; CHECK-LABEL: @Identity_i16( 111 ; CHECK: ret <4 x i16> %InVec 112 113 define <4 x i16> @AddToSelf_i16(<4 x i16> %InVec) { 114 entry: 115 %mul = mul <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2> 116 ret <4 x i16> %mul 117 } 118 119 ; CHECK-LABEL: @AddToSelf_i16( 120 ; CHECK: shl <4 x i16> %InVec, <i16 1, i16 1, i16 1, i16 1> 121 ; CHECK: ret 122 123 define <4 x i16> @SplatPow2Test1_i16(<4 x i16> %InVec) { 124 entry: 125 %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 4, i16 4> 126 ret <4 x i16> %mul 127 } 128 129 ; CHECK-LABEL: @SplatPow2Test1_i16( 130 ; CHECK: shl <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2> 131 ; CHECK: ret 132 133 define <4 x i16> @SplatPow2Test2_i16(<4 x i16> %InVec) { 134 entry: 135 %mul = mul <4 x i16> %InVec, <i16 8, i16 8, i16 8, i16 8> 136 ret <4 x i16> %mul 137 } 138 139 ; CHECK-LABEL: @SplatPow2Test2_i16( 140 ; CHECK: shl <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3> 141 ; CHECK: ret 142 143 define <4 x i16> @MulTest1_i16(<4 x i16> %InVec) { 144 entry: 145 %mul = mul <4 x i16> %InVec, <i16 1, i16 2, i16 4, i16 8> 146 ret <4 x i16> %mul 147 } 148 149 ; CHECK-LABEL: @MulTest1_i16( 150 ; CHECK: shl <4 x i16> %InVec, <i16 0, i16 1, i16 2, i16 3> 151 ; CHECK: ret 152 153 define <4 x i16> @MulTest2_i16(<4 x i16> %InVec) { 154 entry: 155 %mul = mul <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3> 156 ret <4 x i16> %mul 157 } 158 159 ; CHECK-LABEL: @MulTest2_i16( 160 ; CHECK: mul <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3> 161 ; CHECK: ret 162 163 define <4 x i16> @MulTest3_i16(<4 x i16> %InVec) { 164 entry: 165 %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 2, i16 2> 166 ret <4 x i16> %mul 167 } 168 169 ; CHECK-LABEL: @MulTest3_i16( 170 ; CHECK: shl <4 x i16> %InVec, <i16 2, i16 2, i16 1, i16 1> 171 ; CHECK: ret 172 173 define <4 x i16> @MulTest4_i16(<4 x i16> %InVec) { 174 entry: 175 %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 0, i16 2> 176 ret <4 x i16> %mul 177 } 178 179 ; CHECK-LABEL: @MulTest4_i16( 180 ; CHECK: mul <4 x i16> %InVec, <i16 4, i16 4, i16 0, i16 2> 181 ; CHECK: ret 182 183 define <4 x i32> @Zero_i32(<4 x i32> %InVec) { 184 entry: 185 %mul = mul <4 x i32> %InVec, <i32 0, i32 0, i32 0, i32 0> 186 ret <4 x i32> %mul 187 } 188 189 ; CHECK-LABEL: @Zero_i32( 190 ; CHECK: ret <4 x i32> zeroinitializer 191 192 define <4 x i32> @Identity_i32(<4 x i32> %InVec) { 193 entry: 194 %mul = mul <4 x i32> %InVec, <i32 1, i32 1, i32 1, i32 1> 195 ret <4 x i32> %mul 196 } 197 198 ; CHECK-LABEL: @Identity_i32( 199 ; CHECK: ret <4 x i32> %InVec 200 201 define <4 x i32> @AddToSelf_i32(<4 x i32> %InVec) { 202 entry: 203 %mul = mul <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2> 204 ret <4 x i32> %mul 205 } 206 207 ; CHECK-LABEL: @AddToSelf_i32( 208 ; CHECK: shl <4 x i32> %InVec, <i32 1, i32 1, i32 1, i32 1> 209 ; CHECK: ret 210 211 212 define <4 x i32> @SplatPow2Test1_i32(<4 x i32> %InVec) { 213 entry: 214 %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 4, i32 4> 215 ret <4 x i32> %mul 216 } 217 218 ; CHECK-LABEL: @SplatPow2Test1_i32( 219 ; CHECK: shl <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2> 220 ; CHECK: ret 221 222 define <4 x i32> @SplatPow2Test2_i32(<4 x i32> %InVec) { 223 entry: 224 %mul = mul <4 x i32> %InVec, <i32 8, i32 8, i32 8, i32 8> 225 ret <4 x i32> %mul 226 } 227 228 ; CHECK-LABEL: @SplatPow2Test2_i32( 229 ; CHECK: shl <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3> 230 ; CHECK: ret 231 232 define <4 x i32> @MulTest1_i32(<4 x i32> %InVec) { 233 entry: 234 %mul = mul <4 x i32> %InVec, <i32 1, i32 2, i32 4, i32 8> 235 ret <4 x i32> %mul 236 } 237 238 ; CHECK-LABEL: @MulTest1_i32( 239 ; CHECK: shl <4 x i32> %InVec, <i32 0, i32 1, i32 2, i32 3> 240 ; CHECK: ret 241 242 define <4 x i32> @MulTest2_i32(<4 x i32> %InVec) { 243 entry: 244 %mul = mul <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3> 245 ret <4 x i32> %mul 246 } 247 248 ; CHECK-LABEL: @MulTest2_i32( 249 ; CHECK: mul <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3> 250 ; CHECK: ret 251 252 define <4 x i32> @MulTest3_i32(<4 x i32> %InVec) { 253 entry: 254 %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 2, i32 2> 255 ret <4 x i32> %mul 256 } 257 258 ; CHECK-LABEL: @MulTest3_i32( 259 ; CHECK: shl <4 x i32> %InVec, <i32 2, i32 2, i32 1, i32 1> 260 ; CHECK: ret 261 262 263 define <4 x i32> @MulTest4_i32(<4 x i32> %InVec) { 264 entry: 265 %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 0, i32 1> 266 ret <4 x i32> %mul 267 } 268 269 ; CHECK-LABEL: @MulTest4_i32( 270 ; CHECK: mul <4 x i32> %InVec, <i32 4, i32 4, i32 0, i32 1> 271 ; CHECK: ret 272 273 define <4 x i64> @Zero_i64(<4 x i64> %InVec) { 274 entry: 275 %mul = mul <4 x i64> %InVec, <i64 0, i64 0, i64 0, i64 0> 276 ret <4 x i64> %mul 277 } 278 279 ; CHECK-LABEL: @Zero_i64( 280 ; CHECK: ret <4 x i64> zeroinitializer 281 282 define <4 x i64> @Identity_i64(<4 x i64> %InVec) { 283 entry: 284 %mul = mul <4 x i64> %InVec, <i64 1, i64 1, i64 1, i64 1> 285 ret <4 x i64> %mul 286 } 287 288 ; CHECK-LABEL: @Identity_i64( 289 ; CHECK: ret <4 x i64> %InVec 290 291 define <4 x i64> @AddToSelf_i64(<4 x i64> %InVec) { 292 entry: 293 %mul = mul <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2> 294 ret <4 x i64> %mul 295 } 296 297 ; CHECK-LABEL: @AddToSelf_i64( 298 ; CHECK: shl <4 x i64> %InVec, <i64 1, i64 1, i64 1, i64 1> 299 ; CHECK: ret 300 301 define <4 x i64> @SplatPow2Test1_i64(<4 x i64> %InVec) { 302 entry: 303 %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 4, i64 4> 304 ret <4 x i64> %mul 305 } 306 307 ; CHECK-LABEL: @SplatPow2Test1_i64( 308 ; CHECK: shl <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2> 309 ; CHECK: ret 310 311 define <4 x i64> @SplatPow2Test2_i64(<4 x i64> %InVec) { 312 entry: 313 %mul = mul <4 x i64> %InVec, <i64 8, i64 8, i64 8, i64 8> 314 ret <4 x i64> %mul 315 } 316 317 ; CHECK-LABEL: @SplatPow2Test2_i64( 318 ; CHECK: shl <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3> 319 ; CHECK: ret 320 321 define <4 x i64> @MulTest1_i64(<4 x i64> %InVec) { 322 entry: 323 %mul = mul <4 x i64> %InVec, <i64 1, i64 2, i64 4, i64 8> 324 ret <4 x i64> %mul 325 } 326 327 ; CHECK-LABEL: @MulTest1_i64( 328 ; CHECK: shl <4 x i64> %InVec, <i64 0, i64 1, i64 2, i64 3> 329 ; CHECK: ret 330 331 define <4 x i64> @MulTest2_i64(<4 x i64> %InVec) { 332 entry: 333 %mul = mul <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3> 334 ret <4 x i64> %mul 335 } 336 337 ; CHECK-LABEL: @MulTest2_i64( 338 ; CHECK: mul <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3> 339 ; CHECK: ret 340 341 define <4 x i64> @MulTest3_i64(<4 x i64> %InVec) { 342 entry: 343 %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 2, i64 2> 344 ret <4 x i64> %mul 345 } 346 347 ; CHECK-LABEL: @MulTest3_i64( 348 ; CHECK: shl <4 x i64> %InVec, <i64 2, i64 2, i64 1, i64 1> 349 ; CHECK: ret 350 351 define <4 x i64> @MulTest4_i64(<4 x i64> %InVec) { 352 entry: 353 %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 0, i64 1> 354 ret <4 x i64> %mul 355 } 356 357 ; CHECK-LABEL: @MulTest4_i64( 358 ; CHECK: mul <4 x i64> %InVec, <i64 4, i64 4, i64 0, i64 1> 359 ; CHECK: ret 360 361 ; Test also that the following rewriting rule works with vectors 362 ; of integers as well: 363 ; ((X << C1)*C2) == (X * (C2 << C1)) 364 365 define <4 x i8> @ShiftMulTest1(<4 x i8> %InVec) { 366 entry: 367 %shl = shl <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2> 368 %mul = mul <4 x i8> %shl, <i8 3, i8 3, i8 3, i8 3> 369 ret <4 x i8> %mul 370 } 371 372 ; CHECK-LABEL: @ShiftMulTest1( 373 ; CHECK: mul <4 x i8> %InVec, <i8 12, i8 12, i8 12, i8 12> 374 ; CHECK: ret 375 376 define <4 x i16> @ShiftMulTest2(<4 x i16> %InVec) { 377 entry: 378 %shl = shl <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2> 379 %mul = mul <4 x i16> %shl, <i16 3, i16 3, i16 3, i16 3> 380 ret <4 x i16> %mul 381 } 382 383 ; CHECK-LABEL: @ShiftMulTest2( 384 ; CHECK: mul <4 x i16> %InVec, <i16 12, i16 12, i16 12, i16 12> 385 ; CHECK: ret 386 387 define <4 x i32> @ShiftMulTest3(<4 x i32> %InVec) { 388 entry: 389 %shl = shl <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2> 390 %mul = mul <4 x i32> %shl, <i32 3, i32 3, i32 3, i32 3> 391 ret <4 x i32> %mul 392 } 393 394 ; CHECK-LABEL: @ShiftMulTest3( 395 ; CHECK: mul <4 x i32> %InVec, <i32 12, i32 12, i32 12, i32 12> 396 ; CHECK: ret 397 398 define <4 x i64> @ShiftMulTest4(<4 x i64> %InVec) { 399 entry: 400 %shl = shl <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2> 401 %mul = mul <4 x i64> %shl, <i64 3, i64 3, i64 3, i64 3> 402 ret <4 x i64> %mul 403 } 404 405 ; CHECK-LABEL: @ShiftMulTest4( 406 ; CHECK: mul <4 x i64> %InVec, <i64 12, i64 12, i64 12, i64 12> 407 ; CHECK: ret 408 409