[llvm] [AsmParser] Implicitly declare intrinsics (PR #78251)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 16 05:30:07 PST 2024
================
@@ -246,6 +246,34 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
"use of undefined comdat '$" +
ForwardRefComdats.begin()->first + "'");
+ // Automatically create declarations for intrinsics. Intrinsics can only be
+ // called directly, so the call function type directly determines the
+ // declaration function type.
+ for (const auto &[Name, Info] : make_early_inc_range(ForwardRefVals)) {
+ if (!StringRef(Name).starts_with("llvm."))
+ continue;
+
+ // Don't do anything if the intrinsic is called with different function
+ // types. This would result in a verifier error anyway.
+ auto GetCommonFunctionType = [](Value *V) -> FunctionType * {
+ FunctionType *FTy = nullptr;
+ for (User *U : V->users()) {
+ auto *CB = dyn_cast<CallBase>(U);
+ if (!CB || (FTy && FTy != CB->getFunctionType()))
+ return nullptr;
+ FTy = CB->getFunctionType();
+ }
+ return FTy;
+ };
+ if (FunctionType *FTy = GetCommonFunctionType(Info.first)) {
+ Function *Fn =
+ Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
----------------
dtcxzyw wrote:
I'd like to see a test that shows the result of `II->getIntrinsicID()` is correct.
```
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
define i32 @test_canonicalize_fshr_to_fshl(i32 %x) {
%ret = call i32 @llvm.fshr(i32 %x, i32 %x, i32 16)
ret i32 %ret
}
```
Expected output:
```
define i32 @test_canonicalize_fshr_to_fshl(i32 %x) {
%ret = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 16)
ret i32 %ret
}
declare i32 @llvm.fshr.i32(i32, i32, i32)
declare i32 @llvm.fshl.i32(i32, i32, i32)
```
It should be handled by `llvm::UpgradeCallsToIntrinsic`.
https://github.com/llvm/llvm-project/pull/78251
More information about the llvm-commits
mailing list