227 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s3 4declare i8 @llvm.fshl.i8(i8, i8, i8)5declare i16 @llvm.fshl.i16(i16, i16, i16)6declare i32 @llvm.fshl.i32(i32, i32, i32)7declare i64 @llvm.fshl.i64(i64, i64, i64)8declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)9 10declare i8 @llvm.fshr.i8(i8, i8, i8)11declare i16 @llvm.fshr.i16(i16, i16, i16)12declare i32 @llvm.fshr.i32(i32, i32, i32)13declare i64 @llvm.fshr.i64(i64, i64, i64)14declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)15 16; When first 2 operands match, it's a rotate.17 18define i8 @rotl_i8_const_shift(i8 %x) {19; CHECK-LABEL: rotl_i8_const_shift:20; CHECK: // %bb.0:21; CHECK-NEXT: ubfx w8, w0, #5, #322; CHECK-NEXT: orr w0, w8, w0, lsl #323; CHECK-NEXT: ret24 %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)25 ret i8 %f26}27 28define i64 @rotl_i64_const_shift(i64 %x) {29; CHECK-LABEL: rotl_i64_const_shift:30; CHECK: // %bb.0:31; CHECK-NEXT: ror x0, x0, #6132; CHECK-NEXT: ret33 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 3)34 ret i64 %f35}36 37; When first 2 operands match, it's a rotate (by variable amount).38 39define i16 @rotl_i16(i16 %x, i16 %z) {40; CHECK-LABEL: rotl_i16:41; CHECK: // %bb.0:42; CHECK-NEXT: neg w8, w143; CHECK-NEXT: and w9, w0, #0xffff44; CHECK-NEXT: and w10, w1, #0xf45; CHECK-NEXT: and w8, w8, #0xf46; CHECK-NEXT: lsl w10, w0, w1047; CHECK-NEXT: lsr w8, w9, w848; CHECK-NEXT: orr w0, w10, w849; CHECK-NEXT: ret50 %f = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 %z)51 ret i16 %f52}53 54define i32 @rotl_i32(i32 %x, i32 %z) {55; CHECK-LABEL: rotl_i32:56; CHECK: // %bb.0:57; CHECK-NEXT: neg w8, w158; CHECK-NEXT: ror w0, w0, w859; CHECK-NEXT: ret60 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)61 ret i32 %f62}63 64define i64 @rotl_i64(i64 %x, i64 %z) {65; CHECK-LABEL: rotl_i64:66; CHECK: // %bb.0:67; CHECK-NEXT: neg w8, w168; CHECK-NEXT: ror x0, x0, x869; CHECK-NEXT: ret70 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %z)71 ret i64 %f72}73 74; Vector rotate.75 76define <4 x i32> @rotl_v4i32(<4 x i32> %x, <4 x i32> %z) {77; CHECK-LABEL: rotl_v4i32:78; CHECK: // %bb.0:79; CHECK-NEXT: movi v2.4s, #3180; CHECK-NEXT: neg v3.4s, v1.4s81; CHECK-NEXT: and v3.16b, v3.16b, v2.16b82; CHECK-NEXT: and v1.16b, v1.16b, v2.16b83; CHECK-NEXT: neg v2.4s, v3.4s84; CHECK-NEXT: ushl v1.4s, v0.4s, v1.4s85; CHECK-NEXT: ushl v0.4s, v0.4s, v2.4s86; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b87; CHECK-NEXT: ret88 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)89 ret <4 x i32> %f90}91 92; Vector rotate by constant splat amount.93 94define <4 x i32> @rotl_v4i32_rotl_const_shift(<4 x i32> %x) {95; CHECK-LABEL: rotl_v4i32_rotl_const_shift:96; CHECK: // %bb.0:97; CHECK-NEXT: shl v1.4s, v0.4s, #398; CHECK-NEXT: usra v1.4s, v0.4s, #2999; CHECK-NEXT: mov v0.16b, v1.16b100; CHECK-NEXT: ret101 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)102 ret <4 x i32> %f103}104 105; Repeat everything for funnel shift right.106 107; When first 2 operands match, it's a rotate.108 109define i8 @rotr_i8_const_shift(i8 %x) {110; CHECK-LABEL: rotr_i8_const_shift:111; CHECK: // %bb.0:112; CHECK-NEXT: lsl w8, w0, #5113; CHECK-NEXT: bfxil w8, w0, #3, #5114; CHECK-NEXT: mov w0, w8115; CHECK-NEXT: ret116 %f = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 3)117 ret i8 %f118}119 120define i32 @rotr_i32_const_shift(i32 %x) {121; CHECK-LABEL: rotr_i32_const_shift:122; CHECK: // %bb.0:123; CHECK-NEXT: ror w0, w0, #3124; CHECK-NEXT: ret125 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 3)126 ret i32 %f127}128 129; When first 2 operands match, it's a rotate (by variable amount).130 131define i16 @rotr_i16(i16 %x, i16 %z) {132; CHECK-LABEL: rotr_i16:133; CHECK: // %bb.0:134; CHECK-NEXT: neg w8, w1135; CHECK-NEXT: and w9, w0, #0xffff136; CHECK-NEXT: and w10, w1, #0xf137; CHECK-NEXT: and w8, w8, #0xf138; CHECK-NEXT: lsr w9, w9, w10139; CHECK-NEXT: lsl w8, w0, w8140; CHECK-NEXT: orr w0, w9, w8141; CHECK-NEXT: ret142 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %z)143 ret i16 %f144}145 146define i32 @rotr_i32(i32 %x, i32 %z) {147; CHECK-LABEL: rotr_i32:148; CHECK: // %bb.0:149; CHECK-NEXT: ror w0, w0, w1150; CHECK-NEXT: ret151 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %z)152 ret i32 %f153}154 155define i64 @rotr_i64(i64 %x, i64 %z) {156; CHECK-LABEL: rotr_i64:157; CHECK: // %bb.0:158; CHECK-NEXT: ror x0, x0, x1159; CHECK-NEXT: ret160 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)161 ret i64 %f162}163 164; Vector rotate.165 166define <4 x i32> @rotr_v4i32(<4 x i32> %x, <4 x i32> %z) {167; CHECK-LABEL: rotr_v4i32:168; CHECK: // %bb.0:169; CHECK-NEXT: movi v2.4s, #31170; CHECK-NEXT: neg v3.4s, v1.4s171; CHECK-NEXT: and v1.16b, v1.16b, v2.16b172; CHECK-NEXT: and v2.16b, v3.16b, v2.16b173; CHECK-NEXT: neg v1.4s, v1.4s174; CHECK-NEXT: ushl v2.4s, v0.4s, v2.4s175; CHECK-NEXT: ushl v0.4s, v0.4s, v1.4s176; CHECK-NEXT: orr v0.16b, v0.16b, v2.16b177; CHECK-NEXT: ret178 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)179 ret <4 x i32> %f180}181 182; Vector rotate by constant splat amount.183 184define <4 x i32> @rotr_v4i32_const_shift(<4 x i32> %x) {185; CHECK-LABEL: rotr_v4i32_const_shift:186; CHECK: // %bb.0:187; CHECK-NEXT: shl v1.4s, v0.4s, #29188; CHECK-NEXT: usra v1.4s, v0.4s, #3189; CHECK-NEXT: mov v0.16b, v1.16b190; CHECK-NEXT: ret191 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)192 ret <4 x i32> %f193}194 195define i32 @rotl_i32_shift_by_bitwidth(i32 %x) {196; CHECK-LABEL: rotl_i32_shift_by_bitwidth:197; CHECK: // %bb.0:198; CHECK-NEXT: ret199 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 32)200 ret i32 %f201}202 203define i32 @rotr_i32_shift_by_bitwidth(i32 %x) {204; CHECK-LABEL: rotr_i32_shift_by_bitwidth:205; CHECK: // %bb.0:206; CHECK-NEXT: ret207 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 32)208 ret i32 %f209}210 211define <4 x i32> @rotl_v4i32_shift_by_bitwidth(<4 x i32> %x) {212; CHECK-LABEL: rotl_v4i32_shift_by_bitwidth:213; CHECK: // %bb.0:214; CHECK-NEXT: ret215 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)216 ret <4 x i32> %f217}218 219define <4 x i32> @rotr_v4i32_shift_by_bitwidth(<4 x i32> %x) {220; CHECK-LABEL: rotr_v4i32_shift_by_bitwidth:221; CHECK: // %bb.0:222; CHECK-NEXT: ret223 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)224 ret <4 x i32> %f225}226 227