Skip to content

Commit d688725

Browse files
committed
[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.
1 parent f29002a commit d688725

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,9 +1005,15 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
10051005
return true;
10061006
}
10071007

1008-
if (auto *ST = dyn_cast<StructType>(F->getReturnType())) {
1009-
if (!ST->isLiteral() || ST->isPacked()) {
1010-
// Replace return type with literal non-packed struct.
1008+
auto *ST = dyn_cast<StructType>(F->getReturnType());
1009+
if (ST && (!ST->isLiteral() || ST->isPacked())) {
1010+
// Replace return type with literal non-packed struct. Only do this for
1011+
// intrinsics declared to return a struct, not for intrinsics with
1012+
// overloaded return type, in which case the exact struct type will be
1013+
// mangled into the name.
1014+
SmallVector<Intrinsic::IITDescriptor> Desc;
1015+
Intrinsic::getIntrinsicInfoTableEntries(F->getIntrinsicID(), Desc);
1016+
if (Desc.front().Kind == Intrinsic::IITDescriptor::Struct) {
10111017
auto *FT = F->getFunctionType();
10121018
auto *NewST = StructType::get(ST->getContext(), ST->elements());
10131019
auto *NewFT = FunctionType::get(NewST, FT->params(), FT->isVarArg());
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -S < %s | FileCheck %s
3+
4+
; This is an overloaded struct return, we should not try to update it to an
5+
; anonymous struct return.
6+
7+
%ty = type { i32 }
8+
9+
define %ty @test(%ty %arg) {
10+
; CHECK-LABEL: @test(
11+
; CHECK-NEXT: [[COPY:%.*]] = call [[TY:%.*]] @llvm.ssa.copy.s_tys([[TY]] [[ARG:%.*]])
12+
; CHECK-NEXT: ret [[TY]] [[COPY]]
13+
;
14+
%copy = call %ty @llvm.ssa.copy.s_tys(%ty %arg)
15+
ret %ty %copy
16+
}
17+
18+
declare %ty @llvm.ssa.copy.s_tys(%ty)

0 commit comments

Comments
 (0)