@@ -11,13 +11,23 @@ int2 ToTwoInts(int V){
1111}
1212
1313// CHECK-LABEL: ToFourFloats
14- // [[splat:%.*]] = insertelement <1 x float> poison, float {{.*}}, i64 0
15- // [[vec4:%.*]] = shufflevector <1 x float> [[splat]], <1 x float> poison, <4 x i32> zeroinitializer
14+ // CHECK: [[splat:%.*]] = insertelement <1 x float> poison, float {{.*}}, i64 0
15+ // CHECK: [[vec4:%.*]] = shufflevector <1 x float> [[splat]], <1 x float> poison, <4 x i32> zeroinitializer
1616// ret <4 x float> [[vec4]]
1717float4 ToFourFloats (float V){
1818 return V.rrrr;
1919}
2020
21+ // CHECK-LABEL: ToFourBools
22+ // CHECK: {{%.*}} = zext i1 {{.*}} to i32
23+ // CHECK: [[splat:%.*]] = insertelement <1 x i32> poison, i32 {{.*}}, i64 0
24+ // CHECK-NEXT: [[vec4:%.*]] = shufflevector <1 x i32> [[splat]], <1 x i32> poison, <4 x i32> zeroinitializer
25+ // CHECK-NEXT: [[vec2Ret:%.*]] = trunc <4 x i32> [[vec4]] to <4 x i1>
26+ // CHECK-NEXT: ret <4 x i1> [[vec2Ret]]
27+ bool4 ToFourBools (bool V) {
28+ return V.rrrr;
29+ }
30+
2131// CHECK-LABEL: FillOne
2232// CHECK: [[vec1Ptr:%.*]] = alloca <1 x i32>, align 4
2333// CHECK: store <1 x i32> splat (i32 1), ptr [[vec1Ptr]], align 4
@@ -93,6 +103,17 @@ vector<float, 1> FillOneHalfFloat(){
93103 return .5f .r;
94104}
95105
106+ // CHECK-LABEL: FillTrue
107+ // CHECK: [[Tmp:%.*]] = alloca <1 x i32>, align 1
108+ // CHECK-NEXT: store <1 x i1> splat (i1 true), ptr [[Tmp]], align 1
109+ // CHECK-NEXT: [[Vec1:%.*]] = load <1 x i32>, ptr [[Tmp]], align 1
110+ // CHECK-NEXT: [[Vec2:%.*]] = shufflevector <1 x i32> [[Vec1]], <1 x i32> poison, <2 x i32> zeroinitializer
111+ // CHECK-NEXT: [[Vec2Ret:%.*]] = trunc <2 x i32> [[Vec2]] to <2 x i1>
112+ // CHECK-NEXT: ret <2 x i1> [[Vec2Ret]]
113+ bool2 FillTrue () {
114+ return true .xx;
115+ }
116+
96117// The initial codegen for this case is correct but a bit odd. The IR optimizer
97118// cleans this up very nicely.
98119
@@ -110,6 +131,24 @@ float2 HowManyFloats(float V) {
110131 return V.rr.rr;
111132}
112133
134+ // CHECK-LABEL: HowManyBools
135+ // CHECK: [[VAddr:%.*]] = alloca i32, align 4
136+ // CHECK-NEXT: [[Vec2Ptr:%.*]] = alloca <2 x i32>, align 1
137+ // CHECK-NEXT: [[Tmp:%.*]] = zext i1 {{.*}} to i32
138+ // CHECK-NEXT: store i32 [[Tmp]], ptr [[VAddr]], align 4
139+ // CHECK-NEXT: [[VVal:%.*]] = load i32, ptr [[VAddr]], align 4
140+ // CHECK-NEXT: [[Splat:%.*]] = insertelement <1 x i32> poison, i32 [[VVal]], i64 0
141+ // CHECK-NEXT: [[Vec2:%.*]] = shufflevector <1 x i32> [[Splat]], <1 x i32> poison, <2 x i32> zeroinitializer
142+ // CHECK-NEXT: [[Trunc:%.*]] = trunc <2 x i32> [[Vec2]] to <2 x i1>
143+ // CHECK-NEXT: store <2 x i1> [[Trunc]], ptr [[Vec2Ptr]], align 1
144+ // CHECK-NEXT: [[V2:%.*]] = load <2 x i32>, ptr [[Vec2Ptr]], align 1
145+ // CHECK-NEXT: [[V3:%.*]] = shufflevector <2 x i32> [[V2]], <2 x i32> poison, <2 x i32> zeroinitializer
146+ // CHECK-NEXT: [[LV1:%.*]] = trunc <2 x i32> [[V3]] to <2 x i1>
147+ // CHECK-NEXT: ret <2 x i1> [[LV1]]
148+ bool2 HowManyBools (bool V) {
149+ return V.rr.rr;
150+ }
151+
113152// This codegen is gnarly because `1.l` is a double, so this creates double
114153// vectors that need to be truncated down to floats. The optimizer cleans this
115154// up nicely too.
@@ -166,3 +205,39 @@ int AssignInt(int V){
166205 X.x = V.x + V.x;
167206 return X;
168207}
208+
209+ // CHECK-LABEL: AssignBool
210+ // CHECK: [[VAddr:%.*]] = alloca i32, align 4
211+ // CHECK-NEXT: [[XAddr:%.*]] = alloca i32, align 4
212+ // CHECK-NEXT: [[Zext:%.*]] = zext i1 %V to i32
213+ // CHECK-NEXT: store i32 [[Zext]], ptr [[VAddr]], align 4
214+ // CHECK-NEXT: [[X:%.*]] = load i32, ptr [[VAddr]], align 4
215+ // CHECK-NEXT: [[Splat:%.*]] = insertelement <1 x i32> poison, i32 [[X]], i64 0
216+ // CHECK-NEXT: [[Y:%.*]] = extractelement <1 x i32> [[Splat]], i32 0
217+ // CHECK-NEXT: [[Z:%.*]] = trunc i32 [[Y]] to i1
218+ // CHECK-NEXT: [[A:%.*]] = zext i1 [[Z]] to i32
219+ // CHECK-NEXT: store i32 [[A]], ptr [[XAddr]], align 4
220+ // CHECK-NEXT: [[B:%.*]] = load i32, ptr [[VAddr]], align 4
221+ // CHECK-NEXT: [[Splat2:%.*]] = insertelement <1 x i32> poison, i32 [[B]], i64 0
222+ // CHECK-NEXT: [[C:%.*]] = extractelement <1 x i32> [[Splat2]], i32 0
223+ // CHECK-NEXT: [[D:%.*]] = trunc i32 [[C]] to i1
224+ // CHECK-NEXT: br i1 [[D]], label %lor.end, label %lor.rhs
225+
226+ // CHECK: lor.rhs:
227+ // CHECK-NEXT: [[E:%.*]] = load i32, ptr [[VAddr]], align 4
228+ // CHECK-NEXT: [[Splat3:%.*]] = insertelement <1 x i32> poison, i32 [[E]], i64 0
229+ // CHECK-NEXT: [[F:%.*]] = extractelement <1 x i32> [[Splat3]], i32 0
230+ // CHECK-NEXT: [[G:%.*]] = trunc i32 [[F]] to i1
231+ // CHECK-NEXT: br label %lor.end
232+
233+ // CHECK: lor.end:
234+ // CHECK-NEXT: [[H:%.*]] = phi i1 [ true, %entry ], [ [[G]], %lor.rhs ]
235+ // CHECK-NEXT: store i1 [[H]], ptr [[XAddr]], align 4
236+ // CHECK-NEXT: [[I:%.*]] = load i32, ptr [[XAddr]], align 4
237+ // CHECK-NEXT: [[LoadV:%.*]] = trunc i32 [[I]] to i1
238+ // CHECK-NEXT: ret i1 [[LoadV]]
239+ bool AssignBool (bool V) {
240+ bool X = V.x;
241+ X.x = V.x || V.x;
242+ return X;
243+ }
0 commit comments