440 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=ppc32-- | FileCheck %s --check-prefixes=CHECK,CHECK32,CHECK32_323; RUN: llc < %s -mtriple=ppc32-- -mcpu=ppc64 | FileCheck %s --check-prefixes=CHECK,CHECK32,CHECK32_644; RUN: llc < %s -mtriple=powerpc64le-- | FileCheck %s --check-prefixes=CHECK,CHECK645; RUN: llc < %s -mcpu=future -mtriple=powerpc64le-- | FileCheck %s --check-prefix=FUTURE6 7declare i8 @llvm.fshl.i8(i8, i8, i8)8declare i16 @llvm.fshl.i16(i16, i16, i16)9declare i32 @llvm.fshl.i32(i32, i32, i32)10declare i64 @llvm.fshl.i64(i64, i64, i64)11declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)12 13declare i8 @llvm.fshr.i8(i8, i8, i8)14declare i16 @llvm.fshr.i16(i16, i16, i16)15declare i32 @llvm.fshr.i32(i32, i32, i32)16declare i64 @llvm.fshr.i64(i64, i64, i64)17declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)18 19; When first 2 operands match, it's a rotate.20 21define i8 @rotl_i8_const_shift(i8 %x) {22; CHECK-LABEL: rotl_i8_const_shift:23; CHECK: # %bb.0:24; CHECK-NEXT: rotlwi 4, 3, 2725; CHECK-NEXT: rlwimi 4, 3, 3, 0, 2826; CHECK-NEXT: mr 3, 427; CHECK-NEXT: blr28;29; FUTURE-LABEL: rotl_i8_const_shift:30; FUTURE: # %bb.0:31; FUTURE-NEXT: rotlwi 4, 3, 2732; FUTURE-NEXT: rlwimi 4, 3, 3, 0, 2833; FUTURE-NEXT: mr 3, 434; FUTURE-NEXT: blr35 %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)36 ret i8 %f37}38 39define i64 @rotl_i64_const_shift(i64 %x) {40; CHECK32-LABEL: rotl_i64_const_shift:41; CHECK32: # %bb.0:42; CHECK32-NEXT: rotlwi 5, 4, 343; CHECK32-NEXT: rotlwi 6, 3, 344; CHECK32-NEXT: rlwimi 5, 3, 3, 0, 2845; CHECK32-NEXT: rlwimi 6, 4, 3, 0, 2846; CHECK32-NEXT: mr 3, 547; CHECK32-NEXT: mr 4, 648; CHECK32-NEXT: blr49;50; CHECK64-LABEL: rotl_i64_const_shift:51; CHECK64: # %bb.0:52; CHECK64-NEXT: rotldi 3, 3, 353; CHECK64-NEXT: blr54;55; FUTURE-LABEL: rotl_i64_const_shift:56; FUTURE: # %bb.0:57; FUTURE-NEXT: rotldi 3, 3, 358; FUTURE-NEXT: blr59 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 3)60 ret i64 %f61}62 63; When first 2 operands match, it's a rotate (by variable amount).64 65define i16 @rotl_i16(i16 %x, i16 %z) {66; CHECK-LABEL: rotl_i16:67; CHECK: # %bb.0:68; CHECK-NEXT: clrlwi 6, 4, 2869; CHECK-NEXT: neg 4, 470; CHECK-NEXT: clrlwi 5, 3, 1671; CHECK-NEXT: clrlwi 4, 4, 2872; CHECK-NEXT: slw 3, 3, 673; CHECK-NEXT: srw 4, 5, 474; CHECK-NEXT: or 3, 3, 475; CHECK-NEXT: blr76;77; FUTURE-LABEL: rotl_i16:78; FUTURE: # %bb.0:79; FUTURE-NEXT: clrlwi 6, 4, 2880; FUTURE-NEXT: neg 4, 481; FUTURE-NEXT: clrlwi 5, 3, 1682; FUTURE-NEXT: clrlwi 4, 4, 2883; FUTURE-NEXT: slw 3, 3, 684; FUTURE-NEXT: srw 4, 5, 485; FUTURE-NEXT: or 3, 3, 486; FUTURE-NEXT: blr87 %f = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 %z)88 ret i16 %f89}90 91define i32 @rotl_i32(i32 %x, i32 %z) {92; CHECK-LABEL: rotl_i32:93; CHECK: # %bb.0:94; CHECK-NEXT: rotlw 3, 3, 495; CHECK-NEXT: blr96;97; FUTURE-LABEL: rotl_i32:98; FUTURE: # %bb.0:99; FUTURE-NEXT: rotlw 3, 3, 4100; FUTURE-NEXT: blr101 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)102 ret i32 %f103}104 105define i64 @rotl_i64(i64 %x, i64 %z) {106; CHECK32-LABEL: rotl_i64:107; CHECK32: # %bb.0:108; CHECK32-NEXT: andi. 5, 6, 32109; CHECK32-NEXT: mr 5, 3110; CHECK32-NEXT: bne 0, .LBB4_2111; CHECK32-NEXT: # %bb.1:112; CHECK32-NEXT: mr 5, 4113; CHECK32-NEXT: .LBB4_2:114; CHECK32-NEXT: clrlwi 6, 6, 27115; CHECK32-NEXT: subfic 8, 6, 32116; CHECK32-NEXT: srw 7, 5, 8117; CHECK32-NEXT: bne 0, .LBB4_4118; CHECK32-NEXT: # %bb.3:119; CHECK32-NEXT: mr 4, 3120; CHECK32-NEXT: .LBB4_4:121; CHECK32-NEXT: slw 3, 4, 6122; CHECK32-NEXT: srw 4, 4, 8123; CHECK32-NEXT: slw 5, 5, 6124; CHECK32-NEXT: or 3, 3, 7125; CHECK32-NEXT: or 4, 5, 4126; CHECK32-NEXT: blr127;128; CHECK64-LABEL: rotl_i64:129; CHECK64: # %bb.0:130; CHECK64-NEXT: rotld 3, 3, 4131; CHECK64-NEXT: blr132;133; FUTURE-LABEL: rotl_i64:134; FUTURE: # %bb.0:135; FUTURE-NEXT: rotld 3, 3, 4136; FUTURE-NEXT: blr137 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %z)138 ret i64 %f139}140 141; Vector rotate.142 143define <4 x i32> @rotl_v4i32(<4 x i32> %x, <4 x i32> %z) {144; CHECK32_32-LABEL: rotl_v4i32:145; CHECK32_32: # %bb.0:146; CHECK32_32-NEXT: rotlw 3, 3, 7147; CHECK32_32-NEXT: rotlw 4, 4, 8148; CHECK32_32-NEXT: rotlw 5, 5, 9149; CHECK32_32-NEXT: rotlw 6, 6, 10150; CHECK32_32-NEXT: blr151;152; CHECK32_64-LABEL: rotl_v4i32:153; CHECK32_64: # %bb.0:154; CHECK32_64-NEXT: vrlw 2, 2, 3155; CHECK32_64-NEXT: blr156;157; CHECK64-LABEL: rotl_v4i32:158; CHECK64: # %bb.0:159; CHECK64-NEXT: vrlw 2, 2, 3160; CHECK64-NEXT: blr161;162; FUTURE-LABEL: rotl_v4i32:163; FUTURE: # %bb.0:164; FUTURE-NEXT: xvrlw 34, 34, 35165; FUTURE-NEXT: blr166 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)167 ret <4 x i32> %f168}169 170; Vector rotate by constant splat amount.171 172define <4 x i32> @rotl_v4i32_const_shift(<4 x i32> %x) {173; CHECK32_32-LABEL: rotl_v4i32_const_shift:174; CHECK32_32: # %bb.0:175; CHECK32_32-NEXT: rotlwi 3, 3, 3176; CHECK32_32-NEXT: rotlwi 4, 4, 3177; CHECK32_32-NEXT: rotlwi 5, 5, 3178; CHECK32_32-NEXT: rotlwi 6, 6, 3179; CHECK32_32-NEXT: blr180;181; CHECK32_64-LABEL: rotl_v4i32_const_shift:182; CHECK32_64: # %bb.0:183; CHECK32_64-NEXT: vspltisw 3, 3184; CHECK32_64-NEXT: vrlw 2, 2, 3185; CHECK32_64-NEXT: blr186;187; CHECK64-LABEL: rotl_v4i32_const_shift:188; CHECK64: # %bb.0:189; CHECK64-NEXT: vspltisw 3, 3190; CHECK64-NEXT: vrlw 2, 2, 3191; CHECK64-NEXT: blr192;193; FUTURE-LABEL: rotl_v4i32_const_shift:194; FUTURE: # %bb.0:195; FUTURE-NEXT: vspltisw 3, 3196; FUTURE-NEXT: xvrlw 34, 34, 35197; FUTURE-NEXT: blr198 %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>)199 ret <4 x i32> %f200}201 202; Repeat everything for funnel shift right.203 204define i8 @rotr_i8_const_shift(i8 %x) {205; CHECK-LABEL: rotr_i8_const_shift:206; CHECK: # %bb.0:207; CHECK-NEXT: rotlwi 4, 3, 29208; CHECK-NEXT: rlwimi 4, 3, 5, 0, 26209; CHECK-NEXT: mr 3, 4210; CHECK-NEXT: blr211;212; FUTURE-LABEL: rotr_i8_const_shift:213; FUTURE: # %bb.0:214; FUTURE-NEXT: rotlwi 4, 3, 29215; FUTURE-NEXT: rlwimi 4, 3, 5, 0, 26216; FUTURE-NEXT: mr 3, 4217; FUTURE-NEXT: blr218 %f = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 3)219 ret i8 %f220}221 222define i32 @rotr_i32_const_shift(i32 %x) {223; CHECK-LABEL: rotr_i32_const_shift:224; CHECK: # %bb.0:225; CHECK-NEXT: rotlwi 3, 3, 29226; CHECK-NEXT: blr227;228; FUTURE-LABEL: rotr_i32_const_shift:229; FUTURE: # %bb.0:230; FUTURE-NEXT: rotlwi 3, 3, 29231; FUTURE-NEXT: blr232 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 3)233 ret i32 %f234}235 236; When first 2 operands match, it's a rotate (by variable amount).237 238define i16 @rotr_i16(i16 %x, i16 %z) {239; CHECK-LABEL: rotr_i16:240; CHECK: # %bb.0:241; CHECK-NEXT: clrlwi 6, 4, 28242; CHECK-NEXT: neg 4, 4243; CHECK-NEXT: clrlwi 5, 3, 16244; CHECK-NEXT: clrlwi 4, 4, 28245; CHECK-NEXT: srw 5, 5, 6246; CHECK-NEXT: slw 3, 3, 4247; CHECK-NEXT: or 3, 5, 3248; CHECK-NEXT: blr249;250; FUTURE-LABEL: rotr_i16:251; FUTURE: # %bb.0:252; FUTURE-NEXT: clrlwi 6, 4, 28253; FUTURE-NEXT: neg 4, 4254; FUTURE-NEXT: clrlwi 5, 3, 16255; FUTURE-NEXT: clrlwi 4, 4, 28256; FUTURE-NEXT: srw 5, 5, 6257; FUTURE-NEXT: slw 3, 3, 4258; FUTURE-NEXT: or 3, 5, 3259; FUTURE-NEXT: blr260 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %z)261 ret i16 %f262}263 264define i32 @rotr_i32(i32 %x, i32 %z) {265; CHECK-LABEL: rotr_i32:266; CHECK: # %bb.0:267; CHECK-NEXT: neg 4, 4268; CHECK-NEXT: rotlw 3, 3, 4269; CHECK-NEXT: blr270;271; FUTURE-LABEL: rotr_i32:272; FUTURE: # %bb.0:273; FUTURE-NEXT: neg 4, 4274; FUTURE-NEXT: rotlw 3, 3, 4275; FUTURE-NEXT: blr276 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %z)277 ret i32 %f278}279 280define i64 @rotr_i64(i64 %x, i64 %z) {281; CHECK32-LABEL: rotr_i64:282; CHECK32: # %bb.0:283; CHECK32-NEXT: andi. 5, 6, 32284; CHECK32-NEXT: mr 5, 3285; CHECK32-NEXT: beq 0, .LBB11_2286; CHECK32-NEXT: # %bb.1:287; CHECK32-NEXT: mr 5, 4288; CHECK32-NEXT: .LBB11_2:289; CHECK32-NEXT: clrlwi 7, 6, 27290; CHECK32-NEXT: srw 6, 5, 7291; CHECK32-NEXT: beq 0, .LBB11_4292; CHECK32-NEXT: # %bb.3:293; CHECK32-NEXT: mr 4, 3294; CHECK32-NEXT: .LBB11_4:295; CHECK32-NEXT: subfic 3, 7, 32296; CHECK32-NEXT: srw 7, 4, 7297; CHECK32-NEXT: slw 4, 4, 3298; CHECK32-NEXT: slw 5, 5, 3299; CHECK32-NEXT: or 3, 4, 6300; CHECK32-NEXT: or 4, 5, 7301; CHECK32-NEXT: blr302;303; CHECK64-LABEL: rotr_i64:304; CHECK64: # %bb.0:305; CHECK64-NEXT: neg 4, 4306; CHECK64-NEXT: rotld 3, 3, 4307; CHECK64-NEXT: blr308;309; FUTURE-LABEL: rotr_i64:310; FUTURE: # %bb.0:311; FUTURE-NEXT: neg 4, 4312; FUTURE-NEXT: rotld 3, 3, 4313; FUTURE-NEXT: blr314 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)315 ret i64 %f316}317 318; Vector rotate.319 320define <4 x i32> @rotr_v4i32(<4 x i32> %x, <4 x i32> %z) {321; CHECK32_32-LABEL: rotr_v4i32:322; CHECK32_32: # %bb.0:323; CHECK32_32-NEXT: neg 7, 7324; CHECK32_32-NEXT: neg 8, 8325; CHECK32_32-NEXT: neg 9, 9326; CHECK32_32-NEXT: neg 10, 10327; CHECK32_32-NEXT: rotlw 3, 3, 7328; CHECK32_32-NEXT: rotlw 4, 4, 8329; CHECK32_32-NEXT: rotlw 5, 5, 9330; CHECK32_32-NEXT: rotlw 6, 6, 10331; CHECK32_32-NEXT: blr332;333; CHECK32_64-LABEL: rotr_v4i32:334; CHECK32_64: # %bb.0:335; CHECK32_64-NEXT: vxor 4, 4, 4336; CHECK32_64-NEXT: vsubuwm 3, 4, 3337; CHECK32_64-NEXT: vrlw 2, 2, 3338; CHECK32_64-NEXT: blr339;340; CHECK64-LABEL: rotr_v4i32:341; CHECK64: # %bb.0:342; CHECK64-NEXT: xxlxor 36, 36, 36343; CHECK64-NEXT: vsubuwm 3, 4, 3344; CHECK64-NEXT: vrlw 2, 2, 3345; CHECK64-NEXT: blr346;347; FUTURE-LABEL: rotr_v4i32:348; FUTURE: # %bb.0:349; FUTURE-NEXT: vnegw 3, 3350; FUTURE-NEXT: xvrlw 34, 34, 35351; FUTURE-NEXT: blr352 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)353 ret <4 x i32> %f354}355 356; Vector rotate by constant splat amount.357 358define <4 x i32> @rotr_v4i32_const_shift(<4 x i32> %x) {359; CHECK32_32-LABEL: rotr_v4i32_const_shift:360; CHECK32_32: # %bb.0:361; CHECK32_32-NEXT: rotlwi 3, 3, 29362; CHECK32_32-NEXT: rotlwi 4, 4, 29363; CHECK32_32-NEXT: rotlwi 5, 5, 29364; CHECK32_32-NEXT: rotlwi 6, 6, 29365; CHECK32_32-NEXT: blr366;367; CHECK32_64-LABEL: rotr_v4i32_const_shift:368; CHECK32_64: # %bb.0:369; CHECK32_64-NEXT: vspltisw 3, -16370; CHECK32_64-NEXT: vspltisw 4, 13371; CHECK32_64-NEXT: vsubuwm 3, 4, 3372; CHECK32_64-NEXT: vrlw 2, 2, 3373; CHECK32_64-NEXT: blr374;375; CHECK64-LABEL: rotr_v4i32_const_shift:376; CHECK64: # %bb.0:377; CHECK64-NEXT: vspltisw 3, -16378; CHECK64-NEXT: vspltisw 4, 13379; CHECK64-NEXT: vsubuwm 3, 4, 3380; CHECK64-NEXT: vrlw 2, 2, 3381; CHECK64-NEXT: blr382;383; FUTURE-LABEL: rotr_v4i32_const_shift:384; FUTURE: # %bb.0:385; FUTURE-NEXT: xxspltiw 0, 29386; FUTURE-NEXT: xvrlw 34, 34, 0387; FUTURE-NEXT: blr388 %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>)389 ret <4 x i32> %f390}391 392define i32 @rotl_i32_shift_by_bitwidth(i32 %x) {393; CHECK-LABEL: rotl_i32_shift_by_bitwidth:394; CHECK: # %bb.0:395; CHECK-NEXT: blr396;397; FUTURE-LABEL: rotl_i32_shift_by_bitwidth:398; FUTURE: # %bb.0:399; FUTURE-NEXT: blr400 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 32)401 ret i32 %f402}403 404define i32 @rotr_i32_shift_by_bitwidth(i32 %x) {405; CHECK-LABEL: rotr_i32_shift_by_bitwidth:406; CHECK: # %bb.0:407; CHECK-NEXT: blr408;409; FUTURE-LABEL: rotr_i32_shift_by_bitwidth:410; FUTURE: # %bb.0:411; FUTURE-NEXT: blr412 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 32)413 ret i32 %f414}415 416define <4 x i32> @rotl_v4i32_shift_by_bitwidth(<4 x i32> %x) {417; CHECK-LABEL: rotl_v4i32_shift_by_bitwidth:418; CHECK: # %bb.0:419; CHECK-NEXT: blr420;421; FUTURE-LABEL: rotl_v4i32_shift_by_bitwidth:422; FUTURE: # %bb.0:423; FUTURE-NEXT: blr424 %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>)425 ret <4 x i32> %f426}427 428define <4 x i32> @rotr_v4i32_shift_by_bitwidth(<4 x i32> %x) {429; CHECK-LABEL: rotr_v4i32_shift_by_bitwidth:430; CHECK: # %bb.0:431; CHECK-NEXT: blr432;433; FUTURE-LABEL: rotr_v4i32_shift_by_bitwidth:434; FUTURE: # %bb.0:435; FUTURE-NEXT: blr436 %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>)437 ret <4 x i32> %f438}439 440