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 6define <4 x i8> @Zero_i8(<4 x i8> %InVec) { 7entry: 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 15define <4 x i8> @Identity_i8(<4 x i8> %InVec) { 16entry: 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 24define <4 x i8> @AddToSelf_i8(<4 x i8> %InVec) { 25entry: 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 34define <4 x i8> @SplatPow2Test1_i8(<4 x i8> %InVec) { 35entry: 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 44define <4 x i8> @SplatPow2Test2_i8(<4 x i8> %InVec) { 45entry: 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 54define <4 x i8> @MulTest1_i8(<4 x i8> %InVec) { 55entry: 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 64define <4 x i8> @MulTest2_i8(<4 x i8> %InVec) { 65entry: 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 74define <4 x i8> @MulTest3_i8(<4 x i8> %InVec) { 75entry: 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 85define <4 x i8> @MulTest4_i8(<4 x i8> %InVec) { 86entry: 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 95define <4 x i16> @Zero_i16(<4 x i16> %InVec) { 96entry: 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 104define <4 x i16> @Identity_i16(<4 x i16> %InVec) { 105entry: 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 113define <4 x i16> @AddToSelf_i16(<4 x i16> %InVec) { 114entry: 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 123define <4 x i16> @SplatPow2Test1_i16(<4 x i16> %InVec) { 124entry: 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 133define <4 x i16> @SplatPow2Test2_i16(<4 x i16> %InVec) { 134entry: 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 143define <4 x i16> @MulTest1_i16(<4 x i16> %InVec) { 144entry: 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 153define <4 x i16> @MulTest2_i16(<4 x i16> %InVec) { 154entry: 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 163define <4 x i16> @MulTest3_i16(<4 x i16> %InVec) { 164entry: 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 173define <4 x i16> @MulTest4_i16(<4 x i16> %InVec) { 174entry: 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 183define <4 x i32> @Zero_i32(<4 x i32> %InVec) { 184entry: 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 192define <4 x i32> @Identity_i32(<4 x i32> %InVec) { 193entry: 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 201define <4 x i32> @AddToSelf_i32(<4 x i32> %InVec) { 202entry: 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 212define <4 x i32> @SplatPow2Test1_i32(<4 x i32> %InVec) { 213entry: 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 222define <4 x i32> @SplatPow2Test2_i32(<4 x i32> %InVec) { 223entry: 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 232define <4 x i32> @MulTest1_i32(<4 x i32> %InVec) { 233entry: 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 242define <4 x i32> @MulTest2_i32(<4 x i32> %InVec) { 243entry: 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 252define <4 x i32> @MulTest3_i32(<4 x i32> %InVec) { 253entry: 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 263define <4 x i32> @MulTest4_i32(<4 x i32> %InVec) { 264entry: 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 273define <4 x i64> @Zero_i64(<4 x i64> %InVec) { 274entry: 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 282define <4 x i64> @Identity_i64(<4 x i64> %InVec) { 283entry: 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 291define <4 x i64> @AddToSelf_i64(<4 x i64> %InVec) { 292entry: 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 301define <4 x i64> @SplatPow2Test1_i64(<4 x i64> %InVec) { 302entry: 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 311define <4 x i64> @SplatPow2Test2_i64(<4 x i64> %InVec) { 312entry: 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 321define <4 x i64> @MulTest1_i64(<4 x i64> %InVec) { 322entry: 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 331define <4 x i64> @MulTest2_i64(<4 x i64> %InVec) { 332entry: 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 341define <4 x i64> @MulTest3_i64(<4 x i64> %InVec) { 342entry: 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 351define <4 x i64> @MulTest4_i64(<4 x i64> %InVec) { 352entry: 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 365define <4 x i8> @ShiftMulTest1(<4 x i8> %InVec) { 366entry: 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 376define <4 x i16> @ShiftMulTest2(<4 x i16> %InVec) { 377entry: 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 387define <4 x i32> @ShiftMulTest3(<4 x i32> %InVec) { 388entry: 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 398define <4 x i64> @ShiftMulTest4(<4 x i64> %InVec) { 399entry: 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