@@ -139,7 +139,7 @@ struct Srp {
139139// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SRP:%.*]], align 8
140140// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 8
141141// 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]+]]
143143// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4
144144// CHECK-A64-NEXT: ret void
145145//
@@ -149,7 +149,7 @@ struct Srp {
149149// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SRP:%.*]], align 4
150150// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4
151151// 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]+]]
153153// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4
154154// CHECK-A64_32-NEXT: ret void
155155//
@@ -618,3 +618,180 @@ struct SpSempty {
618618// CHECK-A64_32-NEXT: ret void
619619//
620620void 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