From 153e4b0f11f4d484d6e3c6b73235b1c387230b9b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 3 Mar 2016 02:06:32 +0000 Subject: [PATCH] [X86] Enable forwarding bool arguments in tail calls (PR26305) The code was previously not able to track a boolean argument at a call site back to the formal argument of the caller. Differential Revision: http://reviews.llvm.org/D17786 llvm-svn: 262575 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 20 ++++++++++++++++++ llvm/test/CodeGen/X86/tail-call-casts.ll | 27 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 llvm/test/CodeGen/X86/tail-call-casts.ll diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index b2e201104219b..3b45544730e25 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3645,6 +3645,26 @@ bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags, MachineFrameInfo *MFI, const MachineRegisterInfo *MRI, const X86InstrInfo *TII, const CCValAssign &VA) { unsigned Bytes = Arg.getValueType().getSizeInBits() / 8; + + for (;;) { + // Look through nodes that don't alter the bits of the incoming value. + unsigned Op = Arg.getOpcode(); + if (Op == ISD::ZERO_EXTEND || Op == ISD::ANY_EXTEND || Op == ISD::BITCAST) { + Arg = Arg.getOperand(0); + continue; + } + if (Op == ISD::TRUNCATE) { + const SDValue &TruncInput = Arg.getOperand(0); + if (TruncInput.getOpcode() == ISD::AssertZext && + cast(TruncInput.getOperand(1))->getVT() == + Arg.getValueType()) { + Arg = TruncInput.getOperand(0); + continue; + } + } + break; + } + int FI = INT_MAX; if (Arg.getOpcode() == ISD::CopyFromReg) { unsigned VR = cast(Arg.getOperand(1))->getReg(); diff --git a/llvm/test/CodeGen/X86/tail-call-casts.ll b/llvm/test/CodeGen/X86/tail-call-casts.ll new file mode 100644 index 0000000000000..5421b498e1ea2 --- /dev/null +++ b/llvm/test/CodeGen/X86/tail-call-casts.ll @@ -0,0 +1,27 @@ +; RUN: llc -mtriple=i686-unknown-linux-gnu -o - %s | FileCheck %s + +declare void @g_bool(i1 zeroext) +define void @f_bool(i1 zeroext %x) { +entry: + tail call void @g_bool(i1 zeroext %x) + ret void + +; Forwarding a bool in a tail call works. +; CHECK-LABEL: f_bool: +; CHECK-NOT: movz +; CHECK: jmp g_bool +} + + +declare void @g_float(float) +define void @f_i32(i32 %x) { +entry: + %0 = bitcast i32 %x to float + tail call void @g_float(float %0) + ret void + +; Forwarding a bitcasted value works too. +; CHECK-LABEL: f_i32 +; CHECK-NOT: mov +; CHECK: jmp g_float +}