Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / broadcast.ll
blobffc5508092b4c8a7cc31b38661d534b8a20fb627
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) {
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]]
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
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
27   ret <4 x float> %t6
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
40   ret <4 x float> %t6
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
55   ret <4 x float> %t7
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
72   ret <4 x float> %res
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
88   ret <4 x float> %t6
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
103   ret <4 x float> %t6
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
118   ret <4 x float> %t6
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
127   ret <1 x float> %t
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
147   ret <4 x float> %t7
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
162   ret <4 x float> %t6
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
181   ret <4 x float> %res