[llvm] d688725 - [AutoUpgrade] Don't upgrade intrinsics returning overloaded struct type
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 30 08:27:33 PDT 2022
Author: Nikita Popov
Date: 2022-03-30T17:27:26+02:00
New Revision: d6887256c2cae1b1b721bd47459be6d86003db6f
URL: https://github.com/llvm/llvm-project/commit/d6887256c2cae1b1b721bd47459be6d86003db6f
DIFF: https://github.com/llvm/llvm-project/commit/d6887256c2cae1b1b721bd47459be6d86003db6f.diff
LOG: [AutoUpgrade] Don't upgrade intrinsics returning overloaded struct type
We only want to do the upgrade from named to anonymous struct
return if the intrinsic is declared to return a struct, but not
if it has an overloaded return type that just happens to be a
struct. In that case the struct type will be mangled into the
intrinsic name and there is no problem.
This should address the problem reported in
https://reviews.llvm.org/D122471#3416598.
Added:
llvm/test/Assembler/struct-ret-without-upgrade.ll
Modified:
llvm/lib/IR/AutoUpgrade.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index bf52b098d8d88..8aaf5e67256eb 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -1005,9 +1005,15 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
return true;
}
- if (auto *ST = dyn_cast<StructType>(F->getReturnType())) {
- if (!ST->isLiteral() || ST->isPacked()) {
- // Replace return type with literal non-packed struct.
+ auto *ST = dyn_cast<StructType>(F->getReturnType());
+ if (ST && (!ST->isLiteral() || ST->isPacked())) {
+ // Replace return type with literal non-packed struct. Only do this for
+ // intrinsics declared to return a struct, not for intrinsics with
+ // overloaded return type, in which case the exact struct type will be
+ // mangled into the name.
+ SmallVector<Intrinsic::IITDescriptor> Desc;
+ Intrinsic::getIntrinsicInfoTableEntries(F->getIntrinsicID(), Desc);
+ if (Desc.front().Kind == Intrinsic::IITDescriptor::Struct) {
auto *FT = F->getFunctionType();
auto *NewST = StructType::get(ST->getContext(), ST->elements());
auto *NewFT = FunctionType::get(NewST, FT->params(), FT->isVarArg());
diff --git a/llvm/test/Assembler/struct-ret-without-upgrade.ll b/llvm/test/Assembler/struct-ret-without-upgrade.ll
new file mode 100644
index 0000000000000..992b2f9f767fa
--- /dev/null
+++ b/llvm/test/Assembler/struct-ret-without-upgrade.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S < %s | FileCheck %s
+
+; This is an overloaded struct return, we should not try to update it to an
+; anonymous struct return.
+
+%ty = type { i32 }
+
+define %ty @test(%ty %arg) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: [[COPY:%.*]] = call [[TY:%.*]] @llvm.ssa.copy.s_tys([[TY]] [[ARG:%.*]])
+; CHECK-NEXT: ret [[TY]] [[COPY]]
+;
+ %copy = call %ty @llvm.ssa.copy.s_tys(%ty %arg)
+ ret %ty %copy
+}
+
+declare %ty @llvm.ssa.copy.s_tys(%ty)
More information about the llvm-commits
mailing list