xref: /aosp_15_r20/external/llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -instcombine %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerdefine <1 x i8> @test1(<8 x i8> %in) {
4*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1
5*9880d681SAndroid Build Coastguard Worker; CHECK: shufflevector <8 x i8> %in, <8 x i8> undef, <1 x i32> <i32 5>
6*9880d681SAndroid Build Coastguard Worker  %val = extractelement <8 x i8> %in, i32 5
7*9880d681SAndroid Build Coastguard Worker  %vec = insertelement <1 x i8> undef, i8 %val, i32 0
8*9880d681SAndroid Build Coastguard Worker  ret <1 x i8> %vec
9*9880d681SAndroid Build Coastguard Worker}
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @test2(<8 x i16> %in, <8 x i16> %in2) {
12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2
13*9880d681SAndroid Build Coastguard Worker; CHECK: shufflevector <8 x i16> %in2, <8 x i16> %in, <4 x i32> <i32 11, i32 9, i32 0, i32 10>
14*9880d681SAndroid Build Coastguard Worker  %elt0 = extractelement <8 x i16> %in, i32 3
15*9880d681SAndroid Build Coastguard Worker  %elt1 = extractelement <8 x i16> %in, i32 1
16*9880d681SAndroid Build Coastguard Worker  %elt2 = extractelement <8 x i16> %in2, i32 0
17*9880d681SAndroid Build Coastguard Worker  %elt3 = extractelement <8 x i16> %in, i32 2
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker  %vec.0 = insertelement <4 x i16> undef, i16 %elt0, i32 0
20*9880d681SAndroid Build Coastguard Worker  %vec.1 = insertelement <4 x i16> %vec.0, i16 %elt1, i32 1
21*9880d681SAndroid Build Coastguard Worker  %vec.2 = insertelement <4 x i16> %vec.1, i16 %elt2, i32 2
22*9880d681SAndroid Build Coastguard Worker  %vec.3 = insertelement <4 x i16> %vec.2, i16 %elt3, i32 3
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker  ret <4 x i16> %vec.3
25*9880d681SAndroid Build Coastguard Worker}
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test_vcopyq_lane_p64(<2 x i64> %a, <1 x i64> %b) {
28*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_vcopyq_lane_p64
29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <1 x i64> %b, <1 x i64> undef, <2 x i32> <i32 0, i32 undef>
30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: shufflevector <2 x i64> %a, <2 x i64> %[[WIDEVEC]], <2 x i32> <i32 0, i32 2>
31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <2 x i64> %res
32*9880d681SAndroid Build Coastguard Worker  %elt = extractelement <1 x i64> %b, i32 0
33*9880d681SAndroid Build Coastguard Worker  %res = insertelement <2 x i64> %a, i64 %elt, i32 1
34*9880d681SAndroid Build Coastguard Worker  ret <2 x i64> %res
35*9880d681SAndroid Build Coastguard Worker}
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker; PR2109: https://llvm.org/bugs/show_bug.cgi?id=2109
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @widen_extract2(<4 x float> %ins, <2 x float> %ext) {
40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @widen_extract2(
41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <2 x float> %ext, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: shufflevector <4 x float> %ins, <4 x float> %[[WIDEVEC]], <4 x i32> <i32 0, i32 4, i32 2, i32 5>
43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <4 x float> %i2
44*9880d681SAndroid Build Coastguard Worker  %e1 = extractelement <2 x float> %ext, i32 0
45*9880d681SAndroid Build Coastguard Worker  %e2 = extractelement <2 x float> %ext, i32 1
46*9880d681SAndroid Build Coastguard Worker  %i1 = insertelement <4 x float> %ins, float %e1, i32 1
47*9880d681SAndroid Build Coastguard Worker  %i2 = insertelement <4 x float> %i1, float %e2, i32 3
48*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %i2
49*9880d681SAndroid Build Coastguard Worker}
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @widen_extract3(<4 x float> %ins, <3 x float> %ext) {
52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @widen_extract3(
53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <3 x float> %ext, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: shufflevector <4 x float> %ins, <4 x float> %[[WIDEVEC]], <4 x i32> <i32 6, i32 5, i32 4, i32 3>
55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <4 x float> %i3
56*9880d681SAndroid Build Coastguard Worker  %e1 = extractelement <3 x float> %ext, i32 0
57*9880d681SAndroid Build Coastguard Worker  %e2 = extractelement <3 x float> %ext, i32 1
58*9880d681SAndroid Build Coastguard Worker  %e3 = extractelement <3 x float> %ext, i32 2
59*9880d681SAndroid Build Coastguard Worker  %i1 = insertelement <4 x float> %ins, float %e1, i32 2
60*9880d681SAndroid Build Coastguard Worker  %i2 = insertelement <4 x float> %i1, float %e2, i32 1
61*9880d681SAndroid Build Coastguard Worker  %i3 = insertelement <4 x float> %i2, float %e3, i32 0
62*9880d681SAndroid Build Coastguard Worker  ret <4 x float> %i3
63*9880d681SAndroid Build Coastguard Worker}
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Workerdefine <8 x float> @widen_extract4(<8 x float> %ins, <2 x float> %ext) {
66*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @widen_extract4(
67*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <2 x float> %ext, <2 x float> undef, <8 x i32> <i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: shufflevector <8 x float> %ins, <8 x float> %[[WIDEVEC]], <8 x i32> <i32 0, i32 1, i32 8, i32 3, i32 4, i32 5, i32 6, i32 7>
69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret <8 x float> %i1
70*9880d681SAndroid Build Coastguard Worker  %e1 = extractelement <2 x float> %ext, i32 0
71*9880d681SAndroid Build Coastguard Worker  %i1 = insertelement <8 x float> %ins, float %e1, i32 2
72*9880d681SAndroid Build Coastguard Worker  ret <8 x float> %i1
73*9880d681SAndroid Build Coastguard Worker}
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker; PR26015: https://llvm.org/bugs/show_bug.cgi?id=26015
76*9880d681SAndroid Build Coastguard Worker; The widening shuffle must be inserted before any uses.
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @pr26015(<4 x i16> %t0) {
79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr26015(
80*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <4 x i16> %t0, <4 x i16> undef, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %[[EXT:.*]] = extractelement <4 x i16> %t0, i32 2
82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t2 = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 undef, i16 0, i16 0, i16 undef, i16 undef>, i16 %[[EXT]], i32 3
83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t5 = shufflevector <8 x i16> %t3, <8 x i16> %[[WIDEVEC]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>
85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  ret <8 x i16> %t5
86*9880d681SAndroid Build Coastguard Worker  %t1 = extractelement <4 x i16> %t0, i32 2
87*9880d681SAndroid Build Coastguard Worker  %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
88*9880d681SAndroid Build Coastguard Worker  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
89*9880d681SAndroid Build Coastguard Worker  %t4 = extractelement <4 x i16> %t0, i32 3
90*9880d681SAndroid Build Coastguard Worker  %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
91*9880d681SAndroid Build Coastguard Worker  ret <8 x i16> %t5
92*9880d681SAndroid Build Coastguard Worker}
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker; PR25999: https://llvm.org/bugs/show_bug.cgi?id=25999
95*9880d681SAndroid Build Coastguard Worker; TODO: The widening shuffle could be inserted at the start of the function to allow the first extract to use it.
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @pr25999(<4 x i16> %t0, i1 %b) {
98*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr25999(
99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t1 = extractelement <4 x i16> %t0, i32 2
100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  br i1 %b, label %if, label %end
101*9880d681SAndroid Build Coastguard Worker; CHECK:       if:
102*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <4 x i16> %t0, <4 x i16> undef, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
103*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t2 = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 undef, i16 0, i16 0, i16 undef, i16 undef>, i16 %t1, i32 3
104*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
105*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t5 = shufflevector <8 x i16> %t3, <8 x i16> %[[WIDEVEC]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 11>
106*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  ret <8 x i16> %t5
107*9880d681SAndroid Build Coastguard Worker; CHECK:       end:
108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %a1 = add i16 %t1, 4
109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %t6 = insertelement <8 x i16> <i16 undef, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, i16 %a1, i32 0
110*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  ret <8 x i16> %t6
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker  %t1 = extractelement <4 x i16> %t0, i32 2
113*9880d681SAndroid Build Coastguard Worker  br i1 %b, label %if, label %end
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Workerif:
116*9880d681SAndroid Build Coastguard Worker  %t2 = insertelement <8 x i16> zeroinitializer, i16 %t1, i32 3
117*9880d681SAndroid Build Coastguard Worker  %t3 = insertelement <8 x i16> %t2, i16 0, i32 6
118*9880d681SAndroid Build Coastguard Worker  %t4 = extractelement <4 x i16> %t0, i32 3
119*9880d681SAndroid Build Coastguard Worker  %t5 = insertelement <8 x i16> %t3, i16 %t4, i32 7
120*9880d681SAndroid Build Coastguard Worker  ret <8 x i16> %t5
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Workerend:
123*9880d681SAndroid Build Coastguard Worker  %a1 = add i16 %t1, 4
124*9880d681SAndroid Build Coastguard Worker  %t6 = insertelement <8 x i16> zeroinitializer, i16 %a1, i32 0
125*9880d681SAndroid Build Coastguard Worker  ret <8 x i16> %t6
126*9880d681SAndroid Build Coastguard Worker}
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker; The widening shuffle must be inserted at a valid point (after the PHIs).
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Workerdefine <4 x double> @pr25999_phis1(i1 %c, <2 x double> %a, <4 x double> %b) {
131*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr25999_phis1(
132*9880d681SAndroid Build Coastguard Worker; CHECK:       %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
133*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
134*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <2 x double> %tmp1, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
135*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %tmp4 = shufflevector <4 x double> %tmp2, <4 x double> %[[WIDEVEC]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
136*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  ret <4 x double> %tmp4
137*9880d681SAndroid Build Coastguard Workerbb1:
138*9880d681SAndroid Build Coastguard Worker  br i1 %c, label %bb2, label %bb3
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Workerbb2:
141*9880d681SAndroid Build Coastguard Worker  %r = call <2 x double> @dummy(<2 x double> %a)
142*9880d681SAndroid Build Coastguard Worker  br label %bb3
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Workerbb3:
145*9880d681SAndroid Build Coastguard Worker  %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
146*9880d681SAndroid Build Coastguard Worker  %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
147*9880d681SAndroid Build Coastguard Worker  %tmp3 = extractelement <2 x double> %tmp1, i32 0
148*9880d681SAndroid Build Coastguard Worker  %tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
149*9880d681SAndroid Build Coastguard Worker  ret <4 x double> %tmp4
150*9880d681SAndroid Build Coastguard Worker}
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Workerdeclare <2 x double> @dummy(<2 x double>)
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Workerdefine <4 x double> @pr25999_phis2(i1 %c, <2 x double> %a, <4 x double> %b) {
155*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr25999_phis2(
156*9880d681SAndroid Build Coastguard Worker; CHECK:       %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
158*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %d = fadd <2 x double> %tmp1, %tmp1
159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %[[WIDEVEC:.*]] = shufflevector <2 x double> %d, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %tmp4 = shufflevector <4 x double> %tmp2, <4 x double> %[[WIDEVEC]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
161*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  ret <4 x double> %tmp4
162*9880d681SAndroid Build Coastguard Workerbb1:
163*9880d681SAndroid Build Coastguard Worker  br i1 %c, label %bb2, label %bb3
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Workerbb2:
166*9880d681SAndroid Build Coastguard Worker  %r = call <2 x double> @dummy(<2 x double> %a)
167*9880d681SAndroid Build Coastguard Worker  br label %bb3
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerbb3:
170*9880d681SAndroid Build Coastguard Worker  %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
171*9880d681SAndroid Build Coastguard Worker  %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
172*9880d681SAndroid Build Coastguard Worker  %d = fadd <2 x double> %tmp1, %tmp1
173*9880d681SAndroid Build Coastguard Worker  %tmp3 = extractelement <2 x double> %d, i32 0
174*9880d681SAndroid Build Coastguard Worker  %tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
175*9880d681SAndroid Build Coastguard Worker  ret <4 x double> %tmp4
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker; PR26354: https://llvm.org/bugs/show_bug.cgi?id=26354
179*9880d681SAndroid Build Coastguard Worker; Don't create a shufflevector if we know that we're not going to replace the insertelement.
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Workerdefine double @pr26354(<2 x double>* %tmp, i1 %B) {
182*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @pr26354(
183*9880d681SAndroid Build Coastguard Worker; CHECK:       %ld = load <2 x double>, <2 x double>* %tmp
184*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %e1 = extractelement <2 x double> %ld, i32 0
185*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  br i1 %B, label %if, label %end
186*9880d681SAndroid Build Coastguard Worker; CHECK:       if:
187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %e2 = extractelement <2 x double> %ld, i32 1
188*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %i1 = insertelement <4 x double>
189*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  br label %end
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Workerentry:
192*9880d681SAndroid Build Coastguard Worker  %ld = load <2 x double>, <2 x double>* %tmp
193*9880d681SAndroid Build Coastguard Worker  %e1 = extractelement <2 x double> %ld, i32 0
194*9880d681SAndroid Build Coastguard Worker  %e2 = extractelement <2 x double> %ld, i32 1
195*9880d681SAndroid Build Coastguard Worker  br i1 %B, label %if, label %end
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Workerif:
198*9880d681SAndroid Build Coastguard Worker  %i1 = insertelement <4 x double> zeroinitializer, double %e2, i32 3
199*9880d681SAndroid Build Coastguard Worker  br label %end
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Workerend:
202*9880d681SAndroid Build Coastguard Worker  %ph = phi <4 x double> [ undef, %entry ], [ %i1, %if ]
203*9880d681SAndroid Build Coastguard Worker  %e3 = extractelement <4 x double> %ph, i32 1
204*9880d681SAndroid Build Coastguard Worker  %mu = fmul double %e1, %e3
205*9880d681SAndroid Build Coastguard Worker  ret double %mu
206*9880d681SAndroid Build Coastguard Worker}
207*9880d681SAndroid Build Coastguard Worker
208