diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -1082,13 +1082,30 @@ // If all else fails, try to materialize the value in a register. if (!AM.GV || !Subtarget->isPICStyleRIPRel()) { + auto GetCallRegForValue = [this](const Value *V) { + auto Reg = getRegForValue(V); + + // In 64-bit mode, we need a 64-bit register even if pointers are 32 bits. + if (Reg && Subtarget->isTarget64BitILP32()) { + auto ExtReg = createResultReg(&X86::GR64RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::SUBREG_TO_REG), ExtReg) + .addImm(0) + .addReg(Reg) + .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; } }