1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 define <4 x float> @good1(float %arg) {
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]]
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
17 define <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]]
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
30 define <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]]
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
43 define <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]]
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
58 define <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]]
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
75 ; The insert is changed to allow the canonical shuffle-splat pattern from element 0.
77 define <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]]
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
91 ; Re-uses the existing first insertelement.
93 define <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]]
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
106 define <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]]
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
121 define <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]]
126 %t = insertelement <1 x float> undef, float %arg, i32 0
130 ; Multiple undef elements are ok.
131 ; TODO: Multiple uses triggers the transform at %t4, but we should sink/scalarize/CSE the splats?
133 define <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]]
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
150 define <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]]
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
165 define <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]]
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