1; RUN: llc < %s -mtriple=ve | FileCheck %s 2 3;;; Test ‘shl’ instruction 4;;; 5;;; Syntax: 6;;; <result> = shl <ty> <op1>, <op2> ; yields ty:result 7;;; <result> = shl nuw <ty> <op1>, <op2> ; yields ty:result 8;;; <result> = shl nsw <ty> <op1>, <op2> ; yields ty:result 9;;; <result> = shl nuw nsw <ty> <op1>, <op2> ; yields ty:result 10;;; 11;;; Overview: 12;;; The ‘shl’ instruction returns the first operand shifted to the left 13;;; a specified number of bits. 14;;; 15;;; Arguments: 16;;; Both arguments to the ‘shl’ instruction must be the same integer or 17;;; vector of integer type. ‘op2’ is treated as an unsigned value. 18;;; 19;;; Semantics: 20;;; The value produced is op1 * 2op2 mod 2n, where n is the width of the 21;;; result. If op2 is (statically or dynamically) equal to or larger than 22;;; the number of bits in op1, this instruction returns a poison value. 23;;; If the arguments are vectors, each vector element of op1 is shifted by 24;;; the corresponding shift amount in op2. 25;;; 26;;; If the nuw keyword is present, then the shift produces a poison value 27;;; if it shifts out any non-zero bits. If the nsw keyword is present, 28;;; then the shift produces a poison value if it shifts out any bits that 29;;; disagree with the resultant sign bit. 30;;; 31;;; Example: 32;;; <result> = shl i32 4, %var ; yields i32: 4 << %var 33;;; <result> = shl i32 4, 2 ; yields i32: 16 34;;; <result> = shl i32 1, 10 ; yields i32: 1024 35;;; <result> = shl i32 1, 32 ; undefined 36;;; <result> = shl <2 x i32> < i32 1, i32 1>, < i32 1, i32 2> 37;;; ; yields: result=<2 x i32> < i32 2, i32 4> 38;;; 39;;; Note: 40;;; We test only i8/i16/i32/i64/i128 and unsigned of them. 41 42; Function Attrs: norecurse nounwind readnone 43define signext i8 @shl_i8_var(i8 signext %0, i8 signext %1) { 44; CHECK-LABEL: shl_i8_var: 45; CHECK: # %bb.0: 46; CHECK-NEXT: and %s1, %s1, (56)0 47; CHECK-NEXT: sla.w.sx %s0, %s0, %s1 48; CHECK-NEXT: sll %s0, %s0, 56 49; CHECK-NEXT: sra.l %s0, %s0, 56 50; CHECK-NEXT: b.l.t (, %s10) 51 %3 = sext i8 %0 to i32 52 %4 = zext i8 %1 to i32 53 %5 = shl i32 %3, %4 54 %6 = trunc i32 %5 to i8 55 ret i8 %6 56} 57 58; Function Attrs: norecurse nounwind readnone 59define zeroext i8 @shl_u8_var(i8 zeroext %0, i8 zeroext %1) { 60; CHECK-LABEL: shl_u8_var: 61; CHECK: # %bb.0: 62; CHECK-NEXT: sla.w.sx %s0, %s0, %s1 63; CHECK-NEXT: and %s0, %s0, (56)0 64; CHECK-NEXT: b.l.t (, %s10) 65 %3 = zext i8 %0 to i32 66 %4 = zext i8 %1 to i32 67 %5 = shl i32 %3, %4 68 %6 = trunc i32 %5 to i8 69 ret i8 %6 70} 71 72; Function Attrs: norecurse nounwind readnone 73define signext i16 @shl_i16_var(i16 signext %0, i16 signext %1) { 74; CHECK-LABEL: shl_i16_var: 75; CHECK: # %bb.0: 76; CHECK-NEXT: and %s1, %s1, (48)0 77; CHECK-NEXT: sla.w.sx %s0, %s0, %s1 78; CHECK-NEXT: sll %s0, %s0, 48 79; CHECK-NEXT: sra.l %s0, %s0, 48 80; CHECK-NEXT: b.l.t (, %s10) 81 %3 = sext i16 %0 to i32 82 %4 = zext i16 %1 to i32 83 %5 = shl i32 %3, %4 84 %6 = trunc i32 %5 to i16 85 ret i16 %6 86} 87 88; Function Attrs: norecurse nounwind readnone 89define zeroext i16 @shl_u16_var(i16 zeroext %0, i16 zeroext %1) { 90; CHECK-LABEL: shl_u16_var: 91; CHECK: # %bb.0: 92; CHECK-NEXT: sla.w.sx %s0, %s0, %s1 93; CHECK-NEXT: and %s0, %s0, (48)0 94; CHECK-NEXT: b.l.t (, %s10) 95 %3 = zext i16 %0 to i32 96 %4 = zext i16 %1 to i32 97 %5 = shl i32 %3, %4 98 %6 = trunc i32 %5 to i16 99 ret i16 %6 100} 101 102; Function Attrs: norecurse nounwind readnone 103define signext i32 @shl_i32_var(i32 signext %0, i32 signext %1) { 104; CHECK-LABEL: shl_i32_var: 105; CHECK: # %bb.0: 106; CHECK-NEXT: sla.w.sx %s0, %s0, %s1 107; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 108; CHECK-NEXT: b.l.t (, %s10) 109 %3 = shl i32 %0, %1 110 ret i32 %3 111} 112 113; Function Attrs: norecurse nounwind readnone 114define zeroext i32 @shl_u32_var(i32 zeroext %0, i32 zeroext %1) { 115; CHECK-LABEL: shl_u32_var: 116; CHECK: # %bb.0: 117; CHECK-NEXT: sla.w.sx %s0, %s0, %s1 118; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 119; CHECK-NEXT: b.l.t (, %s10) 120 %3 = shl i32 %0, %1 121 ret i32 %3 122} 123 124; Function Attrs: norecurse nounwind readnone 125define i64 @shl_i64_var(i64 %0, i64 %1) { 126; CHECK-LABEL: shl_i64_var: 127; CHECK: # %bb.0: 128; CHECK-NEXT: sll %s0, %s0, %s1 129; CHECK-NEXT: b.l.t (, %s10) 130 %3 = shl i64 %0, %1 131 ret i64 %3 132} 133 134; Function Attrs: norecurse nounwind readnone 135define i64 @shl_u64_var(i64 %0, i64 %1) { 136; CHECK-LABEL: shl_u64_var: 137; CHECK: # %bb.0: 138; CHECK-NEXT: sll %s0, %s0, %s1 139; CHECK-NEXT: b.l.t (, %s10) 140 %3 = shl i64 %0, %1 141 ret i64 %3 142} 143 144; Function Attrs: norecurse nounwind readnone 145define i128 @shl_i128_var(i128 %0, i128 %1) { 146; CHECK-LABEL: shl_i128_var: 147; CHECK: .LBB{{[0-9]+}}_2: 148; CHECK-NEXT: and %s2, %s2, (32)0 149; CHECK-NEXT: lea %s3, __ashlti3@lo 150; CHECK-NEXT: and %s3, %s3, (32)0 151; CHECK-NEXT: lea.sl %s12, __ashlti3@hi(, %s3) 152; CHECK-NEXT: bsic %s10, (, %s12) 153; CHECK-NEXT: or %s11, 0, %s9 154 %3 = shl i128 %0, %1 155 ret i128 %3 156} 157 158; Function Attrs: norecurse nounwind readnone 159define i128 @shl_u128_var(i128 %0, i128 %1) { 160; CHECK-LABEL: shl_u128_var: 161; CHECK: .LBB{{[0-9]+}}_2: 162; CHECK-NEXT: and %s2, %s2, (32)0 163; CHECK-NEXT: lea %s3, __ashlti3@lo 164; CHECK-NEXT: and %s3, %s3, (32)0 165; CHECK-NEXT: lea.sl %s12, __ashlti3@hi(, %s3) 166; CHECK-NEXT: bsic %s10, (, %s12) 167; CHECK-NEXT: or %s11, 0, %s9 168 %3 = shl i128 %0, %1 169 ret i128 %3 170} 171 172; Function Attrs: norecurse nounwind readnone 173define signext i8 @shl_const_i8(i8 signext %0) { 174; CHECK-LABEL: shl_const_i8: 175; CHECK: # %bb.0: 176; CHECK-NEXT: and %s0, %s0, (56)0 177; CHECK-NEXT: sla.w.sx %s0, (62)1, %s0 178; CHECK-NEXT: sll %s0, %s0, 56 179; CHECK-NEXT: sra.l %s0, %s0, 56 180; CHECK-NEXT: b.l.t (, %s10) 181 %2 = zext i8 %0 to i32 182 %3 = shl i32 -4, %2 183 %4 = trunc i32 %3 to i8 184 ret i8 %4 185} 186 187; Function Attrs: norecurse nounwind readnone 188define zeroext i8 @shl_const_u8(i8 zeroext %0) { 189; CHECK-LABEL: shl_const_u8: 190; CHECK: # %bb.0: 191; CHECK-NEXT: sla.w.sx %s0, (62)1, %s0 192; CHECK-NEXT: lea %s1, 252 193; CHECK-NEXT: and %s0, %s0, %s1 194; CHECK-NEXT: b.l.t (, %s10) 195 %2 = zext i8 %0 to i32 196 %3 = shl i32 -4, %2 197 %4 = trunc i32 %3 to i8 198 ret i8 %4 199} 200 201; Function Attrs: norecurse nounwind readnone 202define signext i16 @shl_const_i16(i16 signext %0) { 203; CHECK-LABEL: shl_const_i16: 204; CHECK: # %bb.0: 205; CHECK-NEXT: and %s0, %s0, (48)0 206; CHECK-NEXT: sla.w.sx %s0, (62)1, %s0 207; CHECK-NEXT: sll %s0, %s0, 48 208; CHECK-NEXT: sra.l %s0, %s0, 48 209; CHECK-NEXT: b.l.t (, %s10) 210 %2 = zext i16 %0 to i32 211 %3 = shl i32 -4, %2 212 %4 = trunc i32 %3 to i16 213 ret i16 %4 214} 215 216; Function Attrs: norecurse nounwind readnone 217define zeroext i16 @shl_const_u16(i16 zeroext %0) { 218; CHECK-LABEL: shl_const_u16: 219; CHECK: # %bb.0: 220; CHECK-NEXT: sla.w.sx %s0, (62)1, %s0 221; CHECK-NEXT: lea %s1, 65532 222; CHECK-NEXT: and %s0, %s0, %s1 223; CHECK-NEXT: b.l.t (, %s10) 224 %2 = zext i16 %0 to i32 225 %3 = shl i32 -4, %2 226 %4 = trunc i32 %3 to i16 227 ret i16 %4 228} 229 230; Function Attrs: norecurse nounwind readnone 231define signext i32 @shl_const_i32(i32 signext %0) { 232; CHECK-LABEL: shl_const_i32: 233; CHECK: # %bb.0: 234; CHECK-NEXT: sla.w.sx %s0, (62)1, %s0 235; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 236; CHECK-NEXT: b.l.t (, %s10) 237 %2 = shl i32 -4, %0 238 ret i32 %2 239} 240 241; Function Attrs: norecurse nounwind readnone 242define zeroext i32 @shl_const_u32(i32 zeroext %0) { 243; CHECK-LABEL: shl_const_u32: 244; CHECK: # %bb.0: 245; CHECK-NEXT: sla.w.sx %s0, (62)1, %s0 246; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 247; CHECK-NEXT: b.l.t (, %s10) 248 %2 = shl i32 -4, %0 249 ret i32 %2 250} 251 252; Function Attrs: norecurse nounwind readnone 253define i64 @shl_const_i64(i64 %0) { 254; CHECK-LABEL: shl_const_i64: 255; CHECK: # %bb.0: 256; CHECK-NEXT: sll %s0, (62)1, %s0 257; CHECK-NEXT: b.l.t (, %s10) 258 %2 = shl i64 -4, %0 259 ret i64 %2 260} 261 262; Function Attrs: norecurse nounwind readnone 263define i64 @shl_const_u64(i64 %0) { 264; CHECK-LABEL: shl_const_u64: 265; CHECK: # %bb.0: 266; CHECK-NEXT: sll %s0, (62)1, %s0 267; CHECK-NEXT: b.l.t (, %s10) 268 %2 = shl i64 -4, %0 269 ret i64 %2 270} 271 272; Function Attrs: norecurse nounwind readnone 273define i128 @shl_const_i128(i128 %0) { 274; CHECK-LABEL: shl_const_i128: 275; CHECK: .LBB{{[0-9]+}}_2: 276; CHECK-NEXT: and %s2, %s0, (32)0 277; CHECK-NEXT: lea %s0, __ashlti3@lo 278; CHECK-NEXT: and %s0, %s0, (32)0 279; CHECK-NEXT: lea.sl %s12, __ashlti3@hi(, %s0) 280; CHECK-NEXT: or %s0, -4, (0)1 281; CHECK-NEXT: or %s1, -1, (0)1 282; CHECK-NEXT: bsic %s10, (, %s12) 283; CHECK-NEXT: or %s11, 0, %s9 284 %2 = shl i128 -4, %0 285 ret i128 %2 286} 287 288; Function Attrs: norecurse nounwind readnone 289define i128 @shl_const_u128(i128 %0) { 290; CHECK-LABEL: shl_const_u128: 291; CHECK: .LBB{{[0-9]+}}_2: 292; CHECK-NEXT: and %s2, %s0, (32)0 293; CHECK-NEXT: lea %s0, __ashlti3@lo 294; CHECK-NEXT: and %s0, %s0, (32)0 295; CHECK-NEXT: lea.sl %s12, __ashlti3@hi(, %s0) 296; CHECK-NEXT: or %s0, -4, (0)1 297; CHECK-NEXT: or %s1, -1, (0)1 298; CHECK-NEXT: bsic %s10, (, %s12) 299; CHECK-NEXT: or %s11, 0, %s9 300 %2 = shl i128 -4, %0 301 ret i128 %2 302} 303 304; Function Attrs: norecurse nounwind readnone 305define signext i8 @shl_i8_const(i8 signext %0) { 306; CHECK-LABEL: shl_i8_const: 307; CHECK: # %bb.0: 308; CHECK-NEXT: sla.w.sx %s0, %s0, 3 309; CHECK-NEXT: sll %s0, %s0, 56 310; CHECK-NEXT: sra.l %s0, %s0, 56 311; CHECK-NEXT: b.l.t (, %s10) 312 %2 = shl i8 %0, 3 313 ret i8 %2 314} 315 316; Function Attrs: norecurse nounwind readnone 317define zeroext i8 @shl_u8_const(i8 zeroext %0) { 318; CHECK-LABEL: shl_u8_const: 319; CHECK: # %bb.0: 320; CHECK-NEXT: sla.w.sx %s0, %s0, 3 321; CHECK-NEXT: lea %s1, 248 322; CHECK-NEXT: and %s0, %s0, %s1 323; CHECK-NEXT: b.l.t (, %s10) 324 %2 = shl i8 %0, 3 325 ret i8 %2 326} 327 328; Function Attrs: norecurse nounwind readnone 329define signext i16 @shl_i16_const(i16 signext %0) { 330; CHECK-LABEL: shl_i16_const: 331; CHECK: # %bb.0: 332; CHECK-NEXT: sla.w.sx %s0, %s0, 7 333; CHECK-NEXT: sll %s0, %s0, 48 334; CHECK-NEXT: sra.l %s0, %s0, 48 335; CHECK-NEXT: b.l.t (, %s10) 336 %2 = shl i16 %0, 7 337 ret i16 %2 338} 339 340; Function Attrs: norecurse nounwind readnone 341define zeroext i16 @shl_u16_const(i16 zeroext %0) { 342; CHECK-LABEL: shl_u16_const: 343; CHECK: # %bb.0: 344; CHECK-NEXT: sla.w.sx %s0, %s0, 7 345; CHECK-NEXT: lea %s1, 65408 346; CHECK-NEXT: and %s0, %s0, %s1 347; CHECK-NEXT: b.l.t (, %s10) 348 %2 = shl i16 %0, 7 349 ret i16 %2 350} 351 352; Function Attrs: norecurse nounwind readnone 353define signext i32 @shl_i32_const(i32 signext %0) { 354; CHECK-LABEL: shl_i32_const: 355; CHECK: # %bb.0: 356; CHECK-NEXT: sla.w.sx %s0, %s0, 15 357; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 358; CHECK-NEXT: b.l.t (, %s10) 359 %2 = shl i32 %0, 15 360 ret i32 %2 361} 362 363; Function Attrs: norecurse nounwind readnone 364define zeroext i32 @shl_u32_const(i32 zeroext %0) { 365; CHECK-LABEL: shl_u32_const: 366; CHECK: # %bb.0: 367; CHECK-NEXT: sla.w.sx %s0, %s0, 15 368; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 369; CHECK-NEXT: b.l.t (, %s10) 370 %2 = shl i32 %0, 15 371 ret i32 %2 372} 373 374; Function Attrs: norecurse nounwind readnone 375define i64 @shl_i64_const(i64 %0) { 376; CHECK-LABEL: shl_i64_const: 377; CHECK: # %bb.0: 378; CHECK-NEXT: sll %s0, %s0, 63 379; CHECK-NEXT: b.l.t (, %s10) 380 %2 = shl i64 %0, 63 381 ret i64 %2 382} 383 384; Function Attrs: norecurse nounwind readnone 385define i64 @shl_u64_const(i64 %0) { 386; CHECK-LABEL: shl_u64_const: 387; CHECK: # %bb.0: 388; CHECK-NEXT: sll %s0, %s0, 63 389; CHECK-NEXT: b.l.t (, %s10) 390 %2 = shl i64 %0, 63 391 ret i64 %2 392} 393 394; Function Attrs: norecurse nounwind readnone 395define i128 @shl_i128_const(i128 %0) { 396; CHECK-LABEL: shl_i128_const: 397; CHECK: # %bb.0: 398; CHECK-NEXT: sll %s1, %s0, 63 399; CHECK-NEXT: or %s0, 0, (0)1 400; CHECK-NEXT: b.l.t (, %s10) 401 %2 = shl i128 %0, 127 402 ret i128 %2 403} 404 405; Function Attrs: norecurse nounwind readnone 406define i128 @shl_u128_const(i128 %0) { 407; CHECK-LABEL: shl_u128_const: 408; CHECK: # %bb.0: 409; CHECK-NEXT: sll %s1, %s0, 63 410; CHECK-NEXT: or %s0, 0, (0)1 411; CHECK-NEXT: b.l.t (, %s10) 412 %2 = shl i128 %0, 127 413 ret i128 %2 414} 415