Skip to content

Commit b361d3b

Browse files
committed
[MergeFuncs] Remove incorrect attribute copying
Fix for https://bugs.llvm.org/show_bug.cgi?id=44236. This code was originally introduced in rG36512330041201e10f5429361bbd79b1afac1ea1. However, the attribute copying was done in the wrong place (in general call replacement, not thunk generation) and a proper fix was implemented in D12581. Previously this code was just unnecessary but harmless (because FunctionComparator ensured that the attributes of the two functions are exactly the same), but since byval was changed to accept a type this copying is actively wrong and may result in malformed IR. Differential Revision: https://reviews.llvm.org/D71173
1 parent 25e21a0 commit b361d3b

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

llvm/lib/Transforms/IPO/MergeFunctions.cpp

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -450,28 +450,10 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {
450450
++UI;
451451
CallSite CS(U->getUser());
452452
if (CS && CS.isCallee(U)) {
453-
// Transfer the called function's attributes to the call site. Due to the
454-
// bitcast we will 'lose' ABI changing attributes because the 'called
455-
// function' is no longer a Function* but the bitcast. Code that looks up
456-
// the attributes from the called function will fail.
457-
458-
// FIXME: This is not actually true, at least not anymore. The callsite
459-
// will always have the same ABI affecting attributes as the callee,
460-
// because otherwise the original input has UB. Note that Old and New
461-
// always have matching ABI, so no attributes need to be changed.
462-
// Transferring other attributes may help other optimizations, but that
463-
// should be done uniformly and not in this ad-hoc way.
464-
auto &Context = New->getContext();
465-
auto NewPAL = New->getAttributes();
466-
SmallVector<AttributeSet, 4> NewArgAttrs;
467-
for (unsigned argIdx = 0; argIdx < CS.arg_size(); argIdx++)
468-
NewArgAttrs.push_back(NewPAL.getParamAttributes(argIdx));
469-
// Don't transfer attributes from the function to the callee. Function
470-
// attributes typically aren't relevant to the calling convention or ABI.
471-
CS.setAttributes(AttributeList::get(Context, /*FnAttrs=*/AttributeSet(),
472-
NewPAL.getRetAttributes(),
473-
NewArgAttrs));
474-
453+
// Do not copy attributes from the called function to the call-site.
454+
// Function comparison ensures that the attributes are the same up to
455+
// type congruences in byval(), in which case we need to keep the byval
456+
// type of the call-site, not the callee function.
475457
remove(CS.getInstruction()->getFunction());
476458
U->set(BitcastNew);
477459
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -S -mergefunc %s | FileCheck %s
3+
4+
%struct.c = type { i32 }
5+
%struct.a = type { i32 }
6+
7+
@d = external dso_local global %struct.c
8+
9+
define void @e(%struct.a* byval(%struct.a) %f) {
10+
; CHECK-LABEL: @e(
11+
; CHECK-NEXT: ret void
12+
;
13+
ret void
14+
}
15+
16+
define void @g(%struct.c* byval(%struct.c) %f) {
17+
; CHECK-LABEL: @g(
18+
; CHECK-NEXT: ret void
19+
;
20+
ret void
21+
}
22+
23+
define void @h() {
24+
; CHECK-LABEL: @h(
25+
; CHECK-NEXT: call void bitcast (void (%struct.a*)* @e to void (%struct.c*)*)(%struct.c* byval(%struct.c) @d)
26+
; CHECK-NEXT: ret void
27+
;
28+
call void @g(%struct.c* byval(%struct.c) @d)
29+
ret void
30+
}

0 commit comments

Comments
 (0)