Skip to content

Commit b4d3283

Browse files
authored
AArch64: Add libcall impl declarations for __arm_sc* memory functions (#144977)
These were bypassing the ordinary libcall emission mechanism. Make sure we have entries in RuntimeLibcalls, which should include all possible calls the compiler could emit. Fixes not emitting the # prefix in the arm64ec case.
1 parent 779f724 commit b4d3283

File tree

4 files changed

+29
-15
lines changed

4 files changed

+29
-15
lines changed

llvm/include/llvm/IR/RuntimeLibcalls.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ multiclass LibmLongDoubleLibCall<string libcall_basename = !toupper(NAME),
357357
!strconcat(rtbasename, "l")>;
358358
}
359359

360+
// AArch64 calls
361+
def SC_MEMCPY : RuntimeLibcall;
362+
def SC_MEMMOVE : RuntimeLibcall;
363+
def SC_MEMSET : RuntimeLibcall;
364+
360365
// ARM EABI calls
361366
def AEABI_MEMCPY4 : RuntimeLibcall; // Align 4
362367
def AEABI_MEMCPY8 : RuntimeLibcall; // Align 8
@@ -985,6 +990,10 @@ defset list<RuntimeLibcallImpl> AArch64LibcallImpls = {
985990
defm __aarch64_ldeor#MemSize
986991
: AtomicOrderSizeLibcallImpl<"OUTLINE_ATOMIC_LDEOR"#MemSize>;
987992
}
993+
994+
def __arm_sc_memcpy : RuntimeLibcallImpl<SC_MEMCPY>;
995+
def __arm_sc_memmove : RuntimeLibcallImpl<SC_MEMMOVE>;
996+
def __arm_sc_memset : RuntimeLibcallImpl<SC_MEMSET>;
988997
}
989998

990999
foreach libcall = AArch64LibcallImpls in {

llvm/lib/IR/RuntimeLibcalls.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,17 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
489489
}
490490

491491
if (TT.isAArch64()) {
492-
if (TT.isWindowsArm64EC())
492+
if (TT.isWindowsArm64EC()) {
493493
setWindowsArm64LibCallNameOverrides();
494+
setLibcallImpl(RTLIB::SC_MEMCPY, RTLIB::arm64ec___arm_sc_memcpy);
495+
setLibcallImpl(RTLIB::SC_MEMMOVE, RTLIB::arm64ec___arm_sc_memmove);
496+
setLibcallImpl(RTLIB::SC_MEMSET, RTLIB::arm64ec___arm_sc_memset);
497+
} else {
498+
setLibcallImpl(RTLIB::SC_MEMCPY, RTLIB::__arm_sc_memcpy);
499+
setLibcallImpl(RTLIB::SC_MEMMOVE, RTLIB::__arm_sc_memmove);
500+
setLibcallImpl(RTLIB::SC_MEMSET, RTLIB::__arm_sc_memset);
501+
}
502+
494503
setAArch64LibcallNames(*this, TT);
495504
} else if (TT.isARM() || TT.isThumb()) {
496505
setARMLibcallNames(*this, TT, FloatABI, EABIVersion);

llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,35 +164,34 @@ SDValue AArch64SelectionDAGInfo::EmitStreamingCompatibleMemLibCall(
164164
const AArch64Subtarget &STI =
165165
DAG.getMachineFunction().getSubtarget<AArch64Subtarget>();
166166
const AArch64TargetLowering *TLI = STI.getTargetLowering();
167-
SDValue Symbol;
168167
TargetLowering::ArgListEntry DstEntry;
169168
DstEntry.Ty = PointerType::getUnqual(*DAG.getContext());
170169
DstEntry.Node = Dst;
171170
TargetLowering::ArgListTy Args;
172171
Args.push_back(DstEntry);
173-
EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
174172

173+
RTLIB::Libcall NewLC;
175174
switch (LC) {
176175
case RTLIB::MEMCPY: {
176+
NewLC = RTLIB::SC_MEMCPY;
177177
TargetLowering::ArgListEntry Entry;
178178
Entry.Ty = PointerType::getUnqual(*DAG.getContext());
179-
Symbol = DAG.getExternalSymbol("__arm_sc_memcpy", PointerVT);
180179
Entry.Node = Src;
181180
Args.push_back(Entry);
182181
break;
183182
}
184183
case RTLIB::MEMMOVE: {
184+
NewLC = RTLIB::SC_MEMMOVE;
185185
TargetLowering::ArgListEntry Entry;
186186
Entry.Ty = PointerType::getUnqual(*DAG.getContext());
187-
Symbol = DAG.getExternalSymbol("__arm_sc_memmove", PointerVT);
188187
Entry.Node = Src;
189188
Args.push_back(Entry);
190189
break;
191190
}
192191
case RTLIB::MEMSET: {
192+
NewLC = RTLIB::SC_MEMSET;
193193
TargetLowering::ArgListEntry Entry;
194194
Entry.Ty = Type::getInt32Ty(*DAG.getContext());
195-
Symbol = DAG.getExternalSymbol("__arm_sc_memset", PointerVT);
196195
Src = DAG.getZExtOrTrunc(Src, DL, MVT::i32);
197196
Entry.Node = Src;
198197
Args.push_back(Entry);
@@ -202,17 +201,17 @@ SDValue AArch64SelectionDAGInfo::EmitStreamingCompatibleMemLibCall(
202201
return SDValue();
203202
}
204203

204+
EVT PointerVT = TLI->getPointerTy(DAG.getDataLayout());
205+
SDValue Symbol = DAG.getExternalSymbol(TLI->getLibcallName(NewLC), PointerVT);
205206
TargetLowering::ArgListEntry SizeEntry;
206207
SizeEntry.Node = Size;
207208
SizeEntry.Ty = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
208209
Args.push_back(SizeEntry);
209-
assert(Symbol->getOpcode() == ISD::ExternalSymbol &&
210-
"Function name is not set");
211210

212211
TargetLowering::CallLoweringInfo CLI(DAG);
213212
PointerType *RetTy = PointerType::getUnqual(*DAG.getContext());
214213
CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
215-
TLI->getLibcallCallingConv(LC), RetTy, Symbol, std::move(Args));
214+
TLI->getLibcallCallingConv(NewLC), RetTy, Symbol, std::move(Args));
216215
return TLI->LowerCallTo(CLI).second;
217216
}
218217

llvm/test/CodeGen/AArch64/arm64ec-builtins.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,27 +46,24 @@ define float @f6(float %val, i32 %a) {
4646
@dst = global [512 x i8] zeroinitializer, align 1
4747
@src = global [512 x i8] zeroinitializer, align 1
4848

49-
; FIXME: Wrong and probably needs a # prefix
5049
define void @call__arm_sc_memcpy(i64 noundef %n) #0 {
5150
; CHECK-LABEL: "#call__arm_sc_memcpy":
52-
; CHECK: bl __arm_sc_memcpy
51+
; CHECK: bl "#__arm_sc_memcpy"
5352

5453
tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 @dst, ptr nonnull align 1 @src, i64 %n, i1 false)
5554
ret void
5655
}
5756

58-
; FIXME: Wrong and probably needs a # prefix
5957
define void @call__arm_sc_memmove(i64 noundef %n) #0 {
6058
; CHECK-LABEL: "#call__arm_sc_memmove":
61-
; CHECK: bl __arm_sc_memmove
59+
; CHECK: bl "#__arm_sc_memmove"
6260
tail call void @llvm.memmove.p0.p0.i64(ptr align 1 @dst, ptr nonnull align 1 @src, i64 %n, i1 false)
6361
ret void
6462
}
6563

66-
; FIXME: Wrong and probably needs a # prefix
6764
define void @call__arm_sc_memset(i64 noundef %n) #0 {
6865
; CHECK-LABEL: "#call__arm_sc_memset":
69-
; CHECK: bl __arm_sc_memset
66+
; CHECK: bl "#__arm_sc_memset"
7067
tail call void @llvm.memset.p0.i64(ptr align 1 @dst, i8 2, i64 %n, i1 false)
7168
ret void
7269
}

0 commit comments

Comments
 (0)