[PATCH] D45186: [InstCombine] Don't strip function type casts from musttail calls
Reid Kleckner via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 2 15:34:41 PDT 2018
rnk updated this revision to Diff 140698.
rnk added a comment.
Herald added a subscriber: delcypher.
- this isn't about thunks
https://reviews.llvm.org/D45186
Files:
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/musttail-thunk.ll
llvm/utils/lit/lit/TestRunner.py
Index: llvm/utils/lit/lit/TestRunner.py
===================================================================
--- llvm/utils/lit/lit/TestRunner.py
+++ llvm/utils/lit/lit/TestRunner.py
@@ -12,6 +12,7 @@
import tempfile
import threading
+import io
try:
from StringIO import StringIO
except ImportError:
@@ -388,6 +389,8 @@
def compareTwoFiles(filepaths):
filelines = []
for file in filepaths:
+ compare_bytes = False
+ encoding = None
try:
with open(file, 'r') as f:
filelines.append(f.readlines())
Index: llvm/test/Transforms/InstCombine/musttail-thunk.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/musttail-thunk.ll
@@ -0,0 +1,32 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+; These are both direct calls, but make sure instcombine leaves the casts
+; alone.
+
+define i32 @call_thunk(i32 %x, i32 %y) {
+ %r = call i32 bitcast (void (i32, ...)* @inc_first_arg_thunk to i32 (i32, i32)*)(i32 %x, i32 %y)
+ ret i32 %r
+}
+
+; CHECK-LABEL: define i32 @call_thunk(i32 %x, i32 %y)
+; CHECK: %r = call i32 bitcast (void (i32, ...)* @inc_first_arg_thunk to i32 (i32, i32)*)(i32 %x, i32 %y)
+; CHECK: ret i32 %r
+
+define internal void @inc_first_arg_thunk(i32 %arg1, ...) #0 {
+entry:
+ %inc = add i32 %arg1, 1
+ musttail call void (i32, ...) bitcast (i32 (i32, i32)* @plus to void (i32, ...)*)(i32 %inc, ...)
+ ret void
+}
+
+; CHECK-LABEL: define internal void @inc_first_arg_thunk(i32 %arg1, ...) #0
+; CHECK: %inc = add i32 %arg1, 1
+; CHECK: musttail call void (i32, ...) bitcast (i32 (i32, i32)* @plus to void (i32, ...)*)(i32 %inc, ...)
+; CHECK: ret void
+
+define internal i32 @plus(i32 %x, i32 %y) {
+ %r = add i32 %x, %y
+ ret i32 %r
+}
+
+attributes #0 = { "thunk" }
Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3996,11 +3996,22 @@
if (!Callee)
return false;
- // The prototype of a thunk is a lie. Don't directly call such a function.
+ // If this is a call to a thunk function, don't remove the cast. Thunks are
+ // used to transparently forward all incoming parameters and outgoing return
+ // values, so it's important to leave the cast in place.
if (Callee->hasFnAttribute("thunk"))
return false;
Instruction *Caller = CS.getInstruction();
+
+ // If this is a musttail call, the callee's prototype must match the caller's
+ // prototype with the exception of pointee types. The code below doesn't
+ // implement that, so we can't do this transform.
+ // TODO: Do the transform if it only requires adding pointer casts.
+ CallInst *CI = dyn_cast<CallInst>(Caller);
+ if (CI && CI->isMustTailCall())
+ return false;
+
const AttributeList &CallerPAL = CS.getAttributes();
// Okay, this is a cast from a function to a different type. Unless doing so
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45186.140698.patch
Type: text/x-patch
Size: 3109 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180402/e0960631/attachment.bin>
More information about the llvm-commits
mailing list