[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / broadcast.ll
blobb8d17aaa3298953b79729db399a533e70fb6f4a1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -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> undef, float [[ARG:%.*]], i32 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:%.*]], i32 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:%.*]], i32 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:%.*]], i32 0
46 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd <4 x float> [[T]], [[T]]
47 ; CHECK-NEXT:    [[T7:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> undef, <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> undef, float [[V:%.*]], i32 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:    [[TMP1:%.*]] = insertelement <4 x float> poison, float [[ARG:%.*]], i32 0
80 ; CHECK-NEXT:    [[T6:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> poison, <4 x i32> <i32 undef, i32 0, i32 0, i32 0>
81 ; CHECK-NEXT:    ret <4 x float> [[T6]]
83   %t = insertelement <4 x float> undef, float %arg, i32 1
84   %t4 = insertelement <4 x float> %t, float %arg, i32 1
85   %t5 = insertelement <4 x float> %t4, float %arg, i32 2
86   %t6 = insertelement <4 x float> %t5, float %arg, i32 3
87   ret <4 x float> %t6
90 ; Re-uses the existing first insertelement.
92 define <4 x float> @splat_undef2(float %arg) {
93 ; CHECK-LABEL: @splat_undef2(
94 ; CHECK-NEXT:    [[T:%.*]] = insertelement <4 x float> undef, float [[ARG:%.*]], i32 0
95 ; CHECK-NEXT:    [[T6:%.*]] = shufflevector <4 x float> [[T]], <4 x float> poison, <4 x i32> <i32 0, i32 undef, i32 0, i32 0>
96 ; CHECK-NEXT:    ret <4 x float> [[T6]]
98   %t = insertelement <4 x float> undef, float %arg, i32 0
99   %t5 = insertelement <4 x float> %t, float %arg, i32 2
100   %t6 = insertelement <4 x float> %t5, float %arg, i32 3
101   ret <4 x float> %t6
104 define <4 x float> @bad3(float %arg, float %arg2) {
105 ; CHECK-LABEL: @bad3(
106 ; CHECK-NEXT:    [[T:%.*]] = insertelement <4 x float> undef, float [[ARG:%.*]], i32 0
107 ; CHECK-NEXT:    [[T4:%.*]] = insertelement <4 x float> [[T]], float [[ARG2:%.*]], i32 1
108 ; CHECK-NEXT:    [[T5:%.*]] = insertelement <4 x float> [[T4]], float [[ARG]], i32 2
109 ; CHECK-NEXT:    [[T6:%.*]] = insertelement <4 x float> [[T5]], float [[ARG]], i32 3
110 ; CHECK-NEXT:    ret <4 x float> [[T6]]
112   %t = insertelement <4 x float> undef, float %arg, i32 0
113   %t4 = insertelement <4 x float> %t, float %arg2, i32 1
114   %t5 = insertelement <4 x float> %t4, float %arg, i32 2
115   %t6 = insertelement <4 x float> %t5, float %arg, i32 3
116   ret <4 x float> %t6
119 define <1 x float> @bad4(float %arg) {
120 ; CHECK-LABEL: @bad4(
121 ; CHECK-NEXT:    [[T:%.*]] = insertelement <1 x float> undef, float [[ARG:%.*]], i32 0
122 ; CHECK-NEXT:    ret <1 x float> [[T]]
124   %t = insertelement <1 x float> undef, float %arg, i32 0
125   ret <1 x float> %t
128 ; Multiple undef elements are ok.
129 ; TODO: Multiple uses triggers the transform at %t4, but we should sink/scalarize/CSE the splats?
131 define <4 x float> @splat_undef3(float %arg) {
132 ; CHECK-LABEL: @splat_undef3(
133 ; CHECK-NEXT:    [[T:%.*]] = insertelement <4 x float> undef, float [[ARG:%.*]], i32 0
134 ; CHECK-NEXT:    [[T4:%.*]] = shufflevector <4 x float> [[T]], <4 x float> poison, <4 x i32> <i32 0, i32 0, i32 undef, i32 undef>
135 ; CHECK-NEXT:    [[T6:%.*]] = shufflevector <4 x float> [[T]], <4 x float> undef, <4 x i32> zeroinitializer
136 ; CHECK-NEXT:    [[T7:%.*]] = fadd <4 x float> [[T6]], [[T4]]
137 ; CHECK-NEXT:    ret <4 x float> [[T7]]
139   %t = insertelement <4 x float> undef, float %arg, i32 0
140   %t4 = insertelement <4 x float> %t, float %arg, i32 1
141   %t5 = insertelement <4 x float> %t4, float %arg, i32 2
142   %t6 = insertelement <4 x float> %t5, float %arg, i32 3
143   %t7 = fadd <4 x float> %t6, %t4
144   ret <4 x float> %t7
147 define <4 x float> @bad6(float %arg, i32 %k) {
148 ; CHECK-LABEL: @bad6(
149 ; CHECK-NEXT:    [[T:%.*]] = insertelement <4 x float> undef, float [[ARG:%.*]], i32 0
150 ; CHECK-NEXT:    [[T4:%.*]] = insertelement <4 x float> [[T]], float [[ARG]], i32 1
151 ; CHECK-NEXT:    [[T5:%.*]] = insertelement <4 x float> [[T4]], float [[ARG]], i32 [[K:%.*]]
152 ; CHECK-NEXT:    [[T6:%.*]] = insertelement <4 x float> [[T5]], float [[ARG]], i32 3
153 ; CHECK-NEXT:    ret <4 x float> [[T6]]
155   %t = insertelement <4 x float> undef, float %arg, i32 0
156   %t4 = insertelement <4 x float> %t, float %arg, i32 1
157   %t5 = insertelement <4 x float> %t4, float %arg, i32 %k
158   %t6 = insertelement <4 x float> %t5, float %arg, i32 3
159   ret <4 x float> %t6
162 define <4 x float> @bad7(float %v) {
163 ; CHECK-LABEL: @bad7(
164 ; CHECK-NEXT:    [[INS1:%.*]] = insertelement <4 x float> undef, float [[V:%.*]], i32 1
165 ; CHECK-NEXT:    [[A1:%.*]] = fadd <4 x float> [[INS1]], [[INS1]]
166 ; CHECK-NEXT:    [[INS2:%.*]] = insertelement <4 x float> [[INS1]], float [[V]], i32 2
167 ; CHECK-NEXT:    [[INS3:%.*]] = insertelement <4 x float> [[INS2]], float [[V]], i32 3
168 ; CHECK-NEXT:    [[INS4:%.*]] = insertelement <4 x float> [[INS3]], float [[V]], i32 0
169 ; CHECK-NEXT:    [[RES:%.*]] = fadd <4 x float> [[A1]], [[INS4]]
170 ; CHECK-NEXT:    ret <4 x float> [[RES]]
172   %ins1 = insertelement <4 x float> undef, float %v, i32 1
173   %a1 = fadd <4 x float> %ins1, %ins1
174   %ins2 = insertelement<4 x float> %ins1, float %v, i32 2
175   %ins3 = insertelement<4 x float> %ins2, float %v, i32 3
176   %ins4 = insertelement<4 x float> %ins3, float %v, i32 0
177   %res = fadd <4 x float> %a1, %ins4
178   ret <4 x float> %res