800 lines · cpp
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 52// RUN: %clang_cc1 -triple aarch64-none-elf -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-A643// RUN: %clang_cc1 -triple arm64_32-apple-ios7.0 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-A64_324 5struct Sll {6 long long x, y;7};8// CHECK-A64-LABEL: define dso_local void @_Z3Tll3Sll(9// CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {10// CHECK-A64-NEXT: [[ENTRY:.*:]]11// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SLL:%.*]], align 812// CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[S]], align 813// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SLL]], ptr [[S]], i32 0, i32 014// CHECK-A64-NEXT: store i64 1, ptr [[X]], align 815// CHECK-A64-NEXT: ret void16//17// CHECK-A64_32-LABEL: define void @_Z3Tll3Sll(18// CHECK-A64_32-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {19// CHECK-A64_32-NEXT: [[ENTRY:.*:]]20// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SLL:%.*]], align 821// CHECK-A64_32-NEXT: store [2 x i64] [[S_COERCE]], ptr [[S]], align 822// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SLL]], ptr [[S]], i32 0, i32 023// CHECK-A64_32-NEXT: store i64 1, ptr [[X]], align 824// CHECK-A64_32-NEXT: ret void25//26void Tll(Sll s) { s.x = 1; }27 28struct Sp {29 int *x;30};31// CHECK-A64-LABEL: define dso_local void @_Z2Tp2Sp(32// CHECK-A64-SAME: ptr [[S_COERCE:%.*]]) #[[ATTR0]] {33// CHECK-A64-NEXT: [[ENTRY:.*:]]34// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SP:%.*]], align 835// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP]], ptr [[S]], i32 0, i32 036// CHECK-A64-NEXT: store ptr [[S_COERCE]], ptr [[COERCE_DIVE]], align 837// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP]], ptr [[S]], i32 0, i32 038// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 839// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 440// CHECK-A64-NEXT: ret void41//42// CHECK-A64_32-LABEL: define void @_Z2Tp2Sp(43// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {44// CHECK-A64_32-NEXT: [[ENTRY:.*:]]45// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SP:%.*]], align 446// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP]], ptr [[S]], i32 0, i32 047// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i3248// CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 449// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP]], ptr [[S]], i32 0, i32 050// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 451// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 452// CHECK-A64_32-NEXT: ret void53//54void Tp(Sp s) { *s.x = 1; }55 56struct Spp {57 int *x, *y;58};59// CHECK-A64-LABEL: define dso_local void @_Z3Tpp3Spp(60// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {61// CHECK-A64-NEXT: [[ENTRY:.*:]]62// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP:%.*]], align 863// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 864// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP]], ptr [[S]], i32 0, i32 065// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 866// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 467// CHECK-A64-NEXT: ret void68//69// CHECK-A64_32-LABEL: define void @_Z3Tpp3Spp(70// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {71// CHECK-A64_32-NEXT: [[ENTRY:.*:]]72// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP:%.*]], align 473// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 474// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP]], ptr [[S]], i32 0, i32 075// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 476// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 477// CHECK-A64_32-NEXT: ret void78//79void Tpp(Spp s) { *s.x = 1; }80 81struct Sppp {82 int *x, *y, *z;83};84// CHECK-A64-LABEL: define dso_local void @_Z4Tppp4Sppp(85// CHECK-A64-SAME: ptr dead_on_return noundef [[S:%.*]]) #[[ATTR0]] {86// CHECK-A64-NEXT: [[ENTRY:.*:]]87// CHECK-A64-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 888// CHECK-A64-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 889// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPPP:%.*]], ptr [[S]], i32 0, i32 090// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 891// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 492// CHECK-A64-NEXT: ret void93//94// CHECK-A64_32-LABEL: define void @_Z4Tppp4Sppp(95// CHECK-A64_32-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {96// CHECK-A64_32-NEXT: [[ENTRY:.*:]]97// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPPP:%.*]], align 498// CHECK-A64_32-NEXT: [[TMP_COERCE:%.*]] = alloca [2 x i64], align 899// CHECK-A64_32-NEXT: store [2 x i64] [[S_COERCE]], ptr [[TMP_COERCE]], align 8100// CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[S]], ptr align 8 [[TMP_COERCE]], i32 12, i1 false)101// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPPP]], ptr [[S]], i32 0, i32 0102// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4103// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4104// CHECK-A64_32-NEXT: ret void105//106void Tppp(Sppp s) { *s.x = 1; }107 108struct Spi {109 int *x, y;110};111// CHECK-A64-LABEL: define dso_local void @_Z3Tpi3Spi(112// CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {113// CHECK-A64-NEXT: [[ENTRY:.*:]]114// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPI:%.*]], align 8115// CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[S]], align 8116// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPI]], ptr [[S]], i32 0, i32 0117// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8118// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4119// CHECK-A64-NEXT: ret void120//121// CHECK-A64_32-LABEL: define void @_Z3Tpi3Spi(122// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {123// CHECK-A64_32-NEXT: [[ENTRY:.*:]]124// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPI:%.*]], align 4125// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4126// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPI]], ptr [[S]], i32 0, i32 0127// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4128// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4129// CHECK-A64_32-NEXT: ret void130//131void Tpi(Spi s) { *s.x = 1; }132 133struct Srp {134 int &x, *y;135};136// CHECK-A64-LABEL: define dso_local void @_Z3Trp3Srp(137// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {138// CHECK-A64-NEXT: [[ENTRY:.*:]]139// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SRP:%.*]], align 8140// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 8141// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRP]], ptr [[S]], i32 0, i32 0142// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]143// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4144// CHECK-A64-NEXT: ret void145//146// CHECK-A64_32-LABEL: define void @_Z3Trp3Srp(147// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {148// CHECK-A64_32-NEXT: [[ENTRY:.*:]]149// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SRP:%.*]], align 4150// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4151// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRP]], ptr [[S]], i32 0, i32 0152// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]]153// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4154// CHECK-A64_32-NEXT: ret void155//156void Trp(Srp s) { s.x = 1; }157 158struct __attribute__((__packed__)) Spp_packed {159 int *x, *y;160};161// CHECK-A64-LABEL: define dso_local void @_Z10Tpp_packed10Spp_packed(162// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {163// CHECK-A64-NEXT: [[ENTRY:.*:]]164// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP_PACKED:%.*]], align 1165// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 1166// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_PACKED]], ptr [[S]], i32 0, i32 0167// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 1168// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4169// CHECK-A64-NEXT: ret void170//171// CHECK-A64_32-LABEL: define void @_Z10Tpp_packed10Spp_packed(172// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {173// CHECK-A64_32-NEXT: [[ENTRY:.*:]]174// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP_PACKED:%.*]], align 1175// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 1176// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_PACKED]], ptr [[S]], i32 0, i32 0177// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 1178// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4179// CHECK-A64_32-NEXT: ret void180//181void Tpp_packed(Spp_packed s) { *s.x = 1; }182 183struct __attribute__((__packed__)) Spp_superpacked {184 Spp_packed x;185};186// CHECK-A64-LABEL: define dso_local void @_Z15Tpp_superpacked15Spp_superpacked(187// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {188// CHECK-A64-NEXT: [[ENTRY:.*:]]189// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP_SUPERPACKED:%.*]], align 1190// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_SUPERPACKED]], ptr [[S]], i32 0, i32 0191// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[COERCE_DIVE]], align 1192// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_SUPERPACKED]], ptr [[S]], i32 0, i32 0193// CHECK-A64-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_PACKED:%.*]], ptr [[X]], i32 0, i32 0194// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X1]], align 1195// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4196// CHECK-A64-NEXT: ret void197//198// CHECK-A64_32-LABEL: define void @_Z15Tpp_superpacked15Spp_superpacked(199// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {200// CHECK-A64_32-NEXT: [[ENTRY:.*:]]201// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP_SUPERPACKED:%.*]], align 1202// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_SUPERPACKED]], ptr [[S]], i32 0, i32 0203// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[COERCE_DIVE]], align 1204// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_SUPERPACKED]], ptr [[S]], i32 0, i32 0205// CHECK-A64_32-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_PACKED:%.*]], ptr [[X]], i32 0, i32 0206// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X1]], align 1207// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4208// CHECK-A64_32-NEXT: ret void209//210void Tpp_superpacked(Spp_superpacked s) { *s.x.x = 1; }211 212union Upp {213 int *x;214 long long *y;215};216// CHECK-A64-LABEL: define dso_local void @_Z11Tupp_packed3Upp(217// CHECK-A64-SAME: ptr [[S_COERCE:%.*]]) #[[ATTR0]] {218// CHECK-A64-NEXT: [[ENTRY:.*:]]219// CHECK-A64-NEXT: [[S:%.*]] = alloca [[UNION_UPP:%.*]], align 8220// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_UPP]], ptr [[S]], i32 0, i32 0221// CHECK-A64-NEXT: store ptr [[S_COERCE]], ptr [[COERCE_DIVE]], align 8222// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 8223// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4224// CHECK-A64-NEXT: ret void225//226// CHECK-A64_32-LABEL: define void @_Z11Tupp_packed3Upp(227// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {228// CHECK-A64_32-NEXT: [[ENTRY:.*:]]229// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[UNION_UPP:%.*]], align 4230// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_UPP]], ptr [[S]], i32 0, i32 0231// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32232// CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4233// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S]], align 4234// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4235// CHECK-A64_32-NEXT: ret void236//237void Tupp_packed(Upp s) { *s.x = 1; }238 239union USpp {240 Spp s;241 long long y;242};243// CHECK-A64-LABEL: define dso_local void @_Z12TUSpp_packed4USpp(244// CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {245// CHECK-A64-NEXT: [[ENTRY:.*:]]246// CHECK-A64-NEXT: [[S:%.*]] = alloca [[UNION_USPP:%.*]], align 8247// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_USPP]], ptr [[S]], i32 0, i32 0248// CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[COERCE_DIVE]], align 8249// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP:%.*]], ptr [[S]], i32 0, i32 0250// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8251// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4252// CHECK-A64-NEXT: ret void253//254// CHECK-A64_32-LABEL: define void @_Z12TUSpp_packed4USpp(255// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {256// CHECK-A64_32-NEXT: [[ENTRY:.*:]]257// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[UNION_USPP:%.*]], align 8258// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[UNION_USPP]], ptr [[S]], i32 0, i32 0259// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[COERCE_DIVE]], align 8260// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP:%.*]], ptr [[S]], i32 0, i32 0261// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8262// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4263// CHECK-A64_32-NEXT: ret void264//265void TUSpp_packed(USpp s) { *s.s.x = 1; }266 267struct Spf {268 int *x;269 int z[];270};271// CHECK-A64-LABEL: define dso_local void @_Z3Tpf3Spf(272// CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {273// CHECK-A64-NEXT: [[ENTRY:.*:]]274// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPF:%.*]], align 8275// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPF]], ptr [[S]], i32 0, i32 0276// CHECK-A64-NEXT: [[COERCE_VAL_IP:%.*]] = inttoptr i64 [[S_COERCE]] to ptr277// CHECK-A64-NEXT: store ptr [[COERCE_VAL_IP]], ptr [[COERCE_DIVE]], align 8278// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPF]], ptr [[S]], i32 0, i32 0279// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8280// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4281// CHECK-A64-NEXT: ret void282//283// CHECK-A64_32-LABEL: define void @_Z3Tpf3Spf(284// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {285// CHECK-A64_32-NEXT: [[ENTRY:.*:]]286// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPF:%.*]], align 4287// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPF]], ptr [[S]], i32 0, i32 0288// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32289// CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4290// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPF]], ptr [[S]], i32 0, i32 0291// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4292// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4293// CHECK-A64_32-NEXT: ret void294//295void Tpf(Spf s) { *s.x = 1; }296 297struct Sppf {298 int *x, *y;299 int z[];300};301// CHECK-A64-LABEL: define dso_local void @_Z4Tppf4Sppf(302// CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {303// CHECK-A64-NEXT: [[ENTRY:.*:]]304// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPPF:%.*]], align 8305// CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[S]], align 8306// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPPF]], ptr [[S]], i32 0, i32 0307// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8308// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4309// CHECK-A64-NEXT: ret void310//311// CHECK-A64_32-LABEL: define void @_Z4Tppf4Sppf(312// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {313// CHECK-A64_32-NEXT: [[ENTRY:.*:]]314// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPPF:%.*]], align 4315// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4316// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPPF]], ptr [[S]], i32 0, i32 0317// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4318// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4319// CHECK-A64_32-NEXT: ret void320//321void Tppf(Sppf s) { *s.x = 1; }322 323struct SSpSp {324 struct Sp a, b;325};326// CHECK-A64-LABEL: define dso_local void @_Z5TSpSp5SSpSp(327// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {328// CHECK-A64-NEXT: [[ENTRY:.*:]]329// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPSP:%.*]], align 8330// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 8331// CHECK-A64-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPSP]], ptr [[S]], i32 0, i32 0332// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP:%.*]], ptr [[A]], i32 0, i32 0333// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8334// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4335// CHECK-A64-NEXT: ret void336//337// CHECK-A64_32-LABEL: define void @_Z5TSpSp5SSpSp(338// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {339// CHECK-A64_32-NEXT: [[ENTRY:.*:]]340// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPSP:%.*]], align 4341// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4342// CHECK-A64_32-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPSP]], ptr [[S]], i32 0, i32 0343// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP:%.*]], ptr [[A]], i32 0, i32 0344// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4345// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4346// CHECK-A64_32-NEXT: ret void347//348void TSpSp(SSpSp s) { *s.a.x = 1; }349 350struct SSpp {351 Spp a;352};353// CHECK-A64-LABEL: define dso_local void @_Z4TSpp4SSpp(354// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {355// CHECK-A64-NEXT: [[ENTRY:.*:]]356// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPP:%.*]], align 8357// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP]], ptr [[S]], i32 0, i32 0358// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[COERCE_DIVE]], align 8359// CHECK-A64-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP]], ptr [[S]], i32 0, i32 0360// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP:%.*]], ptr [[A]], i32 0, i32 0361// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8362// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4363// CHECK-A64-NEXT: ret void364//365// CHECK-A64_32-LABEL: define void @_Z4TSpp4SSpp(366// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {367// CHECK-A64_32-NEXT: [[ENTRY:.*:]]368// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPP:%.*]], align 4369// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP]], ptr [[S]], i32 0, i32 0370// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[COERCE_DIVE]], align 4371// CHECK-A64_32-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP]], ptr [[S]], i32 0, i32 0372// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP:%.*]], ptr [[A]], i32 0, i32 0373// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4374// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4375// CHECK-A64_32-NEXT: ret void376//377void TSpp(SSpp s) { *s.a.x = 1; }378 379struct SSp : public Sp {380 int* b;381};382// CHECK-A64-LABEL: define dso_local void @_Z3TSp3SSp(383// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {384// CHECK-A64-NEXT: [[ENTRY:.*:]]385// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SSP:%.*]], align 8386// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 8387// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP:%.*]], ptr [[S]], i32 0, i32 0388// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8389// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4390// CHECK-A64-NEXT: ret void391//392// CHECK-A64_32-LABEL: define void @_Z3TSp3SSp(393// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {394// CHECK-A64_32-NEXT: [[ENTRY:.*:]]395// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SSP:%.*]], align 4396// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4397// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP:%.*]], ptr [[S]], i32 0, i32 0398// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4399// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4400// CHECK-A64_32-NEXT: ret void401//402void TSp(SSp s) { *s.x = 1; }403 404struct Si {405 int x;406};407struct SSpi : public Si {408 int* y;409};410// CHECK-A64-LABEL: define dso_local void @_Z4TSpi4SSpi(411// CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {412// CHECK-A64-NEXT: [[ENTRY:.*:]]413// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPI:%.*]], align 8414// CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[S]], align 8415// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SI:%.*]], ptr [[S]], i32 0, i32 0416// CHECK-A64-NEXT: store i32 1, ptr [[X]], align 8417// CHECK-A64-NEXT: ret void418//419// CHECK-A64_32-LABEL: define void @_Z4TSpi4SSpi(420// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {421// CHECK-A64_32-NEXT: [[ENTRY:.*:]]422// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPI:%.*]], align 4423// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4424// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SI:%.*]], ptr [[S]], i32 0, i32 0425// CHECK-A64_32-NEXT: store i32 1, ptr [[X]], align 4426// CHECK-A64_32-NEXT: ret void427//428void TSpi(SSpi s) { s.x = 1; }429 430struct Spa {431 int* xs[1];432};433// CHECK-A64-LABEL: define dso_local void @_Z3Tpa3Spa(434// CHECK-A64-SAME: ptr [[S_COERCE:%.*]]) #[[ATTR0]] {435// CHECK-A64-NEXT: [[ENTRY:.*:]]436// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPA:%.*]], align 8437// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA]], ptr [[S]], i32 0, i32 0438// CHECK-A64-NEXT: store ptr [[S_COERCE]], ptr [[COERCE_DIVE]], align 8439// CHECK-A64-NEXT: [[XS:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA]], ptr [[S]], i32 0, i32 0440// CHECK-A64-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1 x ptr], ptr [[XS]], i64 0, i64 0441// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8442// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4443// CHECK-A64-NEXT: ret void444//445// CHECK-A64_32-LABEL: define void @_Z3Tpa3Spa(446// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {447// CHECK-A64_32-NEXT: [[ENTRY:.*:]]448// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPA:%.*]], align 4449// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA]], ptr [[S]], i32 0, i32 0450// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32451// CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4452// CHECK-A64_32-NEXT: [[XS:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA]], ptr [[S]], i32 0, i32 0453// CHECK-A64_32-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1 x ptr], ptr [[XS]], i32 0, i32 0454// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 4455// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4456// CHECK-A64_32-NEXT: ret void457//458void Tpa(Spa s) { *s.xs[0] = 1; }459 460struct Spa2 {461 int* xs[2];462};463// CHECK-A64-LABEL: define dso_local void @_Z4Tpa24Spa2(464// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {465// CHECK-A64-NEXT: [[ENTRY:.*:]]466// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPA2:%.*]], align 8467// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA2]], ptr [[S]], i32 0, i32 0468// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[COERCE_DIVE]], align 8469// CHECK-A64-NEXT: [[XS:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA2]], ptr [[S]], i32 0, i32 0470// CHECK-A64-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr], ptr [[XS]], i64 0, i64 0471// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8472// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4473// CHECK-A64-NEXT: ret void474//475// CHECK-A64_32-LABEL: define void @_Z4Tpa24Spa2(476// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {477// CHECK-A64_32-NEXT: [[ENTRY:.*:]]478// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPA2:%.*]], align 4479// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA2]], ptr [[S]], i32 0, i32 0480// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[COERCE_DIVE]], align 4481// CHECK-A64_32-NEXT: [[XS:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA2]], ptr [[S]], i32 0, i32 0482// CHECK-A64_32-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr], ptr [[XS]], i32 0, i32 0483// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 4484// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4485// CHECK-A64_32-NEXT: ret void486//487void Tpa2(Spa2 s) { *s.xs[0] = 1; }488 489struct Spa3 {490 int* xs[3];491};492// CHECK-A64-LABEL: define dso_local void @_Z4Tpa34Spa3(493// CHECK-A64-SAME: ptr dead_on_return noundef [[S:%.*]]) #[[ATTR0]] {494// CHECK-A64-NEXT: [[ENTRY:.*:]]495// CHECK-A64-NEXT: [[S_INDIRECT_ADDR:%.*]] = alloca ptr, align 8496// CHECK-A64-NEXT: store ptr [[S]], ptr [[S_INDIRECT_ADDR]], align 8497// CHECK-A64-NEXT: [[XS:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA3:%.*]], ptr [[S]], i32 0, i32 0498// CHECK-A64-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [3 x ptr], ptr [[XS]], i64 0, i64 0499// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8500// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4501// CHECK-A64-NEXT: ret void502//503// CHECK-A64_32-LABEL: define void @_Z4Tpa34Spa3(504// CHECK-A64_32-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {505// CHECK-A64_32-NEXT: [[ENTRY:.*:]]506// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPA3:%.*]], align 4507// CHECK-A64_32-NEXT: [[TMP_COERCE:%.*]] = alloca [2 x i64], align 8508// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA3]], ptr [[S]], i32 0, i32 0509// CHECK-A64_32-NEXT: store [2 x i64] [[S_COERCE]], ptr [[TMP_COERCE]], align 8510// CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[COERCE_DIVE]], ptr align 8 [[TMP_COERCE]], i32 12, i1 false)511// CHECK-A64_32-NEXT: [[XS:%.*]] = getelementptr inbounds nuw [[STRUCT_SPA3]], ptr [[S]], i32 0, i32 0512// CHECK-A64_32-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [3 x ptr], ptr [[XS]], i32 0, i32 0513// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 4514// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4515// CHECK-A64_32-NEXT: ret void516//517void Tpa3(Spa3 s) { *s.xs[0] = 1; }518 519 520struct __attribute__((aligned(16))) Spp_align16 {521 int *x, *y;522};523// CHECK-A64-LABEL: define dso_local void @_Z11Tpp_align1611Spp_align16(524// CHECK-A64-SAME: [2 x ptr] [[S_COERCE:%.*]]) #[[ATTR0]] {525// CHECK-A64-NEXT: [[ENTRY:.*:]]526// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP_ALIGN16:%.*]], align 16527// CHECK-A64-NEXT: store [2 x ptr] [[S_COERCE]], ptr [[S]], align 16528// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_ALIGN16]], ptr [[S]], i32 0, i32 0529// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 16530// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4531// CHECK-A64-NEXT: ret void532//533// CHECK-A64_32-LABEL: define void @_Z11Tpp_align1611Spp_align16(534// CHECK-A64_32-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {535// CHECK-A64_32-NEXT: [[ENTRY:.*:]]536// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPP_ALIGN16:%.*]], align 16537// CHECK-A64_32-NEXT: store [2 x i64] [[S_COERCE]], ptr [[S]], align 16538// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_ALIGN16]], ptr [[S]], i32 0, i32 0539// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 16540// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4541// CHECK-A64_32-NEXT: ret void542//543void Tpp_align16(Spp_align16 s) { *s.x = 1; }544 545struct SSpp_align16 {546 Spp_align16 a;547};548// CHECK-A64-LABEL: define dso_local void @_Z12TSpp_align1612SSpp_align16(549// CHECK-A64-SAME: i128 [[S_COERCE:%.*]]) #[[ATTR0]] {550// CHECK-A64-NEXT: [[ENTRY:.*:]]551// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPP_ALIGN16:%.*]], align 16552// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP_ALIGN16]], ptr [[S]], i32 0, i32 0553// CHECK-A64-NEXT: store i128 [[S_COERCE]], ptr [[COERCE_DIVE]], align 16554// CHECK-A64-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP_ALIGN16]], ptr [[S]], i32 0, i32 0555// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_ALIGN16:%.*]], ptr [[A]], i32 0, i32 0556// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 16557// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4558// CHECK-A64-NEXT: ret void559//560// CHECK-A64_32-LABEL: define void @_Z12TSpp_align1612SSpp_align16(561// CHECK-A64_32-SAME: i128 [[S_COERCE:%.*]]) #[[ATTR0]] {562// CHECK-A64_32-NEXT: [[ENTRY:.*:]]563// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SSPP_ALIGN16:%.*]], align 16564// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP_ALIGN16]], ptr [[S]], i32 0, i32 0565// CHECK-A64_32-NEXT: store i128 [[S_COERCE]], ptr [[COERCE_DIVE]], align 16566// CHECK-A64_32-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_SSPP_ALIGN16]], ptr [[S]], i32 0, i32 0567// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPP_ALIGN16:%.*]], ptr [[A]], i32 0, i32 0568// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 16569// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4570// CHECK-A64_32-NEXT: ret void571//572void TSpp_align16(SSpp_align16 s) { *s.a.x = 1; }573 574 575struct Sempty {576};577// CHECK-A64-LABEL: define dso_local void @_Z6Tempty6Sempty(578// CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {579// CHECK-A64-NEXT: [[ENTRY:.*:]]580// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SEMPTY:%.*]], align 1581// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SEMPTY]], ptr [[S]], i32 0, i32 0582// CHECK-A64-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i8583// CHECK-A64-NEXT: store i8 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 1584// CHECK-A64-NEXT: ret void585//586// CHECK-A64_32-LABEL: define void @_Z6Tempty6Sempty(587// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {588// CHECK-A64_32-NEXT: [[ENTRY:.*:]]589// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SEMPTY:%.*]], align 1590// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SEMPTY]], ptr [[S]], i32 0, i32 0591// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i8592// CHECK-A64_32-NEXT: store i8 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 1593// CHECK-A64_32-NEXT: ret void594//595void Tempty(Sempty s) { }596 597 598struct SpSempty {599 Sempty y;600 int *x;601};602// CHECK-A64-LABEL: define dso_local void @_Z8TpSempty8SpSempty(603// CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {604// CHECK-A64-NEXT: [[ENTRY:.*:]]605// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPSEMPTY:%.*]], align 8606// CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[S]], align 8607// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPSEMPTY]], ptr [[S]], i32 0, i32 1608// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 8609// CHECK-A64-NEXT: store i32 1, ptr [[TMP0]], align 4610// CHECK-A64-NEXT: ret void611//612// CHECK-A64_32-LABEL: define void @_Z8TpSempty8SpSempty(613// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {614// CHECK-A64_32-NEXT: [[ENTRY:.*:]]615// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPSEMPTY:%.*]], align 4616// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[S]], align 4617// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPSEMPTY]], ptr [[S]], i32 0, i32 1618// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr, ptr [[X]], align 4619// CHECK-A64_32-NEXT: store i32 1, ptr [[TMP0]], align 4620// CHECK-A64_32-NEXT: ret void621//622void TpSempty(SpSempty s) { *s.x = 1; }623 624 625struct Spaddrspace {626 __attribute__((address_space(100))) int *x;627};628// CHECK-A64-LABEL: define dso_local void @_Z11Tpaddrspace11Spaddrspace(629// CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {630// CHECK-A64-NEXT: [[ENTRY:.*:]]631// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 8632// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0633// CHECK-A64-NEXT: [[COERCE_VAL_IP:%.*]] = inttoptr i64 [[S_COERCE]] to ptr addrspace(100)634// CHECK-A64-NEXT: store ptr addrspace(100) [[COERCE_VAL_IP]], ptr [[COERCE_DIVE]], align 8635// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0636// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 8637// CHECK-A64-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4638// CHECK-A64-NEXT: ret void639//640// CHECK-A64_32-LABEL: define void @_Z11Tpaddrspace11Spaddrspace(641// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {642// CHECK-A64_32-NEXT: [[ENTRY:.*:]]643// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 4644// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0645// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32646// CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4647// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[S]], i32 0, i32 0648// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 4649// CHECK-A64_32-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4650// CHECK-A64_32-NEXT: ret void651//652void Tpaddrspace(Spaddrspace s) { *s.x = 1; }653// CHECK-A64-LABEL: define dso_local void @_Z11Cpaddrspacev(654// CHECK-A64-SAME: ) #[[ATTR0]] {655// CHECK-A64-NEXT: [[ENTRY:.*:]]656// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 8657// CHECK-A64-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SPADDRSPACE]], align 8658// CHECK-A64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TMP]], ptr align 8 [[S]], i64 8, i1 false)659// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0660// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE]], align 8661// CHECK-A64-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i64662// CHECK-A64-NEXT: call void @_Z11Tpaddrspace11Spaddrspace(i64 [[COERCE_VAL_PI]])663// CHECK-A64-NEXT: ret void664//665// CHECK-A64_32-LABEL: define void @_Z11Cpaddrspacev(666// CHECK-A64_32-SAME: ) #[[ATTR0]] {667// CHECK-A64_32-NEXT: [[ENTRY:.*:]]668// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SPADDRSPACE:%.*]], align 4669// CHECK-A64_32-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SPADDRSPACE]], align 4670// CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TMP]], ptr align 4 [[S]], i32 4, i1 false)671// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SPADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0672// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE]], align 4673// CHECK-A64_32-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i32674// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = zext i32 [[COERCE_VAL_PI]] to i64675// CHECK-A64_32-NEXT: call void @_Z11Tpaddrspace11Spaddrspace(i64 [[COERCE_VAL_II]])676// CHECK-A64_32-NEXT: ret void677//678void Cpaddrspace() { Spaddrspace s; Tpaddrspace(s); }679 680struct Sp2addrspace {681 __attribute__((address_space(100))) int *x[2];682};683// CHECK-A64-LABEL: define dso_local void @_Z12Tp2addrspace12Sp2addrspace(684// CHECK-A64-SAME: [2 x i64] [[S_COERCE:%.*]]) #[[ATTR0]] {685// CHECK-A64-NEXT: [[ENTRY:.*:]]686// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 8687// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0688// CHECK-A64-NEXT: store [2 x i64] [[S_COERCE]], ptr [[COERCE_DIVE]], align 8689// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0690// CHECK-A64-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr addrspace(100)], ptr [[X]], i64 0, i64 0691// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[ARRAYIDX]], align 8692// CHECK-A64-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4693// CHECK-A64-NEXT: ret void694//695// CHECK-A64_32-LABEL: define void @_Z12Tp2addrspace12Sp2addrspace(696// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {697// CHECK-A64_32-NEXT: [[ENTRY:.*:]]698// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 4699// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0700// CHECK-A64_32-NEXT: store i64 [[S_COERCE]], ptr [[COERCE_DIVE]], align 4701// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[S]], i32 0, i32 0702// CHECK-A64_32-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr addrspace(100)], ptr [[X]], i32 0, i32 0703// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[ARRAYIDX]], align 4704// CHECK-A64_32-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4705// CHECK-A64_32-NEXT: ret void706//707void Tp2addrspace(Sp2addrspace s) { *s.x[0] = 1; }708// CHECK-A64-LABEL: define dso_local void @_Z12Cp2addrspacev(709// CHECK-A64-SAME: ) #[[ATTR0]] {710// CHECK-A64-NEXT: [[ENTRY:.*:]]711// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 8712// CHECK-A64-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SP2ADDRSPACE]], align 8713// CHECK-A64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TMP]], ptr align 8 [[S]], i64 16, i1 false)714// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0715// CHECK-A64-NEXT: [[TMP0:%.*]] = load [2 x i64], ptr [[COERCE_DIVE]], align 8716// CHECK-A64-NEXT: call void @_Z12Tp2addrspace12Sp2addrspace([2 x i64] [[TMP0]])717// CHECK-A64-NEXT: ret void718//719// CHECK-A64_32-LABEL: define void @_Z12Cp2addrspacev(720// CHECK-A64_32-SAME: ) #[[ATTR0]] {721// CHECK-A64_32-NEXT: [[ENTRY:.*:]]722// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SP2ADDRSPACE:%.*]], align 4723// CHECK-A64_32-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SP2ADDRSPACE]], align 4724// CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TMP]], ptr align 4 [[S]], i32 8, i1 false)725// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SP2ADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0726// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load i64, ptr [[COERCE_DIVE]], align 4727// CHECK-A64_32-NEXT: call void @_Z12Tp2addrspace12Sp2addrspace(i64 [[TMP0]])728// CHECK-A64_32-NEXT: ret void729//730void Cp2addrspace() { Sp2addrspace s; Tp2addrspace(s); }731 732struct Sraddrspace {733 __attribute__((address_space(100))) int &x;734};735// CHECK-A64-LABEL: define dso_local void @_Z11Traddrspace11Sraddrspace(736// CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {737// CHECK-A64-NEXT: [[ENTRY:.*:]]738// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 8739// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0740// CHECK-A64-NEXT: [[COERCE_VAL_IP:%.*]] = inttoptr i64 [[S_COERCE]] to ptr addrspace(100)741// CHECK-A64-NEXT: store ptr addrspace(100) [[COERCE_VAL_IP]], ptr [[COERCE_DIVE]], align 8742// CHECK-A64-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0743// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 8, !align [[META3]]744// CHECK-A64-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4745// CHECK-A64-NEXT: ret void746//747// CHECK-A64_32-LABEL: define void @_Z11Traddrspace11Sraddrspace(748// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {749// CHECK-A64_32-NEXT: [[ENTRY:.*:]]750// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 4751// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0752// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32753// CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4754// CHECK-A64_32-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0755// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[X]], align 4, !align [[META3]]756// CHECK-A64_32-NEXT: store i32 1, ptr addrspace(100) [[TMP0]], align 4757// CHECK-A64_32-NEXT: ret void758//759void Traddrspace(Sraddrspace s) { s.x = 1; }760// CHECK-A64-LABEL: define dso_local void @_Z11Craddrspace11Sraddrspace(761// CHECK-A64-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {762// CHECK-A64-NEXT: [[ENTRY:.*:]]763// CHECK-A64-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 8764// CHECK-A64-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SRADDRSPACE]], align 8765// CHECK-A64-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0766// CHECK-A64-NEXT: [[COERCE_VAL_IP:%.*]] = inttoptr i64 [[S_COERCE]] to ptr addrspace(100)767// CHECK-A64-NEXT: store ptr addrspace(100) [[COERCE_VAL_IP]], ptr [[COERCE_DIVE]], align 8768// CHECK-A64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_TMP]], ptr align 8 [[S]], i64 8, i1 false)769// CHECK-A64-NEXT: [[COERCE_DIVE1:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0770// CHECK-A64-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE1]], align 8771// CHECK-A64-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i64772// CHECK-A64-NEXT: call void @_Z11Traddrspace11Sraddrspace(i64 [[COERCE_VAL_PI]])773// CHECK-A64-NEXT: ret void774//775// CHECK-A64_32-LABEL: define void @_Z11Craddrspace11Sraddrspace(776// CHECK-A64_32-SAME: i64 [[S_COERCE:%.*]]) #[[ATTR0]] {777// CHECK-A64_32-NEXT: [[ENTRY:.*:]]778// CHECK-A64_32-NEXT: [[S:%.*]] = alloca [[STRUCT_SRADDRSPACE:%.*]], align 4779// CHECK-A64_32-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_SRADDRSPACE]], align 4780// CHECK-A64_32-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[S]], i32 0, i32 0781// CHECK-A64_32-NEXT: [[COERCE_VAL_II:%.*]] = trunc i64 [[S_COERCE]] to i32782// CHECK-A64_32-NEXT: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4783// CHECK-A64_32-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[AGG_TMP]], ptr align 4 [[S]], i32 4, i1 false)784// CHECK-A64_32-NEXT: [[COERCE_DIVE1:%.*]] = getelementptr inbounds nuw [[STRUCT_SRADDRSPACE]], ptr [[AGG_TMP]], i32 0, i32 0785// CHECK-A64_32-NEXT: [[TMP0:%.*]] = load ptr addrspace(100), ptr [[COERCE_DIVE1]], align 4786// CHECK-A64_32-NEXT: [[COERCE_VAL_PI:%.*]] = ptrtoint ptr addrspace(100) [[TMP0]] to i32787// CHECK-A64_32-NEXT: [[COERCE_VAL_II2:%.*]] = zext i32 [[COERCE_VAL_PI]] to i64788// CHECK-A64_32-NEXT: call void @_Z11Traddrspace11Sraddrspace(i64 [[COERCE_VAL_II2]])789// CHECK-A64_32-NEXT: ret void790//791void Craddrspace(Sraddrspace s) { Traddrspace(s); }792 793//.794// CHECK-A64: [[META2]] = !{}795// CHECK-A64: [[META3]] = !{i64 4}796//.797// CHECK-A64_32: [[META2]] = !{}798// CHECK-A64_32: [[META3]] = !{i64 4}799//.800