[X86] When converting movs to pushes, don't assume MOVmi operand is an actual immediate
authorMichael Kuperstein <michael.m.kuperstein@intel.com>
Thu, 11 Dec 2014 11:26:16 +0000 (11:26 +0000)
committerMichael Kuperstein <michael.m.kuperstein@intel.com>
Thu, 11 Dec 2014 11:26:16 +0000 (11:26 +0000)
This should fix PR21878.

llvm-svn: 224010

llvm/lib/Target/X86/X86FrameLowering.cpp
llvm/test/CodeGen/X86/movtopush.ll

index ac18e34..80f9769 100644 (file)
@@ -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);
   }
 
index 6a848b7..4db1372 100644 (file)
@@ -94,4 +94,19 @@ entry:
   ret void\r
 }\r
 \r
+; Check that pushing the addresses of globals (Or generally, things that \r
+; aren't exactly immediates) isn't broken.\r
+; Fixes PR21878.\r
+; NORMAL-LABEL: test6\r
+; NORMAL: pushl    $_ext\r
+; NORMAL-NEXT: call\r
+declare void @f(i8*)\r
+@ext = external constant i8\r
 \r
+define void @test6() {\r
+  call void @f(i8* @ext)\r
+  br label %bb\r
+bb:\r
+  alloca i32\r
+  ret void\r
+}
\ No newline at end of file