125 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; llvm.vector.insert canonicalizes to shufflevector in the fixed case. In the5; scalable case, we lower to the INSERT_SUBVECTOR ISD node.6 7declare <8 x i32> @llvm.vector.insert.v8i32.v2i32(<8 x i32> %vec, <2 x i32> %subvec, i64 %idx)8declare <8 x i32> @llvm.vector.insert.v8i32.v3i32(<8 x i32> %vec, <3 x i32> %subvec, i64 %idx)9declare <8 x i32> @llvm.vector.insert.v8i32.v4i32(<8 x i32> %vec, <4 x i32> %subvec, i64 %idx)10declare <8 x i32> @llvm.vector.insert.v8i32.v8i32(<8 x i32> %vec, <8 x i32> %subvec, i64 %idx)11declare <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32> %vec, <4 x i32> %subvec, i64 %idx)12 13; ============================================================================ ;14; Trivial cases15; ============================================================================ ;16 17; An insert that entirely overwrites an <n x ty> with another <n x ty> is a18; nop.19define <8 x i32> @trivial_nop(<8 x i32> %vec, <8 x i32> %subvec) {20; CHECK-LABEL: @trivial_nop(21; CHECK-NEXT: ret <8 x i32> [[SUBVEC:%.*]]22;23 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v8i32(<8 x i32> %vec, <8 x i32> %subvec, i64 0)24 ret <8 x i32> %125}26 27; ============================================================================ ;28; Valid canonicalizations29; ============================================================================ ;30 31define <8 x i32> @valid_insertion_a(<8 x i32> %vec, <2 x i32> %subvec) {32; CHECK-LABEL: @valid_insertion_a(33; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[SUBVEC:%.*]], <2 x i32> poison, <8 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>34; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> [[VEC:%.*]], <8 x i32> <i32 0, i32 1, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>35; CHECK-NEXT: ret <8 x i32> [[TMP2]]36;37 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v2i32(<8 x i32> %vec, <2 x i32> %subvec, i64 0)38 ret <8 x i32> %139}40 41define <8 x i32> @valid_insertion_b(<8 x i32> %vec, <2 x i32> %subvec) {42; CHECK-LABEL: @valid_insertion_b(43; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[SUBVEC:%.*]], <2 x i32> poison, <8 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>44; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[VEC:%.*]], <8 x i32> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 8, i32 9, i32 4, i32 5, i32 6, i32 7>45; CHECK-NEXT: ret <8 x i32> [[TMP2]]46;47 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v2i32(<8 x i32> %vec, <2 x i32> %subvec, i64 2)48 ret <8 x i32> %149}50 51define <8 x i32> @valid_insertion_c(<8 x i32> %vec, <2 x i32> %subvec) {52; CHECK-LABEL: @valid_insertion_c(53; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[SUBVEC:%.*]], <2 x i32> poison, <8 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>54; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[VEC:%.*]], <8 x i32> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 6, i32 7>55; CHECK-NEXT: ret <8 x i32> [[TMP2]]56;57 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v2i32(<8 x i32> %vec, <2 x i32> %subvec, i64 4)58 ret <8 x i32> %159}60 61define <8 x i32> @valid_insertion_d(<8 x i32> %vec, <2 x i32> %subvec) {62; CHECK-LABEL: @valid_insertion_d(63; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[SUBVEC:%.*]], <2 x i32> poison, <8 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>64; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[VEC:%.*]], <8 x i32> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 8, i32 9>65; CHECK-NEXT: ret <8 x i32> [[TMP2]]66;67 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v2i32(<8 x i32> %vec, <2 x i32> %subvec, i64 6)68 ret <8 x i32> %169}70 71define <8 x i32> @valid_insertion_e(<8 x i32> %vec, <4 x i32> %subvec) {72; CHECK-LABEL: @valid_insertion_e(73; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[SUBVEC:%.*]], <4 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>74; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> [[VEC:%.*]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>75; CHECK-NEXT: ret <8 x i32> [[TMP2]]76;77 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v4i32(<8 x i32> %vec, <4 x i32> %subvec, i64 0)78 ret <8 x i32> %179}80 81define <8 x i32> @valid_insertion_f(<8 x i32> %vec, <4 x i32> %subvec) {82; CHECK-LABEL: @valid_insertion_f(83; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[SUBVEC:%.*]], <4 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>84; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[VEC:%.*]], <8 x i32> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>85; CHECK-NEXT: ret <8 x i32> [[TMP2]]86;87 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v4i32(<8 x i32> %vec, <4 x i32> %subvec, i64 4)88 ret <8 x i32> %189}90 91define <8 x i32> @valid_insertion_g(<8 x i32> %vec, <3 x i32> %subvec) {92; CHECK-LABEL: @valid_insertion_g(93; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <3 x i32> [[SUBVEC:%.*]], <3 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>94; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[TMP1]], <8 x i32> [[VEC:%.*]], <8 x i32> <i32 0, i32 1, i32 2, i32 11, i32 12, i32 13, i32 14, i32 15>95; CHECK-NEXT: ret <8 x i32> [[TMP2]]96;97 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v3i32(<8 x i32> %vec, <3 x i32> %subvec, i64 0)98 ret <8 x i32> %199}100 101define <8 x i32> @valid_insertion_h(<8 x i32> %vec, <3 x i32> %subvec) {102; CHECK-LABEL: @valid_insertion_h(103; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <3 x i32> [[SUBVEC:%.*]], <3 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>104; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[VEC:%.*]], <8 x i32> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 8, i32 9, i32 10, i32 6, i32 7>105; CHECK-NEXT: ret <8 x i32> [[TMP2]]106;107 %1 = call <8 x i32> @llvm.vector.insert.v8i32.v3i32(<8 x i32> %vec, <3 x i32> %subvec, i64 3)108 ret <8 x i32> %1109}110 111; ============================================================================ ;112; Scalable cases113; ============================================================================ ;114 115; Scalable insertions should not be canonicalized. This will be lowered to the116; INSERT_SUBVECTOR ISD node later.117define <vscale x 4 x i32> @scalable_insert(<vscale x 4 x i32> %vec, <4 x i32> %subvec) {118; CHECK-LABEL: @scalable_insert(119; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32> [[VEC:%.*]], <4 x i32> [[SUBVEC:%.*]], i64 0)120; CHECK-NEXT: ret <vscale x 4 x i32> [[TMP1]]121;122 %1 = call <vscale x 4 x i32> @llvm.vector.insert.nxv4i32.v4i32(<vscale x 4 x i32> %vec, <4 x i32> %subvec, i64 0)123 ret <vscale x 4 x i32> %1124}125