445 lines · plain
1; RUN: llc < %s -mtriple=ve | FileCheck %s2 3;;; Test both ‘lshr’ and `ashr` instructions4;;;5;;; ‘lshr’ Instruction6;;;7;;; Syntax:8;;; <result> = lshr <ty> <op1>, <op2> ; yields ty:result9;;; <result> = lshr exact <ty> <op1>, <op2> ; yields ty:result10;;;11;;; Overview:12;;; The ‘lshr’ instruction (logical shift right) returns the first operand13;;; shifted to the right a specified number of bits with zero fill.14;;;15;;; Arguments:16;;; Both arguments to the ‘lshr’ instruction must be the same integer or17;;; vector of integer type. ‘op2’ is treated as an unsigned value.18;;;19;;; Semantics:20;;; This instruction always performs a logical shift right operation. The21;;; most significant bits of the result will be filled with zero bits after22;;; the shift. If op2 is (statically or dynamically) equal to or larger than23;;; the number of bits in op1, this instruction returns a poison value. If24;;; the arguments are vectors, each vector element of op1 is shifted by the25;;; corresponding shift amount in op2.26;;;27;;; If the exact keyword is present, the result value of the lshr is a28;;; poison value if any of the bits shifted out are non-zero.29;;;30;;; Example:31;;; <result> = lshr i32 4, 1 ; yields i32:result = 232;;; <result> = lshr i32 4, 2 ; yields i32:result = 133;;; <result> = lshr i8 4, 3 ; yields i8:result = 034;;; <result> = lshr i8 -2, 1 ; yields i8:result = 0x7F35;;; <result> = lshr i32 1, 32 ; undefined36;;; <result> = lshr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 2>37;;; ; yields: result=<2 x i32> < i32 0x7FFFFFFF, i32 1>38;;;39;;; ‘ashr’ Instruction40;;;41;;; Syntax:42;;; <result> = ashr <ty> <op1>, <op2> ; yields ty:result43;;; <result> = ashr exact <ty> <op1>, <op2> ; yields ty:result44;;;45;;; Overview:46;;; The ‘ashr’ instruction (arithmetic shift right) returns the first operand47;;; shifted to the right a specified number of bits with sign extension.48;;;49;;; Arguments:50;;; Both arguments to the ‘ashr’ instruction must be the same integer or51;;; vector of integer type. ‘op2’ is treated as an unsigned value.52;;;53;;; Semantics:54;;; This instruction always performs an arithmetic shift right operation, The55;;; most significant bits of the result will be filled with the sign bit of56;;; op1. If op2 is (statically or dynamically) equal to or larger than the57;;; number of bits in op1, this instruction returns a poison value. If the58;;; arguments are vectors, each vector element of op1 is shifted by the59;;; corresponding shift amount in op2.60;;;61;;; If the exact keyword is present, the result value of the ashr is a poison62;;; value if any of the bits shifted out are non-zero.63;;;64;;; Example:65;;; <result> = ashr i32 4, 1 ; yields i32:result = 266;;; <result> = ashr i32 4, 2 ; yields i32:result = 167;;; <result> = ashr i8 4, 3 ; yields i8:result = 068;;; <result> = ashr i8 -2, 1 ; yields i8:result = -169;;; <result> = ashr i32 1, 32 ; undefined70;;; <result> = ashr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 3>71;;; ; yields: result=<2 x i32> < i32 -1, i32 0>72;;;73;;; Note:74;;; We test only i8/i16/i32/i64/i128 and unsigned of them.75 76; Function Attrs: norecurse nounwind readnone77define signext i8 @shl_i8_var(i8 signext %0, i8 signext %1) {78; CHECK-LABEL: shl_i8_var:79; CHECK: # %bb.0:80; CHECK-NEXT: and %s1, %s1, (56)081; CHECK-NEXT: sra.w.sx %s0, %s0, %s182; CHECK-NEXT: adds.w.sx %s0, %s0, (0)183; CHECK-NEXT: b.l.t (, %s10)84 %3 = sext i8 %0 to i3285 %4 = zext i8 %1 to i3286 %5 = ashr i32 %3, %487 %6 = trunc i32 %5 to i888 ret i8 %689}90 91; Function Attrs: norecurse nounwind readnone92define zeroext i8 @shl_u8_var(i8 zeroext %0, i8 zeroext %1) {93; CHECK-LABEL: shl_u8_var:94; CHECK: # %bb.0:95; CHECK-NEXT: and %s0, %s0, (32)096; CHECK-NEXT: srl %s0, %s0, %s197; CHECK-NEXT: adds.w.zx %s0, %s0, (0)198; CHECK-NEXT: b.l.t (, %s10)99 %3 = zext i8 %0 to i32100 %4 = zext i8 %1 to i32101 %5 = lshr i32 %3, %4102 %6 = trunc i32 %5 to i8103 ret i8 %6104}105 106; Function Attrs: norecurse nounwind readnone107define signext i16 @shl_i16_var(i16 signext %0, i16 signext %1) {108; CHECK-LABEL: shl_i16_var:109; CHECK: # %bb.0:110; CHECK-NEXT: and %s1, %s1, (48)0111; CHECK-NEXT: sra.w.sx %s0, %s0, %s1112; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1113; CHECK-NEXT: b.l.t (, %s10)114 %3 = sext i16 %0 to i32115 %4 = zext i16 %1 to i32116 %5 = ashr i32 %3, %4117 %6 = trunc i32 %5 to i16118 ret i16 %6119}120 121; Function Attrs: norecurse nounwind readnone122define zeroext i16 @shl_u16_var(i16 zeroext %0, i16 zeroext %1) {123; CHECK-LABEL: shl_u16_var:124; CHECK: # %bb.0:125; CHECK-NEXT: and %s0, %s0, (32)0126; CHECK-NEXT: srl %s0, %s0, %s1127; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1128; CHECK-NEXT: b.l.t (, %s10)129 %3 = zext i16 %0 to i32130 %4 = zext i16 %1 to i32131 %5 = lshr i32 %3, %4132 %6 = trunc i32 %5 to i16133 ret i16 %6134}135 136; Function Attrs: norecurse nounwind readnone137define signext i32 @shl_i32_var(i32 signext %0, i32 signext %1) {138; CHECK-LABEL: shl_i32_var:139; CHECK: # %bb.0:140; CHECK-NEXT: sra.w.sx %s0, %s0, %s1141; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1142; CHECK-NEXT: b.l.t (, %s10)143 %3 = ashr i32 %0, %1144 ret i32 %3145}146 147; Function Attrs: norecurse nounwind readnone148define zeroext i32 @shl_u32_var(i32 zeroext %0, i32 zeroext %1) {149; CHECK-LABEL: shl_u32_var:150; CHECK: # %bb.0:151; CHECK-NEXT: and %s0, %s0, (32)0152; CHECK-NEXT: srl %s0, %s0, %s1153; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1154; CHECK-NEXT: b.l.t (, %s10)155 %3 = lshr i32 %0, %1156 ret i32 %3157}158 159; Function Attrs: norecurse nounwind readnone160define i64 @shl_i64_var(i64 %0, i64 %1) {161; CHECK-LABEL: shl_i64_var:162; CHECK: # %bb.0:163; CHECK-NEXT: sra.l %s0, %s0, %s1164; CHECK-NEXT: b.l.t (, %s10)165 %3 = ashr i64 %0, %1166 ret i64 %3167}168 169; Function Attrs: norecurse nounwind readnone170define i64 @shl_u64_var(i64 %0, i64 %1) {171; CHECK-LABEL: shl_u64_var:172; CHECK: # %bb.0:173; CHECK-NEXT: srl %s0, %s0, %s1174; CHECK-NEXT: b.l.t (, %s10)175 %3 = lshr i64 %0, %1176 ret i64 %3177}178 179; Function Attrs: norecurse nounwind readnone180define i128 @shl_i128_var(i128 %0, i128 %1) {181; CHECK-LABEL: shl_i128_var:182; CHECK: .LBB{{[0-9]+}}_2:183; CHECK-NEXT: adds.w.sx %s2, %s2, (0)1184; CHECK-NEXT: lea %s3, __ashrti3@lo185; CHECK-NEXT: and %s3, %s3, (32)0186; CHECK-NEXT: lea.sl %s12, __ashrti3@hi(, %s3)187; CHECK-NEXT: bsic %s10, (, %s12)188; CHECK-NEXT: or %s11, 0, %s9189 %3 = ashr i128 %0, %1190 ret i128 %3191}192 193; Function Attrs: norecurse nounwind readnone194define i128 @shl_u128_var(i128 %0, i128 %1) {195; CHECK-LABEL: shl_u128_var:196; CHECK: .LBB{{[0-9]+}}_2:197; CHECK-NEXT: and %s2, %s2, (32)0198; CHECK-NEXT: lea %s3, __lshrti3@lo199; CHECK-NEXT: and %s3, %s3, (32)0200; CHECK-NEXT: lea.sl %s12, __lshrti3@hi(, %s3)201; CHECK-NEXT: bsic %s10, (, %s12)202; CHECK-NEXT: or %s11, 0, %s9203 %3 = lshr i128 %0, %1204 ret i128 %3205}206 207; Function Attrs: norecurse nounwind readnone208define signext i8 @shl_const_i8(i8 signext %0) {209; CHECK-LABEL: shl_const_i8:210; CHECK: # %bb.0:211; CHECK-NEXT: and %s0, %s0, (56)0212; CHECK-NEXT: sra.w.sx %s0, (62)1, %s0213; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1214; CHECK-NEXT: b.l.t (, %s10)215 %2 = zext i8 %0 to i32216 %3 = ashr i32 -4, %2217 %4 = trunc i32 %3 to i8218 ret i8 %4219}220 221; Function Attrs: norecurse nounwind readnone222define zeroext i8 @shl_const_u8(i8 zeroext %0) {223; CHECK-LABEL: shl_const_u8:224; CHECK: # %bb.0:225; CHECK-NEXT: sra.w.sx %s0, (62)1, %s0226; CHECK-NEXT: and %s0, %s0, (56)0227; CHECK-NEXT: b.l.t (, %s10)228 %2 = zext i8 %0 to i32229 %3 = ashr i32 -4, %2230 %4 = trunc i32 %3 to i8231 ret i8 %4232}233 234; Function Attrs: norecurse nounwind readnone235define signext i16 @shl_const_i16(i16 signext %0) {236; CHECK-LABEL: shl_const_i16:237; CHECK: # %bb.0:238; CHECK-NEXT: and %s0, %s0, (48)0239; CHECK-NEXT: sra.w.sx %s0, (62)1, %s0240; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1241; CHECK-NEXT: b.l.t (, %s10)242 %2 = zext i16 %0 to i32243 %3 = ashr i32 -4, %2244 %4 = trunc i32 %3 to i16245 ret i16 %4246}247 248; Function Attrs: norecurse nounwind readnone249define zeroext i16 @shl_const_u16(i16 zeroext %0) {250; CHECK-LABEL: shl_const_u16:251; CHECK: # %bb.0:252; CHECK-NEXT: sra.w.sx %s0, (62)1, %s0253; CHECK-NEXT: and %s0, %s0, (48)0254; CHECK-NEXT: b.l.t (, %s10)255 %2 = zext i16 %0 to i32256 %3 = ashr i32 -4, %2257 %4 = trunc i32 %3 to i16258 ret i16 %4259}260 261; Function Attrs: norecurse nounwind readnone262define signext i32 @shl_const_i32(i32 signext %0) {263; CHECK-LABEL: shl_const_i32:264; CHECK: # %bb.0:265; CHECK-NEXT: sra.w.sx %s0, (62)1, %s0266; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1267; CHECK-NEXT: b.l.t (, %s10)268 %2 = ashr i32 -4, %0269 ret i32 %2270}271 272; Function Attrs: norecurse nounwind readnone273define zeroext i32 @shl_const_u32(i32 zeroext %0) {274; CHECK-LABEL: shl_const_u32:275; CHECK: # %bb.0:276; CHECK-NEXT: sra.w.sx %s0, (62)1, %s0277; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1278; CHECK-NEXT: b.l.t (, %s10)279 %2 = ashr i32 -4, %0280 ret i32 %2281}282 283; Function Attrs: norecurse nounwind readnone284define i64 @shl_const_i64(i64 %0) {285; CHECK-LABEL: shl_const_i64:286; CHECK: # %bb.0:287; CHECK-NEXT: sra.l %s0, (62)1, %s0288; CHECK-NEXT: b.l.t (, %s10)289 %2 = ashr i64 -4, %0290 ret i64 %2291}292 293; Function Attrs: norecurse nounwind readnone294define i64 @shl_const_u64(i64 %0) {295; CHECK-LABEL: shl_const_u64:296; CHECK: # %bb.0:297; CHECK-NEXT: sra.l %s0, (62)1, %s0298; CHECK-NEXT: b.l.t (, %s10)299 %2 = ashr i64 -4, %0300 ret i64 %2301}302 303; Function Attrs: norecurse nounwind readnone304define i128 @shl_const_i128(i128 %0) {305; CHECK-LABEL: shl_const_i128:306; CHECK: .LBB{{[0-9]+}}_2:307; CHECK-NEXT: adds.w.sx %s2, %s0, (0)1308; CHECK-NEXT: lea %s0, __ashrti3@lo309; CHECK-NEXT: and %s0, %s0, (32)0310; CHECK-NEXT: lea.sl %s12, __ashrti3@hi(, %s0)311; CHECK-NEXT: or %s0, -4, (0)1312; CHECK-NEXT: or %s1, -1, (0)1313; CHECK-NEXT: bsic %s10, (, %s12)314; CHECK-NEXT: or %s11, 0, %s9315 %2 = ashr i128 -4, %0316 ret i128 %2317}318 319; Function Attrs: norecurse nounwind readnone320define i128 @shl_const_u128(i128 %0) {321; CHECK-LABEL: shl_const_u128:322; CHECK: .LBB{{[0-9]+}}_2:323; CHECK-NEXT: adds.w.sx %s2, %s0, (0)1324; CHECK-NEXT: lea %s0, __ashrti3@lo325; CHECK-NEXT: and %s0, %s0, (32)0326; CHECK-NEXT: lea.sl %s12, __ashrti3@hi(, %s0)327; CHECK-NEXT: or %s0, -4, (0)1328; CHECK-NEXT: or %s1, -1, (0)1329; CHECK-NEXT: bsic %s10, (, %s12)330; CHECK-NEXT: or %s11, 0, %s9331 %2 = ashr i128 -4, %0332 ret i128 %2333}334 335; Function Attrs: norecurse nounwind readnone336define signext i8 @shl_i8_const(i8 signext %0) {337; CHECK-LABEL: shl_i8_const:338; CHECK: # %bb.0:339; CHECK-NEXT: sra.w.sx %s0, %s0, 3340; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1341; CHECK-NEXT: b.l.t (, %s10)342 %2 = ashr i8 %0, 3343 ret i8 %2344}345 346; Function Attrs: norecurse nounwind readnone347define zeroext i8 @shl_u8_const(i8 zeroext %0) {348; CHECK-LABEL: shl_u8_const:349; CHECK: # %bb.0:350; CHECK-NEXT: and %s0, %s0, (32)0351; CHECK-NEXT: srl %s0, %s0, 3352; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1353; CHECK-NEXT: b.l.t (, %s10)354 %2 = lshr i8 %0, 3355 ret i8 %2356}357 358; Function Attrs: norecurse nounwind readnone359define signext i16 @shl_i16_const(i16 signext %0) {360; CHECK-LABEL: shl_i16_const:361; CHECK: # %bb.0:362; CHECK-NEXT: sra.w.sx %s0, %s0, 7363; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1364; CHECK-NEXT: b.l.t (, %s10)365 %2 = ashr i16 %0, 7366 ret i16 %2367}368 369; Function Attrs: norecurse nounwind readnone370define zeroext i16 @shl_u16_const(i16 zeroext %0) {371; CHECK-LABEL: shl_u16_const:372; CHECK: # %bb.0:373; CHECK-NEXT: and %s0, %s0, (32)0374; CHECK-NEXT: srl %s0, %s0, 7375; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1376; CHECK-NEXT: b.l.t (, %s10)377 %2 = lshr i16 %0, 7378 ret i16 %2379}380 381; Function Attrs: norecurse nounwind readnone382define signext i32 @shl_i32_const(i32 signext %0) {383; CHECK-LABEL: shl_i32_const:384; CHECK: # %bb.0:385; CHECK-NEXT: sra.w.sx %s0, %s0, 15386; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1387; CHECK-NEXT: b.l.t (, %s10)388 %2 = ashr i32 %0, 15389 ret i32 %2390}391 392; Function Attrs: norecurse nounwind readnone393define zeroext i32 @shl_u32_const(i32 zeroext %0) {394; CHECK-LABEL: shl_u32_const:395; CHECK: # %bb.0:396; CHECK-NEXT: and %s0, %s0, (32)0397; CHECK-NEXT: srl %s0, %s0, 15398; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1399; CHECK-NEXT: b.l.t (, %s10)400 %2 = lshr i32 %0, 15401 ret i32 %2402}403 404; Function Attrs: norecurse nounwind readnone405define i64 @shl_i64_const(i64 %0) {406; CHECK-LABEL: shl_i64_const:407; CHECK: # %bb.0:408; CHECK-NEXT: sra.l %s0, %s0, 63409; CHECK-NEXT: b.l.t (, %s10)410 %2 = ashr i64 %0, 63411 ret i64 %2412}413 414; Function Attrs: norecurse nounwind readnone415define i64 @shl_u64_const(i64 %0) {416; CHECK-LABEL: shl_u64_const:417; CHECK: # %bb.0:418; CHECK-NEXT: srl %s0, %s0, 63419; CHECK-NEXT: b.l.t (, %s10)420 %2 = lshr i64 %0, 63421 ret i64 %2422}423 424; Function Attrs: norecurse nounwind readnone425define i128 @shl_i128_const(i128 %0) {426; CHECK-LABEL: shl_i128_const:427; CHECK: # %bb.0:428; CHECK-NEXT: sra.l %s0, %s1, 63429; CHECK-NEXT: or %s1, 0, %s0430; CHECK-NEXT: b.l.t (, %s10)431 %2 = ashr i128 %0, 127432 ret i128 %2433}434 435; Function Attrs: norecurse nounwind readnone436define i128 @shl_u128_const(i128 %0) {437; CHECK-LABEL: shl_u128_const:438; CHECK: # %bb.0:439; CHECK-NEXT: srl %s0, %s1, 63440; CHECK-NEXT: or %s1, 0, (0)1441; CHECK-NEXT: b.l.t (, %s10)442 %2 = lshr i128 %0, 127443 ret i128 %2444}445