@@ -36,6 +36,15 @@ struct Zoo {
36
36
Kitteh Cats[4 ];
37
37
};
38
38
39
+ struct FourFloats : TwoFloats {
40
+ float Z, W;
41
+ };
42
+
43
+ struct SlicyBits {
44
+ int Z : 8 ;
45
+ int W : 8 ;
46
+ };
47
+
39
48
// Case 1: Extraneous braces get ignored in literal instantiation.
40
49
// CHECK-LABEL: define void @_Z5case1v(
41
50
// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -712,3 +721,183 @@ Zoo case9(Doggo D1, AnimalBits A1) {
712
721
Zoo Z1 = {D1, A1, D1, A1, D1, A1};
713
722
return Z1;
714
723
}
724
+
725
+ // Case 10: Initialize an object with a base class from two objects.
726
+ // CHECK-LABEL: define void @_Z6case109TwoFloatsS_(
727
+ // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS:%.*]]) align 4 [[TF1:%.*]], ptr noundef byval([[STRUCT_TWOFLOATS]]) align 4 [[TF2:%.*]]) #[[ATTR0]] {
728
+ // CHECK-NEXT: [[ENTRY:.*:]]
729
+ // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0
730
+ // CHECK-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF1]], i32 0, i32 0
731
+ // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[X1]], align 4
732
+ // CHECK-NEXT: store float [[TMP0]], ptr [[X]], align 4
733
+ // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1
734
+ // CHECK-NEXT: [[Y2:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF1]], i32 0, i32 1
735
+ // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[Y2]], align 4
736
+ // CHECK-NEXT: store float [[TMP1]], ptr [[Y]], align 4
737
+ // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1
738
+ // CHECK-NEXT: [[X3:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF2]], i32 0, i32 0
739
+ // CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[X3]], align 4
740
+ // CHECK-NEXT: store float [[TMP2]], ptr [[Z]], align 4
741
+ // CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 2
742
+ // CHECK-NEXT: [[Y4:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[TF2]], i32 0, i32 1
743
+ // CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[Y4]], align 4
744
+ // CHECK-NEXT: store float [[TMP3]], ptr [[W]], align 4
745
+ // CHECK-NEXT: ret void
746
+ //
747
+ FourFloats case10 (TwoFloats TF1, TwoFloats TF2) {
748
+ FourFloats FF1 = {TF1, TF2};
749
+ return FF1;
750
+ }
751
+
752
+ // Case 11: Initialize an object with a base class from a vector splat.
753
+ // CHECK-LABEL: define void @_Z6case11f(
754
+ // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOURFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], float noundef nofpclass(nan inf) [[F:%.*]]) #[[ATTR0]] {
755
+ // CHECK-NEXT: [[ENTRY:.*:]]
756
+ // CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
757
+ // CHECK-NEXT: [[REF_TMP:%.*]] = alloca <4 x float>, align 16
758
+ // CHECK-NEXT: [[REF_TMP1:%.*]] = alloca <4 x float>, align 16
759
+ // CHECK-NEXT: [[REF_TMP4:%.*]] = alloca <4 x float>, align 16
760
+ // CHECK-NEXT: [[REF_TMP7:%.*]] = alloca <4 x float>, align 16
761
+ // CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
762
+ // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS:%.*]], ptr [[AGG_RESULT]], i32 0, i32 0
763
+ // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4
764
+ // CHECK-NEXT: [[CAST_SPLAT:%.*]] = insertelement <1 x float> poison, float [[TMP0]], i64 0
765
+ // CHECK-NEXT: [[TMP1:%.*]] = shufflevector <1 x float> [[CAST_SPLAT]], <1 x float> poison, <4 x i32> zeroinitializer
766
+ // CHECK-NEXT: store <4 x float> [[TMP1]], ptr [[REF_TMP]], align 16
767
+ // CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[REF_TMP]], align 16
768
+ // CHECK-NEXT: [[VECEXT:%.*]] = extractelement <4 x float> [[TMP2]], i64 0
769
+ // CHECK-NEXT: store float [[VECEXT]], ptr [[X]], align 4
770
+ // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1
771
+ // CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[F_ADDR]], align 4
772
+ // CHECK-NEXT: [[CAST_SPLAT2:%.*]] = insertelement <1 x float> poison, float [[TMP3]], i64 0
773
+ // CHECK-NEXT: [[TMP4:%.*]] = shufflevector <1 x float> [[CAST_SPLAT2]], <1 x float> poison, <4 x i32> zeroinitializer
774
+ // CHECK-NEXT: store <4 x float> [[TMP4]], ptr [[REF_TMP1]], align 16
775
+ // CHECK-NEXT: [[TMP5:%.*]] = load <4 x float>, ptr [[REF_TMP1]], align 16
776
+ // CHECK-NEXT: [[VECEXT3:%.*]] = extractelement <4 x float> [[TMP5]], i64 1
777
+ // CHECK-NEXT: store float [[VECEXT3]], ptr [[Y]], align 4
778
+ // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1
779
+ // CHECK-NEXT: [[TMP6:%.*]] = load float, ptr [[F_ADDR]], align 4
780
+ // CHECK-NEXT: [[CAST_SPLAT5:%.*]] = insertelement <1 x float> poison, float [[TMP6]], i64 0
781
+ // CHECK-NEXT: [[TMP7:%.*]] = shufflevector <1 x float> [[CAST_SPLAT5]], <1 x float> poison, <4 x i32> zeroinitializer
782
+ // CHECK-NEXT: store <4 x float> [[TMP7]], ptr [[REF_TMP4]], align 16
783
+ // CHECK-NEXT: [[TMP8:%.*]] = load <4 x float>, ptr [[REF_TMP4]], align 16
784
+ // CHECK-NEXT: [[VECEXT6:%.*]] = extractelement <4 x float> [[TMP8]], i64 2
785
+ // CHECK-NEXT: store float [[VECEXT6]], ptr [[Z]], align 4
786
+ // CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_FOURFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 2
787
+ // CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[F_ADDR]], align 4
788
+ // CHECK-NEXT: [[CAST_SPLAT8:%.*]] = insertelement <1 x float> poison, float [[TMP9]], i64 0
789
+ // CHECK-NEXT: [[TMP10:%.*]] = shufflevector <1 x float> [[CAST_SPLAT8]], <1 x float> poison, <4 x i32> zeroinitializer
790
+ // CHECK-NEXT: store <4 x float> [[TMP10]], ptr [[REF_TMP7]], align 16
791
+ // CHECK-NEXT: [[TMP11:%.*]] = load <4 x float>, ptr [[REF_TMP7]], align 16
792
+ // CHECK-NEXT: [[VECEXT9:%.*]] = extractelement <4 x float> [[TMP11]], i64 3
793
+ // CHECK-NEXT: store float [[VECEXT9]], ptr [[W]], align 4
794
+ // CHECK-NEXT: ret void
795
+ //
796
+ FourFloats case11 (float F) {
797
+ FourFloats FF1 = {F.xxxx};
798
+ return FF1;
799
+ }
800
+
801
+ // Case 12: Initialize bitfield from two integers.
802
+ // CHECK-LABEL: define void @_Z6case12ii(
803
+ // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_SLICYBITS:%.*]]) align 4 [[AGG_RESULT:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) #[[ATTR0]] {
804
+ // CHECK-NEXT: [[ENTRY:.*:]]
805
+ // CHECK-NEXT: [[I_ADDR:%.*]] = alloca i32, align 4
806
+ // CHECK-NEXT: [[J_ADDR:%.*]] = alloca i32, align 4
807
+ // CHECK-NEXT: store i32 [[I]], ptr [[I_ADDR]], align 4
808
+ // CHECK-NEXT: store i32 [[J]], ptr [[J_ADDR]], align 4
809
+ // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I_ADDR]], align 4
810
+ // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i16
811
+ // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[AGG_RESULT]], align 4
812
+ // CHECK-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255
813
+ // CHECK-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -256
814
+ // CHECK-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_VALUE]]
815
+ // CHECK-NEXT: store i16 [[BF_SET]], ptr [[AGG_RESULT]], align 4
816
+ // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[J_ADDR]], align 4
817
+ // CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i16
818
+ // CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[AGG_RESULT]], align 4
819
+ // CHECK-NEXT: [[BF_VALUE2:%.*]] = and i16 [[TMP3]], 255
820
+ // CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_VALUE2]], 8
821
+ // CHECK-NEXT: [[BF_CLEAR3:%.*]] = and i16 [[BF_LOAD1]], 255
822
+ // CHECK-NEXT: [[BF_SET4:%.*]] = or i16 [[BF_CLEAR3]], [[BF_SHL]]
823
+ // CHECK-NEXT: store i16 [[BF_SET4]], ptr [[AGG_RESULT]], align 4
824
+ // CHECK-NEXT: ret void
825
+ //
826
+ SlicyBits case12 (int I, int J) {
827
+ SlicyBits SB = {I, J};
828
+ return SB;
829
+ }
830
+
831
+ // Case 13: Initialize bitfield from a struct of two ints.
832
+ // CHECK-LABEL: define void @_Z6case137TwoInts(
833
+ // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_SLICYBITS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_TWOINTS:%.*]]) align 4 [[TI:%.*]]) #[[ATTR0]] {
834
+ // CHECK-NEXT: [[ENTRY:.*:]]
835
+ // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI]], i32 0, i32 0
836
+ // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Z]], align 4
837
+ // CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i16
838
+ // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[AGG_RESULT]], align 4
839
+ // CHECK-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255
840
+ // CHECK-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -256
841
+ // CHECK-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_VALUE]]
842
+ // CHECK-NEXT: store i16 [[BF_SET]], ptr [[AGG_RESULT]], align 4
843
+ // CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[TI]], i32 0, i32 1
844
+ // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[W]], align 4
845
+ // CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i16
846
+ // CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[AGG_RESULT]], align 4
847
+ // CHECK-NEXT: [[BF_VALUE2:%.*]] = and i16 [[TMP3]], 255
848
+ // CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_VALUE2]], 8
849
+ // CHECK-NEXT: [[BF_CLEAR3:%.*]] = and i16 [[BF_LOAD1]], 255
850
+ // CHECK-NEXT: [[BF_SET4:%.*]] = or i16 [[BF_CLEAR3]], [[BF_SHL]]
851
+ // CHECK-NEXT: store i16 [[BF_SET4]], ptr [[AGG_RESULT]], align 4
852
+ // CHECK-NEXT: ret void
853
+ //
854
+ SlicyBits case13 (TwoInts TI) {
855
+ SlicyBits SB = {TI};
856
+ return SB;
857
+ }
858
+
859
+ // Case 14: Initialize struct of ints from struct with bitfields.
860
+ // CHECK-LABEL: define void @_Z6case149SlicyBits(
861
+ // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOINTS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_SLICYBITS:%.*]]) align 4 [[SB:%.*]]) #[[ATTR0]] {
862
+ // CHECK-NEXT: [[ENTRY:.*:]]
863
+ // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 0
864
+ // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[SB]], align 4
865
+ // CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 8
866
+ // CHECK-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8
867
+ // CHECK-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32
868
+ // CHECK-NEXT: store i32 [[BF_CAST]], ptr [[Z]], align 4
869
+ // CHECK-NEXT: [[W:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOINTS]], ptr [[AGG_RESULT]], i32 0, i32 1
870
+ // CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[SB]], align 4
871
+ // CHECK-NEXT: [[BF_ASHR2:%.*]] = ashr i16 [[BF_LOAD1]], 8
872
+ // CHECK-NEXT: [[BF_CAST3:%.*]] = sext i16 [[BF_ASHR2]] to i32
873
+ // CHECK-NEXT: store i32 [[BF_CAST3]], ptr [[W]], align 4
874
+ // CHECK-NEXT: ret void
875
+ //
876
+ TwoInts case14 (SlicyBits SB) {
877
+ TwoInts TI = {SB};
878
+ return TI;
879
+ }
880
+
881
+ // Case 15: Initialize struct of floats from struct with bitfields.
882
+ // CHECK-LABEL: define void @_Z6case159SlicyBits(
883
+ // CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_TWOFLOATS:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef byval([[STRUCT_SLICYBITS:%.*]]) align 4 [[SB:%.*]]) #[[ATTR0]] {
884
+ // CHECK-NEXT: [[ENTRY:.*:]]
885
+ // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 0
886
+ // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[SB]], align 4
887
+ // CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 8
888
+ // CHECK-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8
889
+ // CHECK-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32
890
+ // CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[BF_CAST]] to float
891
+ // CHECK-NEXT: store float [[CONV]], ptr [[X]], align 4
892
+ // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_TWOFLOATS]], ptr [[AGG_RESULT]], i32 0, i32 1
893
+ // CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[SB]], align 4
894
+ // CHECK-NEXT: [[BF_ASHR2:%.*]] = ashr i16 [[BF_LOAD1]], 8
895
+ // CHECK-NEXT: [[BF_CAST3:%.*]] = sext i16 [[BF_ASHR2]] to i32
896
+ // CHECK-NEXT: [[CONV4:%.*]] = sitofp i32 [[BF_CAST3]] to float
897
+ // CHECK-NEXT: store float [[CONV4]], ptr [[Y]], align 4
898
+ // CHECK-NEXT: ret void
899
+ //
900
+ TwoFloats case15 (SlicyBits SB) {
901
+ TwoFloats TI = {SB};
902
+ return TI;
903
+ }
0 commit comments