311 lines · plain
1; RUN: llc -debug-only=isel -o /dev/null < %s 2>&1 | FileCheck %s2 3; REQUIRES: asserts4 5; NOTE: Due to their nature the expected inserts and extracts often emit no6; instructions and so these tests verify the output of DAGCombiner directly.7 8target triple = "aarch64-unknown-linux-gnu"9 10; CHECK: Initial selection DAG: %bb.0 'insert_small_fixed_into_big_fixed:'11; CHECK: SelectionDAG has 10 nodes:12; CHECK: t0: ch,glue = EntryToken13; CHECK: t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %014; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>15; CHECK: t6: v16i8 = insert_subvector poison:v16i8, t4, Constant:i64<0>16; CHECK: t8: ch,glue = CopyToReg t0, Register:v16i8 $q0, t617; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v16i8 $q0, t8:118 19; CHECK: Optimized lowered selection DAG: %bb.0 'insert_small_fixed_into_big_fixed:'20; CHECK: SelectionDAG has 9 nodes:21; CHECK: t0: ch,glue = EntryToken22; CHECK: t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %023; CHECK: t10: v16i8 = insert_subvector poison:v16i8, t2, Constant:i64<0>24; CHECK: t8: ch,glue = CopyToReg t0, Register:v16i8 $q0, t1025; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v16i8 $q0, t8:126 27define <16 x i8> @insert_small_fixed_into_big_fixed(<8 x i8> %a) #0 {28 %extract = call <4 x i8> @llvm.vector.extract(<8 x i8> %a, i64 0)29 %insert = call <16 x i8> @llvm.vector.insert(<16 x i8> poison, <4 x i8> %extract, i64 0)30 ret <16 x i8> %insert31}32 33; CHECK: Initial selection DAG: %bb.0 'insert_small_fixed_into_big_scalable:'34; CHECK: SelectionDAG has 10 nodes:35; CHECK: t0: ch,glue = EntryToken36; CHECK: t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %037; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>38; CHECK: t6: nxv16i8 = insert_subvector poison:nxv16i8, t4, Constant:i64<0>39; CHECK: t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t640; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:141 42; CHECK: Optimized lowered selection DAG: %bb.0 'insert_small_fixed_into_big_scalable:'43; CHECK: SelectionDAG has 9 nodes:44; CHECK: t0: ch,glue = EntryToken45; CHECK: t2: v8i8,ch = CopyFromReg t0, Register:v8i8 %046; CHECK: t10: nxv16i8 = insert_subvector poison:nxv16i8, t2, Constant:i64<0>47; CHECK: t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t1048; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:149 50define <vscale x 16 x i8> @insert_small_fixed_into_big_scalable(<8 x i8> %a) #0 {51 %extract = call <4 x i8> @llvm.vector.extract(<8 x i8> %a, i64 0)52 %insert = call <vscale x 16 x i8> @llvm.vector.insert(<vscale x 16 x i8> poison, <4 x i8> %extract, i64 0)53 ret <vscale x 16 x i8> %insert54}55 56; CHECK: Initial selection DAG: %bb.0 'insert_small_scalable_into_big_fixed:'57; CHECK: SelectionDAG has 11 nodes:58; CHECK: t0: ch,glue = EntryToken59; CHECK: t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %060; CHECK: t3: nxv8i8 = truncate t261; CHECK: t5: v4i8 = extract_subvector t3, Constant:i64<0>62; CHECK: t7: v16i8 = insert_subvector poison:v16i8, t5, Constant:i64<0>63; CHECK: t9: ch,glue = CopyToReg t0, Register:v16i8 $q0, t764; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:v16i8 $q0, t9:165 66; CHECK: Optimized lowered selection DAG: %bb.0 'insert_small_scalable_into_big_fixed:'67; CHECK: SelectionDAG has 11 nodes:68; CHECK: t0: ch,glue = EntryToken69; CHECK: t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %070; CHECK: t3: nxv8i8 = truncate t271; CHECK: t5: v4i8 = extract_subvector t3, Constant:i64<0>72; CHECK: t7: v16i8 = insert_subvector poison:v16i8, t5, Constant:i64<0>73; CHECK: t9: ch,glue = CopyToReg t0, Register:v16i8 $q0, t774; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:v16i8 $q0, t9:175 76; Resulting insert would not be legal, so there's no transformation.77define <16 x i8> @insert_small_scalable_into_big_fixed(<vscale x 8 x i8> %a) #0 {78 %extract = call <4 x i8> @llvm.vector.extract(<vscale x 8 x i8> %a, i64 0)79 %insert = call <16 x i8> @llvm.vector.insert(<16 x i8> poison, <4 x i8> %extract, i64 0)80 ret <16 x i8> %insert81}82 83; CHECK: Initial selection DAG: %bb.0 'insert_small_scalable_into_big_scalable_1:'84; CHECK: SelectionDAG has 11 nodes:85; CHECK: t0: ch,glue = EntryToken86; CHECK: t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %087; CHECK: t3: nxv8i8 = truncate t288; CHECK: t5: v4i8 = extract_subvector t3, Constant:i64<0>89; CHECK: t7: nxv16i8 = insert_subvector poison:nxv16i8, t5, Constant:i64<0>90; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t791; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:192 93; CHECK: Optimized lowered selection DAG: %bb.0 'insert_small_scalable_into_big_scalable_1:'94; CHECK: SelectionDAG has 10 nodes:95; CHECK: t0: ch,glue = EntryToken96; CHECK: t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %097; CHECK: t3: nxv8i8 = truncate t298; CHECK: t11: nxv16i8 = insert_subvector poison:nxv16i8, t3, Constant:i64<0>99; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t11100; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:1101 102define <vscale x 16 x i8> @insert_small_scalable_into_big_scalable_1(<vscale x 8 x i8> %a) #0 {103 %extract = call <4 x i8> @llvm.vector.extract(<vscale x 8 x i8> %a, i64 0)104 %insert = call <vscale x 16 x i8> @llvm.vector.insert(<vscale x 16 x i8> poison, <4 x i8> %extract, i64 0)105 ret <vscale x 16 x i8> %insert106}107 108; CHECK: Initial selection DAG: %bb.0 'insert_small_scalable_into_big_scalable_2:'109; CHECK: SelectionDAG has 11 nodes:110; CHECK: t0: ch,glue = EntryToken111; CHECK: t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0112; CHECK: t3: nxv8i8 = truncate t2113; CHECK: t5: nxv4i8 = extract_subvector t3, Constant:i64<0>114; CHECK: t7: nxv16i8 = insert_subvector poison:nxv16i8, t5, Constant:i64<0>115; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t7116; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:1117 118; CHECK: Optimized lowered selection DAG: %bb.0 'insert_small_scalable_into_big_scalable_2:'119; CHECK: SelectionDAG has 10 nodes:120; CHECK: t0: ch,glue = EntryToken121; CHECK: t2: nxv8i16,ch = CopyFromReg t0, Register:nxv8i16 %0122; CHECK: t3: nxv8i8 = truncate t2123; CHECK: t11: nxv16i8 = insert_subvector poison:nxv16i8, t3, Constant:i64<0>124; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t11125; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv16i8 $z0, t9:1126 127define <vscale x 16 x i8> @insert_small_scalable_into_big_scalable_2(<vscale x 8 x i8> %a) #0 {128 %extract = call <vscale x 4 x i8> @llvm.vector.extract(<vscale x 8 x i8> %a, i64 0)129 %insert = call <vscale x 16 x i8> @llvm.vector.insert(<vscale x 16 x i8> poison, <vscale x 4 x i8> %extract, i64 0)130 ret <vscale x 16 x i8> %insert131}132 133; CHECK: Initial selection DAG: %bb.0 'extract_small_fixed_from_big_fixed:'134; CHECK: SelectionDAG has 10 nodes:135; CHECK: t0: ch,glue = EntryToken136; CHECK: t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0137; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>138; CHECK: t6: v8i8 = insert_subvector poison:v8i8, t4, Constant:i64<0>139; CHECK: t8: ch,glue = CopyToReg t0, Register:v8i8 $d0, t6140; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v8i8 $d0, t8:1141 142; CHECK: Optimized lowered selection DAG: %bb.0 'extract_small_fixed_from_big_fixed:'143; CHECK: SelectionDAG has 8 nodes:144; CHECK: t0: ch,glue = EntryToken145; CHECK: t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0146; CHECK: t10: v8i8 = extract_subvector t2, Constant:i64<0>147; CHECK: t8: ch,glue = CopyToReg t0, Register:v8i8 $d0, t10148; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v8i8 $d0, t8:1149 150define <8 x i8> @extract_small_fixed_from_big_fixed(<16 x i8> %a) #0 {151 %extract = call <4 x i8> @llvm.vector.extract(<16 x i8> %a, i64 0)152 %insert = call <8 x i8> @llvm.vector.insert(<8 x i8> poison, <4 x i8> %extract, i64 0)153 ret <8 x i8> %insert154}155 156; CHECK: Initial selection DAG: %bb.0 'extract_small_scalable_from_big_fixed:'157; CHECK: SelectionDAG has 11 nodes:158; CHECK: t0: ch,glue = EntryToken159; CHECK: t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0160; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>161; CHECK: t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>162; CHECK: t7: nxv8i16 = any_extend t6163; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7164; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1165 166; CHECK: Optimized lowered selection DAG: %bb.0 'extract_small_scalable_from_big_fixed:'167; CHECK: SelectionDAG has 11 nodes:168; CHECK: t0: ch,glue = EntryToken169; CHECK: t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0170; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>171; CHECK: t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>172; CHECK: t7: nxv8i16 = any_extend t6173; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7174; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1175 176; Resulting insert would not be legal, so there's no transformation.177define <vscale x 8 x i8> @extract_small_scalable_from_big_fixed(<16 x i8> %a) #0 {178 %extract = call <4 x i8> @llvm.vector.extract(<16 x i8> %a, i64 0)179 %insert = call <vscale x 8 x i8> @llvm.vector.insert(<vscale x 8 x i8> poison, <4 x i8> %extract, i64 0)180 ret <vscale x 8 x i8> %insert181}182 183; CHECK: Initial selection DAG: %bb.0 'extract_small_fixed_from_big_scalable:'184; CHECK: SelectionDAG has 10 nodes:185; CHECK: t0: ch,glue = EntryToken186; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0187; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>188; CHECK: t6: v8i8 = insert_subvector poison:v8i8, t4, Constant:i64<0>189; CHECK: t8: ch,glue = CopyToReg t0, Register:v8i8 $d0, t6190; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v8i8 $d0, t8:1191 192; CHECK: Optimized lowered selection DAG: %bb.0 'extract_small_fixed_from_big_scalable:'193; CHECK: SelectionDAG has 8 nodes:194; CHECK: t0: ch,glue = EntryToken195; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0196; CHECK: t10: v8i8 = extract_subvector t2, Constant:i64<0>197; CHECK: t8: ch,glue = CopyToReg t0, Register:v8i8 $d0, t10198; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v8i8 $d0, t8:1199 200define <8 x i8> @extract_small_fixed_from_big_scalable(<vscale x 16 x i8> %a) #0 {201 %extract = call <4 x i8> @llvm.vector.extract(<vscale x 16 x i8> %a, i64 0)202 %insert = call <8 x i8> @llvm.vector.insert(<8 x i8> poison, <4 x i8> %extract, i64 0)203 ret <8 x i8> %insert204}205 206; CHECK: Initial selection DAG: %bb.0 'extract_small_scalable_from_big_scalable_1:'207; CHECK: SelectionDAG has 11 nodes:208; CHECK: t0: ch,glue = EntryToken209; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0210; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>211; CHECK: t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>212; CHECK: t7: nxv8i16 = any_extend t6213; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7214; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1215 216; CHECK: Optimized lowered selection DAG: %bb.0 'extract_small_scalable_from_big_scalable_1:'217; CHECK: SelectionDAG has 9 nodes:218; CHECK: t0: ch,glue = EntryToken219; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0220; CHECK: t11: nxv8i8 = extract_subvector t2, Constant:i64<0>221; CHECK: t7: nxv8i16 = any_extend t11222; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7223; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1224 225define <vscale x 8 x i8> @extract_small_scalable_from_big_scalable_1(<vscale x 16 x i8> %a) #0 {226 %extract = call <4 x i8> @llvm.vector.extract(<vscale x 16 x i8> %a, i64 0)227 %insert = call <vscale x 8 x i8> @llvm.vector.insert(<vscale x 8 x i8> poison, <4 x i8> %extract, i64 0)228 ret <vscale x 8 x i8> %insert229}230 231; CHECK: Initial selection DAG: %bb.0 'extract_small_scalable_from_big_scalable_2:'232; CHECK: SelectionDAG has 11 nodes:233; CHECK: t0: ch,glue = EntryToken234; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0235; CHECK: t4: nxv4i8 = extract_subvector t2, Constant:i64<0>236; CHECK: t6: nxv8i8 = insert_subvector poison:nxv8i8, t4, Constant:i64<0>237; CHECK: t7: nxv8i16 = any_extend t6238; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7239; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1240 241; CHECK: Optimized lowered selection DAG: %bb.0 'extract_small_scalable_from_big_scalable_2:'242; CHECK: SelectionDAG has 9 nodes:243; CHECK: t0: ch,glue = EntryToken244; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0245; CHECK: t11: nxv8i8 = extract_subvector t2, Constant:i64<0>246; CHECK: t7: nxv8i16 = any_extend t11247; CHECK: t9: ch,glue = CopyToReg t0, Register:nxv8i16 $z0, t7248; CHECK: t10: ch = AArch64ISD::RET_GLUE t9, Register:nxv8i16 $z0, t9:1249 250define <vscale x 8 x i8> @extract_small_scalable_from_big_scalable_2(<vscale x 16 x i8> %a) #0 {251 %extract = call <vscale x 4 x i8> @llvm.vector.extract(<vscale x 16 x i8> %a, i64 0)252 %insert = call <vscale x 8 x i8> @llvm.vector.insert(<vscale x 8 x i8> poison, <vscale x 4 x i8> %extract, i64 0)253 ret <vscale x 8 x i8> %insert254}255 256; CHECK: Initial selection DAG: %bb.0 'extract_fixed_from_scalable:'257; CHECK: SelectionDAG has 10 nodes:258; CHECK: t0: ch,glue = EntryToken259; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0260; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>261; CHECK: t6: v16i8 = insert_subvector poison:v16i8, t4, Constant:i64<0>262; CHECK: t8: ch,glue = CopyToReg t0, Register:v16i8 $q0, t6263; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v16i8 $q0, t8:1264 265; CHECK: Optimized lowered selection DAG: %bb.0 'extract_fixed_from_scalable:'266; CHECK: SelectionDAG has 8 nodes:267; CHECK: t0: ch,glue = EntryToken268; CHECK: t2: nxv16i8,ch = CopyFromReg t0, Register:nxv16i8 %0269; CHECK: t10: v16i8 = extract_subvector t2, Constant:i64<0>270; CHECK: t8: ch,glue = CopyToReg t0, Register:v16i8 $q0, t10271; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:v16i8 $q0, t8:1272 273; A variant of insert_small_scalable_into_big_fixed whose vector types prevent274; the expected transformation because the resulting insert would not be legal.275; In this instance their matching minimum vector lengths allow us to perform the276; opposite transformation and emit an extract instead.277define <16 x i8> @extract_fixed_from_scalable(<vscale x 16 x i8> %a) #0 {278 %extract = call <4 x i8> @llvm.vector.extract(<vscale x 16 x i8> %a, i64 0)279 %insert = call <16 x i8> @llvm.vector.insert(<16 x i8> poison, <4 x i8> %extract, i64 0)280 ret <16 x i8> %insert281}282 283; CHECK: Initial selection DAG: %bb.0 'insert_fixed_into_scalable:'284; CHECK: SelectionDAG has 10 nodes:285; CHECK: t0: ch,glue = EntryToken286; CHECK: t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0287; CHECK: t4: v4i8 = extract_subvector t2, Constant:i64<0>288; CHECK: t6: nxv16i8 = insert_subvector poison:nxv16i8, t4, Constant:i64<0>289; CHECK: t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t6290; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:1291 292; CHECK: Optimized lowered selection DAG: %bb.0 'insert_fixed_into_scalable:'293; CHECK: SelectionDAG has 9 nodes:294; CHECK: t0: ch,glue = EntryToken295; CHECK: t2: v16i8,ch = CopyFromReg t0, Register:v16i8 %0296; CHECK: t10: nxv16i8 = insert_subvector poison:nxv16i8, t2, Constant:i64<0>297; CHECK: t8: ch,glue = CopyToReg t0, Register:nxv16i8 $z0, t10298; CHECK: t9: ch = AArch64ISD::RET_GLUE t8, Register:nxv16i8 $z0, t8:1299 300; A variant of extract_small_scalable_from_big_fixed whose vector types prevent301; the expected transformation because the resulting extract would not be legal.302; In this instance their matching minimum vector lengths allow us to perform the303; opposite transformation and emit an insert instead.304define <vscale x 16 x i8> @insert_fixed_into_scalable(<16 x i8> %a) #0 {305 %extract = call <4 x i8> @llvm.vector.extract(<16 x i8> %a, i64 0)306 %insert = call <vscale x 16 x i8> @llvm.vector.insert(<vscale x 16 x i8> poison, <4 x i8> %extract, i64 0)307 ret <vscale x 16 x i8> %insert308}309 310attributes #0 = { "target-features"="+sve" }311