From: Harald van Dijk Date: Sat, 28 Nov 2020 16:46:30 +0000 (+0000) Subject: [X86] Have indirect calls take 64-bit operands in 64-bit modes X-Git-Tag: llvmorg-13-init~4940 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=47c902ba8479fc1faed73b86f59d58830df06644;p=platform%2Fupstream%2Fllvm.git [X86] Have indirect calls take 64-bit operands in 64-bit modes The build bots caught two additional pre-existing problems exposed by the test change part of my change https://reviews.llvm.org/D91339, when expensive checks are enabled. This fixes one of them. X86 has CALL64r and CALL32r opcodes, where CALL64r takes a 64-bit register, and CALL32r takes a 32-bit register. CALL64r can only be used in 64-bit mode, CALL32r can only be used in 32-bit mode. LLVM would assume that after picking the appropriate CALLr opcode, a pointer-sized register would be a valid operand, but in x32 mode, a 64-bit mode, pointers are 32 bits. In this mode, it is invalid to directly pass a pointer to CALL64r, it needs to be extended to 64 bits first. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D91924 --- diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index 15b04c0..a8db3d4 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -1082,13 +1082,35 @@ bool X86FastISel::X86SelectCallAddress(const Value *V, X86AddressMode &AM) { // If all else fails, try to materialize the value in a register. if (!AM.GV || !Subtarget->isPICStyleRIPRel()) { + auto GetCallRegForValue = [this](const Value *V) { + Register Reg = getRegForValue(V); + + // In 64-bit mode, we need a 64-bit register even if pointers are 32 bits. + if (Reg && Subtarget->isTarget64BitILP32()) { + Register CopyReg = createResultReg(&X86::GR32RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV32rr), + CopyReg) + .addReg(Reg); + + Register ExtReg = createResultReg(&X86::GR64RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg) + .addImm(0) + .addReg(CopyReg) + .addImm(X86::sub_32bit); + Reg = ExtReg; + } + + return Reg; + }; + if (AM.Base.Reg == 0) { - AM.Base.Reg = getRegForValue(V); + AM.Base.Reg = GetCallRegForValue(V); return AM.Base.Reg != 0; } if (AM.IndexReg == 0) { assert(AM.Scale == 1 && "Scale with no index!"); - AM.IndexReg = getRegForValue(V); + AM.IndexReg = GetCallRegForValue(V); return AM.IndexReg != 0; } }