1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4define <4 x float> @good1(float %arg) { 5; CHECK-LABEL: @good1( 6; CHECK-NEXT: [[T:%.*]] = insertelement <4 x float> poison, float [[ARG:%.*]], i64 0 7; CHECK-NEXT: [[T6:%.*]] = shufflevector <4 x float> [[T]], <4 x float> poison, <4 x i32> zeroinitializer 8; CHECK-NEXT: ret <4 x float> [[T6]] 9; 10 %t = insertelement <4 x float> undef, float %arg, i32 0 11 %t4 = insertelement <4 x float> %t, float %arg, i32 1 12 %t5 = insertelement <4 x float> %t4, float %arg, i32 2 13 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 14 ret <4 x float> %t6 15} 16 17define <4 x float> @good2(float %arg) { 18; CHECK-LABEL: @good2( 19; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x float> poison, float [[ARG:%.*]], i64 0 20; CHECK-NEXT: [[T6:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> zeroinitializer 21; CHECK-NEXT: ret <4 x float> [[T6]] 22; 23 %t = insertelement <4 x float> undef, float %arg, i32 1 24 %t4 = insertelement <4 x float> %t, float %arg, i32 2 25 %t5 = insertelement <4 x float> %t4, float %arg, i32 0 26 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 27 ret <4 x float> %t6 28} 29 30define <4 x float> @good3(float %arg) { 31; CHECK-LABEL: @good3( 32; CHECK-NEXT: [[T:%.*]] = insertelement <4 x float> poison, float [[ARG:%.*]], i64 0 33; CHECK-NEXT: [[T6:%.*]] = shufflevector <4 x float> [[T]], <4 x float> poison, <4 x i32> zeroinitializer 34; CHECK-NEXT: ret <4 x float> [[T6]] 35; 36 %t = insertelement <4 x float> zeroinitializer, float %arg, i32 0 37 %t4 = insertelement <4 x float> %t, float %arg, i32 1 38 %t5 = insertelement <4 x float> %t4, float %arg, i32 2 39 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 40 ret <4 x float> %t6 41} 42 43define <4 x float> @good4(float %arg) { 44; CHECK-LABEL: @good4( 45; CHECK-NEXT: [[T:%.*]] = insertelement <4 x float> poison, float [[ARG:%.*]], i64 0 46; CHECK-NEXT: [[TMP1:%.*]] = fadd <4 x float> [[T]], [[T]] 47; CHECK-NEXT: [[T7:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> zeroinitializer 48; CHECK-NEXT: ret <4 x float> [[T7]] 49; 50 %t = insertelement <4 x float> zeroinitializer, float %arg, i32 0 51 %t4 = insertelement <4 x float> %t, float %arg, i32 1 52 %t5 = insertelement <4 x float> %t4, float %arg, i32 2 53 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 54 %t7 = fadd <4 x float> %t6, %t6 55 ret <4 x float> %t7 56} 57 58define <4 x float> @good5(float %v) { 59; CHECK-LABEL: @good5( 60; CHECK-NEXT: [[INS1:%.*]] = insertelement <4 x float> <float poison, float undef, float undef, float undef>, float [[V:%.*]], i64 0 61; CHECK-NEXT: [[A1:%.*]] = fadd <4 x float> [[INS1]], [[INS1]] 62; CHECK-NEXT: [[INS4:%.*]] = shufflevector <4 x float> [[INS1]], <4 x float> poison, <4 x i32> zeroinitializer 63; CHECK-NEXT: [[RES:%.*]] = fadd <4 x float> [[A1]], [[INS4]] 64; CHECK-NEXT: ret <4 x float> [[RES]] 65; 66 %ins1 = insertelement <4 x float> undef, float %v, i32 0 67 %a1 = fadd <4 x float> %ins1, %ins1 68 %ins2 = insertelement<4 x float> %ins1, float %v, i32 1 69 %ins3 = insertelement<4 x float> %ins2, float %v, i32 2 70 %ins4 = insertelement<4 x float> %ins3, float %v, i32 3 71 %res = fadd <4 x float> %a1, %ins4 72 ret <4 x float> %res 73} 74 75; The insert is changed to allow the canonical shuffle-splat pattern from element 0. 76 77define <4 x float> @splat_undef1(float %arg) { 78; CHECK-LABEL: @splat_undef1( 79; CHECK-NEXT: [[T4:%.*]] = insertelement <4 x float> <float undef, float poison, float poison, float poison>, float [[ARG:%.*]], i64 1 80; CHECK-NEXT: [[T5:%.*]] = insertelement <4 x float> [[T4]], float [[ARG]], i64 2 81; CHECK-NEXT: [[T6:%.*]] = insertelement <4 x float> [[T5]], float [[ARG]], i64 3 82; CHECK-NEXT: ret <4 x float> [[T6]] 83; 84 %t = insertelement <4 x float> undef, float %arg, i32 1 85 %t4 = insertelement <4 x float> %t, float %arg, i32 1 86 %t5 = insertelement <4 x float> %t4, float %arg, i32 2 87 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 88 ret <4 x float> %t6 89} 90 91; Re-uses the existing first insertelement. 92 93define <4 x float> @splat_undef2(float %arg) { 94; CHECK-LABEL: @splat_undef2( 95; CHECK-NEXT: [[T:%.*]] = insertelement <4 x float> <float poison, float undef, float poison, float poison>, float [[ARG:%.*]], i64 0 96; CHECK-NEXT: [[T5:%.*]] = insertelement <4 x float> [[T]], float [[ARG]], i64 2 97; CHECK-NEXT: [[T6:%.*]] = insertelement <4 x float> [[T5]], float [[ARG]], i64 3 98; CHECK-NEXT: ret <4 x float> [[T6]] 99; 100 %t = insertelement <4 x float> undef, float %arg, i32 0 101 %t5 = insertelement <4 x float> %t, float %arg, i32 2 102 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 103 ret <4 x float> %t6 104} 105 106define <4 x float> @bad3(float %arg, float %arg2) { 107; CHECK-LABEL: @bad3( 108; CHECK-NEXT: [[T:%.*]] = insertelement <4 x float> poison, float [[ARG:%.*]], i64 0 109; CHECK-NEXT: [[T4:%.*]] = insertelement <4 x float> [[T]], float [[ARG2:%.*]], i64 1 110; CHECK-NEXT: [[T5:%.*]] = insertelement <4 x float> [[T4]], float [[ARG]], i64 2 111; CHECK-NEXT: [[T6:%.*]] = insertelement <4 x float> [[T5]], float [[ARG]], i64 3 112; CHECK-NEXT: ret <4 x float> [[T6]] 113; 114 %t = insertelement <4 x float> undef, float %arg, i32 0 115 %t4 = insertelement <4 x float> %t, float %arg2, i32 1 116 %t5 = insertelement <4 x float> %t4, float %arg, i32 2 117 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 118 ret <4 x float> %t6 119} 120 121define <1 x float> @bad4(float %arg) { 122; CHECK-LABEL: @bad4( 123; CHECK-NEXT: [[T:%.*]] = insertelement <1 x float> poison, float [[ARG:%.*]], i64 0 124; CHECK-NEXT: ret <1 x float> [[T]] 125; 126 %t = insertelement <1 x float> undef, float %arg, i32 0 127 ret <1 x float> %t 128} 129 130; Multiple undef elements are ok. 131; TODO: Multiple uses triggers the transform at %t4, but we should sink/scalarize/CSE the splats? 132 133define <4 x float> @splat_undef3(float %arg) { 134; CHECK-LABEL: @splat_undef3( 135; CHECK-NEXT: [[T:%.*]] = insertelement <4 x float> <float poison, float poison, float undef, float undef>, float [[ARG:%.*]], i64 0 136; CHECK-NEXT: [[T4:%.*]] = insertelement <4 x float> [[T]], float [[ARG]], i64 1 137; CHECK-NEXT: [[T5:%.*]] = insertelement <4 x float> [[T4]], float [[ARG]], i64 2 138; CHECK-NEXT: [[T6:%.*]] = insertelement <4 x float> [[T5]], float [[ARG]], i64 3 139; CHECK-NEXT: [[T7:%.*]] = fadd <4 x float> [[T6]], [[T4]] 140; CHECK-NEXT: ret <4 x float> [[T7]] 141; 142 %t = insertelement <4 x float> undef, float %arg, i32 0 143 %t4 = insertelement <4 x float> %t, float %arg, i32 1 144 %t5 = insertelement <4 x float> %t4, float %arg, i32 2 145 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 146 %t7 = fadd <4 x float> %t6, %t4 147 ret <4 x float> %t7 148} 149 150define <4 x float> @bad6(float %arg, i32 %k) { 151; CHECK-LABEL: @bad6( 152; CHECK-NEXT: [[T:%.*]] = insertelement <4 x float> <float poison, float poison, float undef, float poison>, float [[ARG:%.*]], i64 0 153; CHECK-NEXT: [[T4:%.*]] = insertelement <4 x float> [[T]], float [[ARG]], i64 1 154; CHECK-NEXT: [[T5:%.*]] = insertelement <4 x float> [[T4]], float [[ARG]], i32 [[K:%.*]] 155; CHECK-NEXT: [[T6:%.*]] = insertelement <4 x float> [[T5]], float [[ARG]], i64 3 156; CHECK-NEXT: ret <4 x float> [[T6]] 157; 158 %t = insertelement <4 x float> undef, float %arg, i32 0 159 %t4 = insertelement <4 x float> %t, float %arg, i32 1 160 %t5 = insertelement <4 x float> %t4, float %arg, i32 %k 161 %t6 = insertelement <4 x float> %t5, float %arg, i32 3 162 ret <4 x float> %t6 163} 164 165define <4 x float> @bad7(float %v) { 166; CHECK-LABEL: @bad7( 167; CHECK-NEXT: [[INS1:%.*]] = insertelement <4 x float> <float undef, float poison, float undef, float undef>, float [[V:%.*]], i64 1 168; CHECK-NEXT: [[A1:%.*]] = fadd <4 x float> [[INS1]], [[INS1]] 169; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x float> [[INS1]], float [[V]], i64 0 170; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x float> [[TMP1]], float [[V]], i64 2 171; CHECK-NEXT: [[INS4:%.*]] = insertelement <4 x float> [[TMP2]], float [[V]], i64 3 172; CHECK-NEXT: [[RES:%.*]] = fadd <4 x float> [[A1]], [[INS4]] 173; CHECK-NEXT: ret <4 x float> [[RES]] 174; 175 %ins1 = insertelement <4 x float> undef, float %v, i32 1 176 %a1 = fadd <4 x float> %ins1, %ins1 177 %ins2 = insertelement<4 x float> %ins1, float %v, i32 2 178 %ins3 = insertelement<4 x float> %ins2, float %v, i32 3 179 %ins4 = insertelement<4 x float> %ins3, float %v, i32 0 180 %res = fadd <4 x float> %a1, %ins4 181 ret <4 x float> %res 182} 183