diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index ac18e348dc9..80f9769b6f5 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -93,13 +93,14 @@ static unsigned getANDriOpcode(bool IsLP64, int64_t Imm) { return X86::AND32ri; } -static unsigned getPUSHiOpcode(bool IsLP64, int64_t Imm) { +static unsigned getPUSHiOpcode(bool IsLP64, MachineOperand MO) { // We don't support LP64 for now. assert(!IsLP64); - if (isInt<8>(Imm)) + if (MO.isImm() && isInt<8>(MO.getImm())) return X86::PUSH32i8; - return X86::PUSHi32; + + return X86::PUSHi32;; } static unsigned getLEArOpcode(unsigned IsLP64) { @@ -1892,14 +1893,13 @@ convertArgMovsToPushes(MachineFunction &MF, MachineBasicBlock &MBB, for (auto MMI = MovMap.rbegin(), MME = MovMap.rend(); MMI != MME; ++MMI) { MachineBasicBlock::iterator MOV = MMI->second; MachineOperand PushOp = MOV->getOperand(X86::AddrNumOperands); - if (MOV->getOpcode() == X86::MOV32mi) { - int64_t Val = PushOp.getImm(); - BuildMI(MBB, Call, DL, TII.get(getPUSHiOpcode(false, Val))) - .addImm(Val); - } else { - BuildMI(MBB, Call, DL, TII.get(X86::PUSH32r)) - .addReg(PushOp.getReg()); - } + + // Replace MOVmr with PUSH32r, and MOVmi with PUSHi of appropriate size + int PushOpcode = X86::PUSH32r; + if (MOV->getOpcode() == X86::MOV32mi) + PushOpcode = getPUSHiOpcode(false, PushOp); + + BuildMI(MBB, Call, DL, TII.get(PushOpcode)).addOperand(PushOp); MBB.erase(MOV); } diff --git a/test/CodeGen/X86/movtopush.ll b/test/CodeGen/X86/movtopush.ll index 6a848b7dc91..4db1372f948 100644 --- a/test/CodeGen/X86/movtopush.ll +++ b/test/CodeGen/X86/movtopush.ll @@ -94,4 +94,19 @@ entry: ret void } +; Check that pushing the addresses of globals (Or generally, things that +; aren't exactly immediates) isn't broken. +; Fixes PR21878. +; NORMAL-LABEL: test6 +; NORMAL: pushl $_ext +; NORMAL-NEXT: call +declare void @f(i8*) +@ext = external constant i8 +define void @test6() { + call void @f(i8* @ext) + br label %bb +bb: + alloca i32 + ret void +} \ No newline at end of file