[llvm] [IR] Don't allow label arguments (PR #137799)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 29 06:29:42 PDT 2025
https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/137799
>From a86463295b57c4f93380482df9cfb7254695c78b Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 29 Apr 2025 13:03:45 +0200
Subject: [PATCH 1/2] [IR] Don't allow label arguments
We currently accept label arguments to inline asm calls. Remove
this in favor of callbr, or at least the use of blockaddress.
I didn't bother implementing bitcode upgrade support for this,
as we just have one very old test for this functionality, but I
can add it if desired.
---
llvm/lib/AsmParser/LLParser.cpp | 4 +++-
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 9 ++-------
llvm/lib/IR/Type.cpp | 2 +-
llvm/lib/IR/Verifier.cpp | 2 --
llvm/test/Assembler/invalid-label-call-arg.ll | 9 +++++++++
llvm/test/Assembler/invalid-label.ll | 2 +-
llvm/test/CodeGen/X86/asm-block-labels.ll | 6 +++---
llvm/test/Verifier/invalid-label-param.ll | 6 +-----
8 files changed, 20 insertions(+), 20 deletions(-)
create mode 100644 llvm/test/Assembler/invalid-label-call-arg.ll
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 370d124dc42b4..dd37d9b9e3796 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3072,6 +3072,8 @@ bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
Value *V;
if (parseType(ArgTy, ArgLoc))
return true;
+ if (!FunctionType::isValidArgumentType(ArgTy))
+ return error(ArgLoc, "invalid type for function argument");
AttrBuilder ArgAttrs(M->getContext());
@@ -3381,7 +3383,7 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
CurValID = ArgID + 1;
}
- if (!ArgTy->isFirstClassType())
+ if (!FunctionType::isValidArgumentType(ArgTy))
return error(TypeLoc, "invalid type for function argument");
ArgList.emplace_back(TypeLoc, ArgTy,
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 73bed85c65b3d..5226db9db1e03 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -3488,13 +3488,8 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I,
pushValueAndType(CI.getCalledOperand(), InstID, Vals); // Callee
// Emit value #'s for the fixed parameters.
- for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
- // Check for labels (can happen with asm labels).
- if (FTy->getParamType(i)->isLabelTy())
- Vals.push_back(VE.getValueID(CI.getArgOperand(i)));
- else
- pushValue(CI.getArgOperand(i), InstID, Vals); // fixed param.
- }
+ for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
+ pushValue(CI.getArgOperand(i), InstID, Vals); // fixed param.
// Emit type/value pairs for varargs params.
if (FTy->isVarArg()) {
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 884609e734298..1c68b173364f9 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -390,7 +390,7 @@ bool FunctionType::isValidReturnType(Type *RetTy) {
}
bool FunctionType::isValidArgumentType(Type *ArgTy) {
- return ArgTy->isFirstClassType();
+ return ArgTy->isFirstClassType() && !ArgTy->isLabelTy();
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 262e7022099d7..28ba944d8ede3 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2934,8 +2934,6 @@ void Verifier::visitFunction(const Function &F) {
FT->getParamType(i));
Check(Arg.getType()->isFirstClassType(),
"Function arguments must have first-class types!", &Arg);
- Check(!Arg.getType()->isLabelTy(),
- "Function argument cannot be of label type!", &Arg, &F);
if (!IsIntrinsic) {
Check(!Arg.getType()->isMetadataTy(),
"Function takes metadata but isn't an intrinsic", &Arg, &F);
diff --git a/llvm/test/Assembler/invalid-label-call-arg.ll b/llvm/test/Assembler/invalid-label-call-arg.ll
new file mode 100644
index 0000000000000..575ec6b05e38e
--- /dev/null
+++ b/llvm/test/Assembler/invalid-label-call-arg.ll
@@ -0,0 +1,9 @@
+; RUN: not llvm-as < %s 2>&1 | FileCheck %s
+
+; CHECK: invalid type for function argument
+define void @test() {
+bb:
+ call void asm "", ""(label %bb)
+ ret void
+}
+
diff --git a/llvm/test/Assembler/invalid-label.ll b/llvm/test/Assembler/invalid-label.ll
index 33dc63610aae3..ae464b362135b 100644
--- a/llvm/test/Assembler/invalid-label.ll
+++ b/llvm/test/Assembler/invalid-label.ll
@@ -2,7 +2,7 @@
; RUN: FileCheck %s < %t
; Test the case where an invalid label name is used
-; CHECK: unable to create block named 'bb'
+; CHECK: invalid type for function argument
define void @test(label %bb) {
bb:
diff --git a/llvm/test/CodeGen/X86/asm-block-labels.ll b/llvm/test/CodeGen/X86/asm-block-labels.ll
index 44bb7518ab6ee..fd78c793fa73e 100644
--- a/llvm/test/CodeGen/X86/asm-block-labels.ll
+++ b/llvm/test/CodeGen/X86/asm-block-labels.ll
@@ -13,7 +13,7 @@ entry:
call void asm sideeffect "int $$1", "~{dirflag},~{fpsr},~{flags},~{memory}"( )
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
call void asm sideeffect ".line 2", "~{dirflag},~{fpsr},~{flags}"( )
- call void asm sideeffect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"( label %"LASM$foo" )
+ call void asm sideeffect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"(ptr blockaddress(@bar, %"LASM$foo"))
br label %return
return: ; preds = %"LASM$foo"
@@ -24,7 +24,7 @@ define void @baz() {
entry:
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
call void asm sideeffect ".line 3", "~{dirflag},~{fpsr},~{flags}"( )
- call void asm sideeffect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"( label %"LASM$foo" )
+ call void asm sideeffect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"(ptr blockaddress(@baz, %"LASM$foo"))
call void asm sideeffect ".file \22block12.c\22", "~{dirflag},~{fpsr},~{flags}"( )
call void asm sideeffect ".line 4", "~{dirflag},~{fpsr},~{flags}"( )
call void asm sideeffect "int $$1", "~{dirflag},~{fpsr},~{flags},~{memory}"( )
@@ -42,7 +42,7 @@ return: ; preds = %"LASM$foo"
define void @quux() {
entry:
- call void asm sideeffect inteldialect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"( label %"LASM$foo" )
+ call void asm sideeffect inteldialect "brl ${0:l}", "X,~{dirflag},~{fpsr},~{flags},~{memory}"(ptr blockaddress(@quux, %"LASM$foo"))
br label %"LASM$foo"
"LASM$foo": ; preds = %entry
diff --git a/llvm/test/Verifier/invalid-label-param.ll b/llvm/test/Verifier/invalid-label-param.ll
index c89ce99ce1e9f..92d8b80086dcb 100644
--- a/llvm/test/Verifier/invalid-label-param.ll
+++ b/llvm/test/Verifier/invalid-label-param.ll
@@ -7,8 +7,4 @@ define void @invalid_arg_type(i32 %0) {
}
declare void @foo(label)
-; CHECK: Function argument cannot be of label type!
-; CHECK-NEXT: label %0
-; CHECK-NEXT: ptr @foo
-
-
+; CHECK: invalid type for function argument
>From 901abf075f49ec61193a5a1b97c71f284c95e608 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 29 Apr 2025 15:29:24 +0200
Subject: [PATCH 2/2] Add release note
---
llvm/docs/ReleaseNotes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 9e2e63cffdf82..aded1bd67ed76 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -64,6 +64,7 @@ Changes to the LLVM IR
* Updated semantics of `llvm.type.checked.load.relative` to match that of
`llvm.load.relative`.
+* Inline asm calls no longer accept ``label`` arguments. Use ``callbr`` instead.
Changes to LLVM infrastructure
------------------------------
More information about the llvm-commits
mailing list