Skip to content

Commit cc14ecc

Browse files
authored
[InstCombine] Don't change fn signature for calls to declarations (#102596)
transformConstExprCastCall() implements a number of highly dubious transforms attempting to make a call function type line up with the function type of the called function. Historically, the main value this had was to avoid function type mismatches due to pointer type differences, which is no longer relevant with opaque pointers. This patch is a step towards reducing the scope of the transform, by applying it only to definitions, not declarations. For declarations, the declared signature might not match the actual function signature, e.g. `void @fn()` is sometimes used as a placeholder for functions with unknown signature. The implementation already bailed out in some cases for declarations, but I think it would be safer to disable the transform entirely. For the test cases, I've updated some of them to use definitions instead, so that the test coverage is preserved.
1 parent 273e0a4 commit cc14ecc

File tree

5 files changed

+47
-36
lines changed

5 files changed

+47
-36
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4106,6 +4106,12 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
41064106
assert(!isa<CallBrInst>(Call) &&
41074107
"CallBr's don't have a single point after a def to insert at");
41084108

4109+
// Don't perform the transform for declarations, which may not be fully
4110+
// accurate. For example, void @foo() is commonly used as a placeholder for
4111+
// unknown prototypes.
4112+
if (Callee->isDeclaration())
4113+
return false;
4114+
41094115
// If this is a call to a thunk function, don't remove the cast. Thunks are
41104116
// used to transparently forward all incoming parameters and outgoing return
41114117
// values, so it's important to leave the cast in place.
@@ -4142,9 +4148,6 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
41424148
return false; // TODO: Handle multiple return values.
41434149

41444150
if (!CastInst::isBitOrNoopPointerCastable(NewRetTy, OldRetTy, DL)) {
4145-
if (Callee->isDeclaration())
4146-
return false; // Cannot transform this return value.
4147-
41484151
if (!Caller->use_empty())
41494152
return false; // Cannot transform this return value.
41504153
}
@@ -4212,25 +4215,6 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
42124215
return false; // Cannot transform to or from byval.
42134216
}
42144217

4215-
if (Callee->isDeclaration()) {
4216-
// Do not delete arguments unless we have a function body.
4217-
if (FT->getNumParams() < NumActualArgs && !FT->isVarArg())
4218-
return false;
4219-
4220-
// If the callee is just a declaration, don't change the varargsness of the
4221-
// call. We don't want to introduce a varargs call where one doesn't
4222-
// already exist.
4223-
if (FT->isVarArg() != Call.getFunctionType()->isVarArg())
4224-
return false;
4225-
4226-
// If both the callee and the cast type are varargs, we still have to make
4227-
// sure the number of fixed parameters are the same or we have the same
4228-
// ABI issues as if we introduce a varargs call.
4229-
if (FT->isVarArg() && Call.getFunctionType()->isVarArg() &&
4230-
FT->getNumParams() != Call.getFunctionType()->getNumParams())
4231-
return false;
4232-
}
4233-
42344218
if (FT->getNumParams() < NumActualArgs && FT->isVarArg() &&
42354219
!CallerPAL.isEmpty()) {
42364220
// In this case we have more arguments than the new function type, but we

llvm/test/Transforms/InstCombine/apint-call-cast-target.ll

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,19 @@
44
target datalayout = "e-p:32:32"
55
target triple = "i686-pc-linux-gnu"
66

7-
declare i32 @main2()
8-
declare ptr @ctime2(ptr)
7+
define i32 @main2() {
8+
; CHECK-LABEL: @main2(
9+
; CHECK-NEXT: ret i32 0
10+
;
11+
ret i32 0
12+
}
13+
14+
define ptr @ctime2(ptr %p) {
15+
; CHECK-LABEL: @ctime2(
16+
; CHECK-NEXT: ret ptr [[P:%.*]]
17+
;
18+
ret ptr %p
19+
}
920

1021
define ptr @ctime(ptr) {
1122
; CHECK-LABEL: @ctime(

llvm/test/Transforms/InstCombine/call-cast-target.ll

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ entry:
1616
ret i32 %tmp
1717
}
1818

19-
declare ptr @ctime(ptr)
19+
define ptr @ctime(ptr %p) {
20+
; CHECK-LABEL: define ptr @ctime(
21+
; CHECK-SAME: ptr [[P:%.*]]) {
22+
; CHECK-NEXT: ret ptr [[P]]
23+
;
24+
ret ptr %p
25+
}
2026

2127
define internal { i8 } @foo(ptr) {
2228
; CHECK-LABEL: define internal { i8 } @foo(
@@ -39,7 +45,13 @@ entry:
3945
ret void
4046
}
4147

42-
declare i32 @fn1(i32)
48+
define i32 @fn1(i32 %x) {
49+
; CHECK-LABEL: define i32 @fn1(
50+
; CHECK-SAME: i32 [[X:%.*]]) {
51+
; CHECK-NEXT: ret i32 [[X]]
52+
;
53+
ret i32 %x
54+
}
4355

4456
define i32 @test1(ptr %a) {
4557
; CHECK-LABEL: define i32 @test1(
@@ -116,7 +128,13 @@ define i1 @test5() {
116128
ret i1 %6
117129
}
118130

119-
declare void @bundles_callee(i32)
131+
define void @bundles_callee(i32) {
132+
; CHECK-LABEL: define void @bundles_callee(
133+
; CHECK-SAME: i32 [[TMP0:%.*]]) {
134+
; CHECK-NEXT: ret void
135+
;
136+
ret void
137+
}
120138

121139
define void @bundles() {
122140
; CHECK-LABEL: define void @bundles() {

llvm/test/Transforms/InstCombine/call.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ declare i32 @test6a(i32)
110110

111111
define i32 @test6() {
112112
; CHECK-LABEL: define i32 @test6() {
113-
; CHECK-NEXT: [[X:%.*]] = call i32 @test6a(i32 0)
113+
; CHECK-NEXT: [[X:%.*]] = call i32 @test6a()
114114
; CHECK-NEXT: ret i32 [[X]]
115115
;
116116
%X = call i32 @test6a( )
@@ -141,12 +141,12 @@ declare void @test8a()
141141
define ptr @test8() personality ptr @__gxx_personality_v0 {
142142
; CHECK-LABEL: define ptr @test8() personality ptr @__gxx_personality_v0 {
143143
; CHECK-NEXT: invoke void @test8a()
144-
; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TRY_HANDLER:%.*]]
144+
; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TRY_HANDLER:%.*]]
145145
; CHECK: invoke.cont:
146146
; CHECK-NEXT: unreachable
147147
; CHECK: try.handler:
148148
; CHECK-NEXT: [[EXN:%.*]] = landingpad { ptr, i32 }
149-
; CHECK-NEXT: cleanup
149+
; CHECK-NEXT: cleanup
150150
; CHECK-NEXT: ret ptr null
151151
;
152152
; Don't turn this into "unreachable": the callee and caller don't agree in

llvm/test/Transforms/InstCombine/opaque-ptr.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,8 +743,7 @@ declare void @call_byval(i64, ptr byval(i64))
743743

744744
define void @call_cast_ptr_to_int(ptr %p) {
745745
; CHECK-LABEL: @call_cast_ptr_to_int(
746-
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i64
747-
; CHECK-NEXT: call void @call_i64(i64 [[TMP1]])
746+
; CHECK-NEXT: call void @call_i64(ptr [[P:%.*]])
748747
; CHECK-NEXT: ret void
749748
;
750749
call void @call_i64(ptr %p)
@@ -753,8 +752,7 @@ define void @call_cast_ptr_to_int(ptr %p) {
753752

754753
define void @call_cast_byval(ptr %p, ptr %p2) {
755754
; CHECK-LABEL: @call_cast_byval(
756-
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i64
757-
; CHECK-NEXT: call void @call_byval(i64 [[TMP1]], ptr byval(double) [[P2:%.*]])
755+
; CHECK-NEXT: call void @call_byval(ptr [[P:%.*]], ptr byval(double) [[P2:%.*]])
758756
; CHECK-NEXT: ret void
759757
;
760758
call void @call_byval(ptr %p, ptr byval(double) %p2)
@@ -765,8 +763,8 @@ declare float @fmodf(float, float)
765763

766764
define i32 @const_fold_call_with_func_type_mismatch() {
767765
; CHECK-LABEL: @const_fold_call_with_func_type_mismatch(
768-
; CHECK-NEXT: [[V:%.*]] = call float @fmodf(float 0x40091EB860000000, float 2.000000e+00)
769-
; CHECK-NEXT: ret i32 1066527622
766+
; CHECK-NEXT: [[V:%.*]] = call i32 @fmodf(float 0x40091EB860000000, float 2.000000e+00)
767+
; CHECK-NEXT: ret i32 [[V]]
770768
;
771769
%v = call i32 @fmodf(float 0x40091EB860000000, float 2.000000e+00)
772770
ret i32 %v

0 commit comments

Comments
 (0)