Skip to content

Commit 250620f

Browse files
committed
[OpaquePtr][AArch64] Use elementtype on ldxr/stxr
Includes verifier changes checking the elementtype, clang codegen changes to emit the elementtype, and ISel changes using the elementtype. Reviewed By: #opaque-pointers, nikic Differential Revision: https://reviews.llvm.org/D120527
1 parent 5d25267 commit 250620f

File tree

15 files changed

+175
-104
lines changed

15 files changed

+175
-104
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9684,23 +9684,26 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
96849684

96859685
QualType Ty = E->getType();
96869686
llvm::Type *RealResTy = ConvertType(Ty);
9687-
llvm::Type *PtrTy = llvm::IntegerType::get(
9688-
getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
9687+
llvm::Type *IntTy =
9688+
llvm::IntegerType::get(getLLVMContext(), getContext().getTypeSize(Ty));
9689+
llvm::Type *PtrTy = IntTy->getPointerTo();
96899690
LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
96909691

96919692
Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
96929693
? Intrinsic::aarch64_ldaxr
96939694
: Intrinsic::aarch64_ldxr,
96949695
PtrTy);
9695-
Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
9696+
CallInst *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
9697+
Val->addParamAttr(
9698+
0, Attribute::get(getLLVMContext(), Attribute::ElementType, IntTy));
96969699

96979700
if (RealResTy->isPointerTy())
96989701
return Builder.CreateIntToPtr(Val, RealResTy);
96999702

97009703
llvm::Type *IntResTy = llvm::IntegerType::get(
97019704
getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
9702-
Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
9703-
return Builder.CreateBitCast(Val, RealResTy);
9705+
return Builder.CreateBitCast(Builder.CreateTruncOrBitCast(Val, IntResTy),
9706+
RealResTy);
97049707
}
97059708

97069709
if ((BuiltinID == AArch64::BI__builtin_arm_strex ||
@@ -9748,7 +9751,10 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
97489751
? Intrinsic::aarch64_stlxr
97499752
: Intrinsic::aarch64_stxr,
97509753
StoreAddr->getType());
9751-
return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
9754+
CallInst *CI = Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
9755+
CI->addParamAttr(
9756+
1, Attribute::get(getLLVMContext(), Attribute::ElementType, StoreTy));
9757+
return CI;
97529758
}
97539759

97549760
if (BuiltinID == AArch64::BI__getReg) {

clang/test/CodeGen/arm_acle.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,10 @@ void test_dbg(void) {
153153
// AArch64-NEXT: [[TMP0:%.*]] = bitcast i8* [[P:%.*]] to i32*
154154
// AArch64-NEXT: br label [[DO_BODY_I:%.*]]
155155
// AArch64: do.body.i:
156-
// AArch64-NEXT: [[LDXR_I:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* [[TMP0]]) [[ATTR3]]
156+
// AArch64-NEXT: [[LDXR_I:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* elementtype(i32) [[TMP0]]) [[ATTR3]]
157157
// AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[LDXR_I]] to i32
158158
// AArch64-NEXT: [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
159-
// AArch64-NEXT: [[STXR_I:%.*]] = call i32 @llvm.aarch64.stxr.p0i32(i64 [[TMP2]], i32* [[TMP0]]) [[ATTR3]]
159+
// AArch64-NEXT: [[STXR_I:%.*]] = call i32 @llvm.aarch64.stxr.p0i32(i64 [[TMP2]], i32* elementtype(i32) [[TMP0]]) [[ATTR3]]
160160
// AArch64-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STXR_I]], 0
161161
// AArch64-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], [[LOOP6:!llvm.loop !.*]]
162162
// AArch64: __swp.exit:

clang/test/CodeGen/builtins-arm-exclusive.c

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) {
1313
// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i8(i8* %addr)
1414
// CHECK: trunc i32 [[INTRES]] to i8
1515

16-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i8(i8* %addr)
16+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i8(i8* elementtype(i8) %addr)
1717
// CHECK-ARM64: trunc i64 [[INTRES]] to i8
1818

1919
sum += __builtin_arm_ldrex((short *)addr);
@@ -22,15 +22,15 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) {
2222
// CHECK: trunc i32 [[INTRES]] to i16
2323

2424
// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
25-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i16(i16* [[ADDR16]])
25+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i16(i16* elementtype(i16) [[ADDR16]])
2626
// CHECK-ARM64: trunc i64 [[INTRES]] to i16
2727

2828
sum += __builtin_arm_ldrex((int *)addr);
2929
// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
3030
// CHECK: call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]])
3131

3232
// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
33-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* [[ADDR32]])
33+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* elementtype(i32) [[ADDR32]])
3434
// CHECK-ARM64: trunc i64 [[INTRES]] to i32
3535

3636
sum += __builtin_arm_ldrex((long long *)addr);
@@ -39,21 +39,21 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) {
3939
// CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* [[TMP5]])
4040

4141
// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
42-
// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]])
42+
// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* elementtype(i64) [[ADDR64]])
4343

4444
sum += __builtin_arm_ldrex(addr64);
4545
// CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8*
4646
// CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* [[ADDR64_AS8]])
4747

48-
// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* %addr64)
48+
// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* elementtype(i64) %addr64)
4949

5050
sum += __builtin_arm_ldrex(addrfloat);
5151
// CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
5252
// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* [[INTADDR]])
5353
// CHECK: bitcast i32 [[INTRES]] to float
5454

5555
// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
56-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* [[INTADDR]])
56+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* elementtype(i32) [[INTADDR]])
5757
// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
5858
// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float
5959

@@ -71,7 +71,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) {
7171

7272
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to double*
7373
// CHECK-ARM64: [[TMP5:%.*]] = bitcast double* [[TMP4]] to i64*
74-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i64(i64* [[TMP5]])
74+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i64(i64* elementtype(i64) [[TMP5]])
7575
// CHECK-ARM64: bitcast i64 [[INTRES]] to double
7676

7777
sum += *__builtin_arm_ldrex((int **)addr);
@@ -82,7 +82,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) {
8282

8383
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to i32**
8484
// CHECK-ARM64: [[TMP5:%.*]] = bitcast i32** [[TMP4]] to i64*
85-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i64(i64* [[TMP5]])
85+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i64(i64* elementtype(i64) [[TMP5]])
8686
// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32*
8787

8888
sum += __builtin_arm_ldrex((struct Simple **)addr)->a;
@@ -93,7 +93,7 @@ int test_ldrex(char *addr, long long *addr64, float *addrfloat) {
9393

9494
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple**
9595
// CHECK-ARM64: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i64*
96-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i64(i64* [[TMP5]])
96+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldxr.p0i64(i64* elementtype(i64) [[TMP5]])
9797
// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple*
9898
return sum;
9999
}
@@ -106,7 +106,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
106106
// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i8(i8* %addr)
107107
// CHECK: trunc i32 [[INTRES]] to i8
108108

109-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr)
109+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i8(i8* elementtype(i8) %addr)
110110
// CHECK-ARM64: trunc i64 [[INTRES]] to i8
111111

112112
sum += __builtin_arm_ldaex((short *)addr);
@@ -115,15 +115,15 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
115115
// CHECK: trunc i32 [[INTRES]] to i16
116116

117117
// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
118-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i16(i16* [[ADDR16]])
118+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i16(i16* elementtype(i16) [[ADDR16]])
119119
// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i16
120120

121121
sum += __builtin_arm_ldaex((int *)addr);
122122
// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
123123
// CHECK: call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]])
124124

125125
// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
126-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[ADDR32]])
126+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i32(i32* elementtype(i32) [[ADDR32]])
127127
// CHECK-ARM64: trunc i64 [[INTRES]] to i32
128128

129129
sum += __builtin_arm_ldaex((long long *)addr);
@@ -132,21 +132,21 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
132132
// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* [[TMP5]])
133133

134134
// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
135-
// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
135+
// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* elementtype(i64) [[ADDR64]])
136136

137137
sum += __builtin_arm_ldaex(addr64);
138138
// CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8*
139139
// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* [[ADDR64_AS8]])
140140

141-
// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr64)
141+
// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* elementtype(i64) %addr64)
142142

143143
sum += __builtin_arm_ldaex(addrfloat);
144144
// CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
145145
// CHECK: [[INTRES:%.*]] = call i32 @llvm.arm.ldaex.p0i32(i32* [[INTADDR]])
146146
// CHECK: bitcast i32 [[INTRES]] to float
147147

148148
// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
149-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[INTADDR]])
149+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i32(i32* elementtype(i32) [[INTADDR]])
150150
// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
151151
// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float
152152

@@ -164,7 +164,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
164164

165165
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to double*
166166
// CHECK-ARM64: [[TMP5:%.*]] = bitcast double* [[TMP4]] to i64*
167-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[TMP5]])
167+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i64(i64* elementtype(i64) [[TMP5]])
168168
// CHECK-ARM64: bitcast i64 [[INTRES]] to double
169169

170170
sum += *__builtin_arm_ldaex((int **)addr);
@@ -175,7 +175,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
175175

176176
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to i32**
177177
// CHECK-ARM64: [[TMP5:%.*]] = bitcast i32** [[TMP4]] to i64*
178-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[TMP5]])
178+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i64(i64* elementtype(i64) [[TMP5]])
179179
// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32*
180180

181181
sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
@@ -186,7 +186,7 @@ int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
186186

187187
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple**
188188
// CHECK-ARM64: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i64*
189-
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[TMP5]])
189+
// CHECK-ARM64: [[INTRES:%.*]] = call i64 @llvm.aarch64.ldaxr.p0i64(i64* elementtype(i64) [[TMP5]])
190190
// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple*
191191
return sum;
192192
}
@@ -199,21 +199,21 @@ int test_strex(char *addr) {
199199
res |= __builtin_arm_strex(4, addr);
200200
// CHECK: call i32 @llvm.arm.strex.p0i8(i32 4, i8* %addr)
201201

202-
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i8(i64 4, i8* %addr)
202+
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i8(i64 4, i8* elementtype(i8) %addr)
203203

204204
res |= __builtin_arm_strex(42, (short *)addr);
205205
// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
206206
// CHECK: call i32 @llvm.arm.strex.p0i16(i32 42, i16* [[ADDR16]])
207207

208208
// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
209-
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i16(i64 42, i16* [[ADDR16]])
209+
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i16(i64 42, i16* elementtype(i16) [[ADDR16]])
210210

211211
res |= __builtin_arm_strex(42, (int *)addr);
212212
// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
213213
// CHECK: call i32 @llvm.arm.strex.p0i32(i32 42, i32* [[ADDR32]])
214214

215215
// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
216-
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 42, i32* [[ADDR32]])
216+
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 42, i32* elementtype(i32) [[ADDR32]])
217217

218218
res |= __builtin_arm_strex(42, (long long *)addr);
219219
// CHECK: store i64 42, i64* [[TMP:%.*]], align 8
@@ -226,7 +226,7 @@ int test_strex(char *addr) {
226226
// CHECK: call i32 @llvm.arm.strexd(i32 [[LO]], i32 [[HI]], i8* [[TMP5]])
227227

228228
// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
229-
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 42, i64* [[ADDR64]])
229+
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 42, i64* elementtype(i64) [[ADDR64]])
230230

231231
res |= __builtin_arm_strex(2.71828f, (float *)addr);
232232
// CHECK: [[TMP4:%.*]] = bitcast i8* %addr to float*
@@ -235,7 +235,7 @@ int test_strex(char *addr) {
235235

236236
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to float*
237237
// CHECK-ARM64: [[TMP5:%.*]] = bitcast float* [[TMP4]] to i32*
238-
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 1076754509, i32* [[TMP5]])
238+
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 1076754509, i32* elementtype(i32) [[TMP5]])
239239

240240
res |= __builtin_arm_strex(3.14159, (double *)addr);
241241
// CHECK: store double 3.141590e+00, double* [[TMP:%.*]], align 8
@@ -249,7 +249,7 @@ int test_strex(char *addr) {
249249

250250
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to double*
251251
// CHECK-ARM64: [[TMP5:%.*]] = bitcast double* [[TMP4]] to i64*
252-
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 4614256650576692846, i64* [[TMP5]])
252+
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 4614256650576692846, i64* elementtype(i64) [[TMP5]])
253253

254254
res |= __builtin_arm_strex(&var, (struct Simple **)addr);
255255
// CHECK: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple**
@@ -260,7 +260,7 @@ int test_strex(char *addr) {
260260
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple**
261261
// CHECK-ARM64: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i64*
262262
// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint %struct.Simple* %var to i64
263-
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 [[INTVAL]], i64* [[TMP5]])
263+
// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 [[INTVAL]], i64* elementtype(i64) [[TMP5]])
264264

265265
return res;
266266
}
@@ -273,21 +273,21 @@ int test_stlex(char *addr) {
273273
res |= __builtin_arm_stlex(4, addr);
274274
// CHECK: call i32 @llvm.arm.stlex.p0i8(i32 4, i8* %addr)
275275

276-
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i8(i64 4, i8* %addr)
276+
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i8(i64 4, i8* elementtype(i8) %addr)
277277

278278
res |= __builtin_arm_stlex(42, (short *)addr);
279279
// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
280280
// CHECK: call i32 @llvm.arm.stlex.p0i16(i32 42, i16* [[ADDR16]])
281281

282282
// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
283-
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i16(i64 42, i16* [[ADDR16]])
283+
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i16(i64 42, i16* elementtype(i16) [[ADDR16]])
284284

285285
res |= __builtin_arm_stlex(42, (int *)addr);
286286
// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
287287
// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 42, i32* [[ADDR32]])
288288

289289
// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
290-
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 42, i32* [[ADDR32]])
290+
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 42, i32* elementtype(i32) [[ADDR32]])
291291

292292
res |= __builtin_arm_stlex(42, (long long *)addr);
293293
// CHECK: store i64 42, i64* [[TMP:%.*]], align 8
@@ -300,7 +300,7 @@ int test_stlex(char *addr) {
300300
// CHECK: call i32 @llvm.arm.stlexd(i32 [[LO]], i32 [[HI]], i8* [[TMP5]])
301301

302302
// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
303-
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 42, i64* [[ADDR64]])
303+
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 42, i64* elementtype(i64) [[ADDR64]])
304304

305305
res |= __builtin_arm_stlex(2.71828f, (float *)addr);
306306
// CHECK: [[TMP4:%.*]] = bitcast i8* %addr to float*
@@ -309,7 +309,7 @@ int test_stlex(char *addr) {
309309

310310
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to float*
311311
// CHECK-ARM64: [[TMP5:%.*]] = bitcast float* [[TMP4]] to i32*
312-
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 1076754509, i32* [[TMP5]])
312+
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 1076754509, i32* elementtype(i32) [[TMP5]])
313313

314314
res |= __builtin_arm_stlex(3.14159, (double *)addr);
315315
// CHECK: store double 3.141590e+00, double* [[TMP:%.*]], align 8
@@ -323,7 +323,7 @@ int test_stlex(char *addr) {
323323

324324
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to double*
325325
// CHECK-ARM64: [[TMP5:%.*]] = bitcast double* [[TMP4]] to i64*
326-
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 4614256650576692846, i64* [[TMP5]])
326+
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 4614256650576692846, i64* elementtype(i64) [[TMP5]])
327327

328328
res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
329329
// CHECK: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple**
@@ -334,7 +334,7 @@ int test_stlex(char *addr) {
334334
// CHECK-ARM64: [[TMP4:%.*]] = bitcast i8* %addr to %struct.Simple**
335335
// CHECK-ARM64: [[TMP5:%.*]] = bitcast %struct.Simple** [[TMP4]] to i64*
336336
// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint %struct.Simple* %var to i64
337-
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 [[INTVAL]], i64* [[TMP5]])
337+
// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 [[INTVAL]], i64* elementtype(i64) [[TMP5]])
338338

339339
return res;
340340
}

clang/test/CodeGenCXX/builtins-arm-exclusive.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ bool b;
77
// CHECK: call i32 @llvm.arm.ldrex.p0i8(i8* @b)
88

99
// CHECK-ARM64-LABEL: @_Z10test_ldrexv()
10-
// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i8(i8* @b)
10+
// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i8(i8* elementtype(i8) @b)
1111

1212
void test_ldrex() {
1313
b = __builtin_arm_ldrex(&b);
@@ -17,7 +17,7 @@ void test_ldrex() {
1717
// CHECK: %{{.*}} = call i32 @llvm.arm.strex.p0i8(i32 1, i8* @b)
1818

1919
// CHECK-ARM64-LABEL: @_Z10tset_strexv()
20-
// CHECK-ARM64: %{{.*}} = call i32 @llvm.aarch64.stxr.p0i8(i64 1, i8* @b)
20+
// CHECK-ARM64: %{{.*}} = call i32 @llvm.aarch64.stxr.p0i8(i64 1, i8* elementtype(i8) @b)
2121

2222
void tset_strex() {
2323
__builtin_arm_strex(true, &b);

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "llvm/IR/Instruction.h"
5252
#include "llvm/IR/Instructions.h"
5353
#include "llvm/IR/Intrinsics.h"
54+
#include "llvm/IR/IntrinsicsAArch64.h"
5455
#include "llvm/IR/LLVMContext.h"
5556
#include "llvm/IR/Metadata.h"
5657
#include "llvm/IR/Module.h"
@@ -4140,14 +4141,23 @@ Error BitcodeReader::propagateAttributeTypes(CallBase *CB,
41404141
switch (CB->getIntrinsicID()) {
41414142
case Intrinsic::preserve_array_access_index:
41424143
case Intrinsic::preserve_struct_access_index:
4143-
if (!Attrs.getParamElementType(0)) {
4144-
Type *ElTy = getPtrElementTypeByID(ArgTyIDs[0]);
4144+
case Intrinsic::aarch64_ldaxr:
4145+
case Intrinsic::aarch64_ldxr:
4146+
case Intrinsic::aarch64_stlxr:
4147+
case Intrinsic::aarch64_stxr: {
4148+
unsigned ArgNo = CB->getIntrinsicID() == Intrinsic::aarch64_stlxr ||
4149+
CB->getIntrinsicID() == Intrinsic::aarch64_stxr
4150+
? 1
4151+
: 0;
4152+
if (!Attrs.getParamElementType(ArgNo)) {
4153+
Type *ElTy = getPtrElementTypeByID(ArgTyIDs[ArgNo]);
41454154
if (!ElTy)
41464155
return error("Missing element type for elementtype upgrade");
41474156
Attribute NewAttr = Attribute::get(Context, Attribute::ElementType, ElTy);
4148-
Attrs = Attrs.addParamAttribute(Context, 0, NewAttr);
4157+
Attrs = Attrs.addParamAttribute(Context, ArgNo, NewAttr);
41494158
}
41504159
break;
4160+
}
41514161
default:
41524162
break;
41534163
}

0 commit comments

Comments
 (0)