Skip to content

Commit 11bf901

Browse files
authored
[AsmParser] Upgrade intrinsics without declaration (llvm#163402)
Usually calls to intrinsics get auto-upgraded if the intrinsic name/signature changes. However, this currently doesn't happen if the intrinsic declaration is omitted, which is the preferred form in new tests. Make sure that intrinsic calls without declaration also get upgraded.
1 parent 778d3c8 commit 11bf901

File tree

4 files changed

+64
-11
lines changed

4 files changed

+64
-11
lines changed

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,6 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
329329
for (const auto &[Name, Info] : make_early_inc_range(ForwardRefVals)) {
330330
if (StringRef(Name).starts_with("llvm.")) {
331331
Intrinsic::ID IID = Intrinsic::lookupIntrinsicID(Name);
332-
if (IID == Intrinsic::not_intrinsic)
333-
// Don't do anything for unknown intrinsics.
334-
continue;
335-
336332
// Automatically create declarations for intrinsics. Intrinsics can only
337333
// be called directly, so the call function type directly determines the
338334
// declaration function type.
@@ -346,11 +342,26 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
346342
return error(Info.second, "intrinsic can only be used as callee");
347343

348344
SmallVector<Type *> OverloadTys;
349-
if (!Intrinsic::getIntrinsicSignature(IID, CB->getFunctionType(),
350-
OverloadTys))
351-
return error(Info.second, "invalid intrinsic signature");
352-
353-
U.set(Intrinsic::getOrInsertDeclaration(M, IID, OverloadTys));
345+
if (IID != Intrinsic::not_intrinsic &&
346+
Intrinsic::getIntrinsicSignature(IID, CB->getFunctionType(),
347+
OverloadTys)) {
348+
U.set(Intrinsic::getOrInsertDeclaration(M, IID, OverloadTys));
349+
} else {
350+
// Try to upgrade the intrinsic.
351+
Function *TmpF = Function::Create(CB->getFunctionType(),
352+
Function::ExternalLinkage, Name, M);
353+
Function *NewF = nullptr;
354+
if (!UpgradeIntrinsicFunction(TmpF, NewF)) {
355+
if (IID == Intrinsic::not_intrinsic)
356+
return error(Info.second, "unknown intrinsic '" + Name + "'");
357+
return error(Info.second, "invalid intrinsic signature");
358+
}
359+
360+
U.set(TmpF);
361+
UpgradeIntrinsicCall(CB, NewF);
362+
if (TmpF->use_empty())
363+
TmpF->eraseFromParent();
364+
}
354365
}
355366

356367
Info.first->eraseFromParent();

llvm/test/Assembler/autoupgrade-lifetime-intrinsics.ll

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,45 @@ define void @remove_unanalyzable(ptr %p) {
5656
ret void
5757
}
5858

59+
define void @no_declaration() {
60+
; CHECK-LABEL: define void @no_declaration() {
61+
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1, addrspace(2)
62+
; CHECK-NEXT: call void @llvm.lifetime.start.p2(ptr addrspace(2) [[A]])
63+
; CHECK-NEXT: call void @llvm.lifetime.end.p2(ptr addrspace(2) [[A]])
64+
; CHECK-NEXT: ret void
65+
;
66+
%a = alloca i8, addrspace(2)
67+
call void @llvm.lifetime.start.p2(i64 1, ptr addrspace(2) %a)
68+
call void @llvm.lifetime.end.p2(i64 1, ptr addrspace(2) %a)
69+
ret void
70+
}
71+
72+
define void @no_suffix1() {
73+
; CHECK-LABEL: define void @no_suffix1() {
74+
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1, addrspace(3)
75+
; CHECK-NEXT: call void @llvm.lifetime.start.p3(ptr addrspace(3) [[A]])
76+
; CHECK-NEXT: call void @llvm.lifetime.end.p3(ptr addrspace(3) [[A]])
77+
; CHECK-NEXT: ret void
78+
;
79+
%a = alloca i8, addrspace(3)
80+
call void @llvm.lifetime.start(i64 1, ptr addrspace(3) %a)
81+
call void @llvm.lifetime.end(i64 1, ptr addrspace(3) %a)
82+
ret void
83+
}
84+
85+
define void @no_suffix2() {
86+
; CHECK-LABEL: define void @no_suffix2() {
87+
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1, addrspace(4)
88+
; CHECK-NEXT: call void @llvm.lifetime.start.p4(ptr addrspace(4) [[A]])
89+
; CHECK-NEXT: call void @llvm.lifetime.end.p4(ptr addrspace(4) [[A]])
90+
; CHECK-NEXT: ret void
91+
;
92+
%a = alloca i8, addrspace(4)
93+
call void @llvm.lifetime.start(i64 1, ptr addrspace(4) %a)
94+
call void @llvm.lifetime.end(i64 1, ptr addrspace(4) %a)
95+
ret void
96+
}
97+
5998
declare void @llvm.lifetime.start.p0(i64, ptr)
6099
declare void @llvm.lifetime.end.p0(i64, ptr)
61100
declare void @llvm.lifetime.start.p1(i64, ptr addrspace(1))

llvm/test/Assembler/autoupgrade-wasm-intrinsics.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ define <4 x float> @test_fms(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
4646
ret <4 x float> %res
4747
}
4848

49-
declare <16 x i8> @llvm.wasm.laneselect.v16i8(<16 x i8>, <16 x i8>, <16 x i8>)
49+
; This declaration is intentionally omitted to check that intrinsic upgrade
50+
; also works without a declaration.
51+
; declare <16 x i8> @llvm.wasm.laneselect.v16i8(<16 x i8>, <16 x i8>, <16 x i8>)
52+
5053
declare <8 x i16> @llvm.wasm.dot.i8x16.i7x16.signed(<16 x i8>, <16 x i8>)
5154
declare <4 x i32> @llvm.wasm.dot.i8x16.i7x16.add.signed(<16 x i8>, <16 x i8>, <4 x i32>)
5255
declare <4 x float> @llvm.wasm.fma.v4f32(<4 x float>, <4 x float>, <4 x float>)

llvm/test/Assembler/implicit-intrinsic-declaration-invalid3.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
; Use of unknown intrinsic without declaration should be rejected.
44

5-
; CHECK: error: use of undefined value '@llvm.foobar'
5+
; CHECK: error: unknown intrinsic 'llvm.foobar'
66
define void @test() {
77
call i8 @llvm.foobar(i8 0, i16 1)
88
ret void

0 commit comments

Comments
 (0)