@@ -139,7 +139,7 @@ struct Srp {
139
139
// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SRP:%.*]], align 8
140
140
// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 8
141
141
// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRP]], ptr [[S]], i32 0, i32 0
142
- // CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8
142
+ // CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]
143
143
// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4
144
144
// CHECK-A64-NEXT: ret void
145
145
//
@@ -149,7 +149,7 @@ struct Srp {
149
149
// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SRP:%.*]], align 4
150
150
// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4
151
151
// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRP]], ptr [[S]], i32 0, i32 0
152
- // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4
152
+ // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]
153
153
// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4
154
154
// CHECK-A64_32-NEXT: ret void
155
155
//
@@ -618,3 +618,180 @@ struct SpSempty {
618
618
// CHECK-A64_32-NEXT: ret void
619
619
//
620
620
void TpSempty (SpSempty s) { *s.x = 1 ; }
621
+
622
+
623
+ struct Spaddrspace {
624
+ __attribute__ ((address_space(100 ))) int *x;
625
+ };
626
+ // CHECK-A64-LABEL: define dso_local void @_Z11Tpaddrspace11Spaddrspace(
627
+ // CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {
628
+ // CHECK-A64-NEXT: [[ENTRY:.*:]]
629
+ // CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 8
630
+ // CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0
631
+ // CHECK-A64-NEXT: [[COERCE_VAL_IP:%.*]] = inttoptr i64 [[S_COERCE]] to ptr addrspace(100)
632
+ // CHECK-A64-NEXT: store ptr addrspace(100) [[COERCE_VAL_IP]], ptr [[COERCE_DIVE]], align 8
633
+ // CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0
634
+ // CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 8
635
+ // CHECK-A64-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4
636
+ // CHECK-A64-NEXT: ret void
637
+ //
638
+ // CHECK-A64_32-LABEL: define void @_Z11Tpaddrspace11Spaddrspace(
639
+ // CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {
640
+ // CHECK-A64_32-NEXT: [[ENTRY:.*:]]
641
+ // CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 4
642
+ // CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0
643
+ // CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32
644
+ // CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4
645
+ // CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0
646
+ // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 4
647
+ // CHECK-A64_32-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4
648
+ // CHECK-A64_32-NEXT: ret void
649
+ //
650
+ void Tpaddrspace (Spaddrspace s) { *s.x = 1 ; }
651
+ // CHECK-A64-LABEL: define dso_local void @_Z11Cpaddrspacev(
652
+ // CHECK-A64-SAME: ) #[[ATTR0]] {
653
+ // CHECK-A64-NEXT: [[ENTRY:.*:]]
654
+ // CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 8
655
+ // CHECK-A64-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SPADDRSPACE]], align 8
656
+ // CHECK-A64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TMP]], ptr align 8 [[S]], i64 8, i1 false)
657
+ // CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0
658
+ // CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE]], align 8
659
+ // CHECK-A64-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i64
660
+ // CHECK-A64-NEXT: call void @_Z11Tpaddrspace11Spaddrspace(i64 [[COERCE_VAL_PI]])
661
+ // CHECK-A64-NEXT: ret void
662
+ //
663
+ // CHECK-A64_32-LABEL: define void @_Z11Cpaddrspacev(
664
+ // CHECK-A64_32-SAME: ) #[[ATTR0]] {
665
+ // CHECK-A64_32-NEXT: [[ENTRY:.*:]]
666
+ // CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 4
667
+ // CHECK-A64_32-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SPADDRSPACE]], align 4
668
+ // CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TMP]], ptr align 4 [[S]], i32 4, i1 false)
669
+ // CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0
670
+ // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE]], align 4
671
+ // CHECK-A64_32-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i32
672
+ // CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = zext i32 [[COERCE_VAL_PI]] to i64
673
+ // CHECK-A64_32-NEXT: call void @_Z11Tpaddrspace11Spaddrspace(i64 [[COERCE_VAL_II]])
674
+ // CHECK-A64_32-NEXT: ret void
675
+ //
676
+ void Cpaddrspace () { Spaddrspace s; Tpaddrspace (s); }
677
+
678
+ struct Sp2addrspace {
679
+ __attribute__ ((address_space(100 ))) int *x[2 ];
680
+ };
681
+ // CHECK-A64-LABEL: define dso_local void @_Z12Tp2addrspace12Sp2addrspace(
682
+ // CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {
683
+ // CHECK-A64-NEXT: [[ENTRY:.*:]]
684
+ // CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 8
685
+ // CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0
686
+ // CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[COERCE_DIVE]], align 8
687
+ // CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0
688
+ // CHECK-A64-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr addrspace(100)], ptr [[X]], i64 0, i64 0
689
+ // CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[ARRAYIDX]], align 8
690
+ // CHECK-A64-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4
691
+ // CHECK-A64-NEXT: ret void
692
+ //
693
+ // CHECK-A64_32-LABEL: define void @_Z12Tp2addrspace12Sp2addrspace(
694
+ // CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {
695
+ // CHECK-A64_32-NEXT: [[ENTRY:.*:]]
696
+ // CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 4
697
+ // CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0
698
+ // CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[COERCE_DIVE]], align 4
699
+ // CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0
700
+ // CHECK-A64_32-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr addrspace(100)], ptr [[X]], i32 0, i32 0
701
+ // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[ARRAYIDX]], align 4
702
+ // CHECK-A64_32-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4
703
+ // CHECK-A64_32-NEXT: ret void
704
+ //
705
+ void Tp2addrspace (Sp2addrspace s) { *s.x [0 ] = 1 ; }
706
+ // CHECK-A64-LABEL: define dso_local void @_Z12Cp2addrspacev(
707
+ // CHECK-A64-SAME: ) #[[ATTR0]] {
708
+ // CHECK-A64-NEXT: [[ENTRY:.*:]]
709
+ // CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 8
710
+ // CHECK-A64-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SP2ADDRSPACE]], align 8
711
+ // CHECK-A64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TMP]], ptr align 8 [[S]], i64 16, i1 false)
712
+ // CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0
713
+ // CHECK-A64-NEXT: [[TMP0:%.*]] = load [2 x i64], ptr [[COERCE_DIVE]], align 8
714
+ // CHECK-A64-NEXT: call void @_Z12Tp2addrspace12Sp2addrspace([2 x i64] [[TMP0]])
715
+ // CHECK-A64-NEXT: ret void
716
+ //
717
+ // CHECK-A64_32-LABEL: define void @_Z12Cp2addrspacev(
718
+ // CHECK-A64_32-SAME: ) #[[ATTR0]] {
719
+ // CHECK-A64_32-NEXT: [[ENTRY:.*:]]
720
+ // CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 4
721
+ // CHECK-A64_32-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SP2ADDRSPACE]], align 4
722
+ // CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TMP]], ptr align 4 [[S]], i32 8, i1 false)
723
+ // CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0
724
+ // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load i64, ptr [[COERCE_DIVE]], align 4
725
+ // CHECK-A64_32-NEXT: call void @_Z12Tp2addrspace12Sp2addrspace(i64 [[TMP0]])
726
+ // CHECK-A64_32-NEXT: ret void
727
+ //
728
+ void Cp2addrspace () { Sp2addrspace s; Tp2addrspace (s); }
729
+
730
+ struct Sraddrspace {
731
+ __attribute__ ((address_space(100 ))) int &x;
732
+ };
733
+ // CHECK-A64-LABEL: define dso_local void @_Z11Traddrspace11Sraddrspace(
734
+ // CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {
735
+ // CHECK-A64-NEXT: [[ENTRY:.*:]]
736
+ // CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 8
737
+ // CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0
738
+ // CHECK-A64-NEXT: [[COERCE_VAL_IP:%.*]] = inttoptr i64 [[S_COERCE]] to ptr addrspace(100)
739
+ // CHECK-A64-NEXT: store ptr addrspace(100) [[COERCE_VAL_IP]], ptr [[COERCE_DIVE]], align 8
740
+ // CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0
741
+ // CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 8, !align [[META3]]
742
+ // CHECK-A64-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4
743
+ // CHECK-A64-NEXT: ret void
744
+ //
745
+ // CHECK-A64_32-LABEL: define void @_Z11Traddrspace11Sraddrspace(
746
+ // CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {
747
+ // CHECK-A64_32-NEXT: [[ENTRY:.*:]]
748
+ // CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 4
749
+ // CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0
750
+ // CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32
751
+ // CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4
752
+ // CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0
753
+ // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 4, !align [[META3]]
754
+ // CHECK-A64_32-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4
755
+ // CHECK-A64_32-NEXT: ret void
756
+ //
757
+ void Traddrspace (Sraddrspace s) { s.x = 1 ; }
758
+ // CHECK-A64-LABEL: define dso_local void @_Z11Craddrspace11Sraddrspace(
759
+ // CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {
760
+ // CHECK-A64-NEXT: [[ENTRY:.*:]]
761
+ // CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 8
762
+ // CHECK-A64-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SRADDRSPACE]], align 8
763
+ // CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0
764
+ // CHECK-A64-NEXT: [[COERCE_VAL_IP:%.*]] = inttoptr i64 [[S_COERCE]] to ptr addrspace(100)
765
+ // CHECK-A64-NEXT: store ptr addrspace(100) [[COERCE_VAL_IP]], ptr [[COERCE_DIVE]], align 8
766
+ // CHECK-A64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TMP]], ptr align 8 [[S]], i64 8, i1 false)
767
+ // CHECK-A64-NEXT: [[COERCE_DIVE1:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0
768
+ // CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE1]], align 8
769
+ // CHECK-A64-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i64
770
+ // CHECK-A64-NEXT: call void @_Z11Traddrspace11Sraddrspace(i64 [[COERCE_VAL_PI]])
771
+ // CHECK-A64-NEXT: ret void
772
+ //
773
+ // CHECK-A64_32-LABEL: define void @_Z11Craddrspace11Sraddrspace(
774
+ // CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {
775
+ // CHECK-A64_32-NEXT: [[ENTRY:.*:]]
776
+ // CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 4
777
+ // CHECK-A64_32-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SRADDRSPACE]], align 4
778
+ // CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0
779
+ // CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32
780
+ // CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4
781
+ // CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TMP]], ptr align 4 [[S]], i32 4, i1 false)
782
+ // CHECK-A64_32-NEXT: [[COERCE_DIVE1:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0
783
+ // CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE1]], align 4
784
+ // CHECK-A64_32-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i32
785
+ // CHECK-A64_32-NEXT: [[COERCE_VAL_II2:%.*]] = zext i32 [[COERCE_VAL_PI]] to i64
786
+ // CHECK-A64_32-NEXT: call void @_Z11Traddrspace11Sraddrspace(i64 [[COERCE_VAL_II2]])
787
+ // CHECK-A64_32-NEXT: ret void
788
+ //
789
+ void Craddrspace (Sraddrspace s) { Traddrspace (s); }
790
+
791
+ // .
792
+ // CHECK-A64: [[META2]] = !{}
793
+ // CHECK-A64: [[META3]] = !{i64 4}
794
+ // .
795
+ // CHECK-A64_32: [[META2]] = !{}
796
+ // CHECK-A64_32: [[META3]] = !{i64 4}
797
+ // .
0 commit comments