mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-11 10:26:44 +00:00
[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.
This commit is contained in:
parent
f29002a4b7
commit
d6887256c2
@ -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());
|
||||
|
18
llvm/test/Assembler/struct-ret-without-upgrade.ll
Normal file
18
llvm/test/Assembler/struct-ret-without-upgrade.ll
Normal file
@ -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)
|
Loading…
x
Reference in New Issue
Block a user