X86CallFrameOptimization: Recognize 'store 0/-1 using and/or' idioms
authorZvi Rackover <zvi.rackover@intel.com>
Tue, 24 Oct 2017 12:13:05 +0000 (12:13 +0000)
committerZvi Rackover <zvi.rackover@intel.com>
Tue, 24 Oct 2017 12:13:05 +0000 (12:13 +0000)
Summary:
r264440 added or/and patterns for storing -1 or 0 with the intention of decreasing code size. However,
X86CallFrameOptimization does not recognize these memory accesses so it will not replace them with push's when profitable.

This patch fixes this problem by teaching X86CallFrameOptimization these store 0/-1 idioms.

An alternative fix would be to prevent the 'store 0/1 idioms' patterns from firing when accessing the stack. This would save
the need to teach the pass about these idioms. However, because X86CallFrameOptimization does not always fire we may result
in cases where neither X86CallFrameOptimization not the patterns for 'store 0/1 idioms' fire.

Fixes pr34863

Reviewers: DavidKreitzer, guyblank, aymanmus

Reviewed By: aymanmus

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D38738

llvm-svn: 316431

llvm/lib/Target/X86/X86CallFrameOptimization.cpp
llvm/test/CodeGen/X86/memcmp-minsize.ll
llvm/test/CodeGen/X86/movtopush.ll
llvm/test/CodeGen/X86/movtopush64.ll

index 32b18b0..94beb38 100644 (file)
@@ -280,11 +280,27 @@ X86CallFrameOptimization::classifyInstruction(
   if (MI == MBB.end())
     return Exit;
 
-  // The instructions we actually care about are movs onto the stack
-  int Opcode = MI->getOpcode();
-  if (Opcode == X86::MOV32mi   || Opcode == X86::MOV32mr ||
-      Opcode == X86::MOV64mi32 || Opcode == X86::MOV64mr)
-    return Convert;
+  // The instructions we actually care about are movs onto the stack or special
+  // cases of constant-stores to stack
+  switch (MI->getOpcode()) {
+    case X86::AND16mi8:
+    case X86::AND32mi8:
+    case X86::AND64mi8: {
+      MachineOperand ImmOp = MI->getOperand(X86::AddrNumOperands);
+      return ImmOp.getImm() == 0 ? Convert : Exit;
+    }
+    case X86::OR16mi8:
+    case X86::OR32mi8:
+    case X86::OR64mi8: {
+      MachineOperand ImmOp = MI->getOperand(X86::AddrNumOperands);
+      return ImmOp.getImm() == -1 ? Convert : Exit;
+    }
+    case X86::MOV32mi:
+    case X86::MOV32mr:
+    case X86::MOV64mi32:
+    case X86::MOV64mr:
+      return Convert;
+  }
 
   // Not all calling conventions have only stack MOVs between the stack
   // adjust and the call.
@@ -483,8 +499,8 @@ void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,
 
   DebugLoc DL = FrameSetup->getDebugLoc();
   bool Is64Bit = STI->is64Bit();
-  // Now, iterate through the vector in reverse order, and replace the movs
-  // with pushes. MOVmi/MOVmr doesn't have any defs, so no need to
+  // Now, iterate through the vector in reverse order, and replace the store to
+  // stack with pushes. MOVmi/MOVmr doesn't have any defs, so no need to
   // replace uses.
   for (int Idx = (Context.ExpectedDist >> Log2SlotSize) - 1; Idx >= 0; --Idx) {
     MachineBasicBlock::iterator MOV = *Context.MovVector[Idx];
@@ -494,6 +510,12 @@ void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,
     switch (MOV->getOpcode()) {
     default:
       llvm_unreachable("Unexpected Opcode!");
+    case X86::AND16mi8:
+    case X86::AND32mi8:
+    case X86::AND64mi8:
+    case X86::OR16mi8:
+    case X86::OR32mi8:
+    case X86::OR64mi8:
     case X86::MOV32mi:
     case X86::MOV64mi32:
       PushOpcode = Is64Bit ? X86::PUSH64i32 : X86::PUSHi32;
index a55c40f..9c196b1 100644 (file)
@@ -14,13 +14,10 @@ declare i32 @memcmp(i8*, i8*, i64)
 define i32 @length2(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length2:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $2, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $2
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -76,17 +73,14 @@ define i1 @length2_eq_const(i8* %X) nounwind minsize {
 define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length2_eq_nobuiltin_attr:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $2, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $2
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    sete %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length2_eq_nobuiltin_attr:
@@ -107,13 +101,10 @@ define i1 @length2_eq_nobuiltin_attr(i8* %X, i8* %Y) nounwind minsize {
 define i32 @length3(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length3:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $3, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $3
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -130,17 +121,14 @@ define i32 @length3(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length3_eq(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length3_eq:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $3, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $3
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    setne %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length3_eq:
@@ -161,13 +149,10 @@ define i1 @length3_eq(i8* %X, i8* %Y) nounwind minsize {
 define i32 @length4(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length4:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $4, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $4
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -223,13 +208,10 @@ define i1 @length4_eq_const(i8* %X) nounwind minsize {
 define i32 @length5(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length5:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $5, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $5
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -246,17 +228,14 @@ define i32 @length5(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length5_eq(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length5_eq:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $5, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $5
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    setne %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length5_eq:
@@ -277,13 +256,10 @@ define i1 @length5_eq(i8* %X, i8* %Y) nounwind minsize {
 define i32 @length8(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length8:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $8, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $8
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -300,17 +276,14 @@ define i32 @length8(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length8_eq(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length8_eq:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $8, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $8
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    sete %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length8_eq:
@@ -327,16 +300,14 @@ define i1 @length8_eq(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length8_eq_const(i8* %X) nounwind minsize {
 ; X86-LABEL: length8_eq_const:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $8, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $.L.str, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $8
+; X86-NEXT:    pushl $.L.str
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    setne %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length8_eq_const:
@@ -353,17 +324,14 @@ define i1 @length8_eq_const(i8* %X) nounwind minsize {
 define i1 @length12_eq(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length12_eq:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $12, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $12
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    setne %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length12_eq:
@@ -384,13 +352,10 @@ define i1 @length12_eq(i8* %X, i8* %Y) nounwind minsize {
 define i32 @length12(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length12:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $12, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $12
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -409,13 +374,10 @@ define i32 @length12(i8* %X, i8* %Y) nounwind minsize {
 define i32 @length16(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length16:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $16, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $16
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -432,17 +394,14 @@ define i32 @length16(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length16_eq(i8* %x, i8* %y) nounwind minsize {
 ; X86-NOSSE-LABEL: length16_eq:
 ; X86-NOSSE:       # BB#0:
-; X86-NOSSE-NEXT:    subl $16, %esp
-; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
-; X86-NOSSE-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    movl $16, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    pushl $0
+; X86-NOSSE-NEXT:    pushl $16
+; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    calll memcmp
+; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    testl %eax, %eax
 ; X86-NOSSE-NEXT:    setne %al
-; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE2-LABEL: length16_eq:
@@ -483,16 +442,14 @@ define i1 @length16_eq(i8* %x, i8* %y) nounwind minsize {
 define i1 @length16_eq_const(i8* %X) nounwind minsize {
 ; X86-NOSSE-LABEL: length16_eq_const:
 ; X86-NOSSE:       # BB#0:
-; X86-NOSSE-NEXT:    subl $16, %esp
-; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
-; X86-NOSSE-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    movl $16, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    movl $.L.str, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    pushl $0
+; X86-NOSSE-NEXT:    pushl $16
+; X86-NOSSE-NEXT:    pushl $.L.str
+; X86-NOSSE-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    calll memcmp
+; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    testl %eax, %eax
 ; X86-NOSSE-NEXT:    sete %al
-; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE2-LABEL: length16_eq_const:
@@ -532,13 +489,10 @@ define i1 @length16_eq_const(i8* %X) nounwind minsize {
 define i32 @length24(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length24:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $24, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $24
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -555,17 +509,14 @@ define i32 @length24(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length24_eq(i8* %x, i8* %y) nounwind minsize {
 ; X86-LABEL: length24_eq:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $24, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $24
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    sete %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length24_eq:
@@ -586,16 +537,14 @@ define i1 @length24_eq(i8* %x, i8* %y) nounwind minsize {
 define i1 @length24_eq_const(i8* %X) nounwind minsize {
 ; X86-LABEL: length24_eq_const:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $24, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $.L.str, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $24
+; X86-NEXT:    pushl $.L.str
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    setne %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length24_eq_const:
@@ -617,13 +566,10 @@ define i1 @length24_eq_const(i8* %X) nounwind minsize {
 define i32 @length32(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length32:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $32, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $32
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -642,17 +588,14 @@ define i32 @length32(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length32_eq(i8* %x, i8* %y) nounwind minsize {
 ; X86-LABEL: length32_eq:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $32, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $32
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    sete %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-SSE2-LABEL: length32_eq:
@@ -683,16 +626,14 @@ define i1 @length32_eq(i8* %x, i8* %y) nounwind minsize {
 define i1 @length32_eq_const(i8* %X) nounwind minsize {
 ; X86-LABEL: length32_eq_const:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $32, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $.L.str, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $32
+; X86-NEXT:    pushl $.L.str
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    setne %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-SSE2-LABEL: length32_eq_const:
@@ -724,13 +665,10 @@ define i1 @length32_eq_const(i8* %X) nounwind minsize {
 define i32 @length64(i8* %X, i8* %Y) nounwind minsize {
 ; X86-LABEL: length64:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $64, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $64
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
 ; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
@@ -747,17 +685,14 @@ define i32 @length64(i8* %X, i8* %Y) nounwind minsize {
 define i1 @length64_eq(i8* %x, i8* %y) nounwind minsize {
 ; X86-LABEL: length64_eq:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $64, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $64
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    setne %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length64_eq:
@@ -778,16 +713,14 @@ define i1 @length64_eq(i8* %x, i8* %y) nounwind minsize {
 define i1 @length64_eq_const(i8* %X) nounwind minsize {
 ; X86-LABEL: length64_eq_const:
 ; X86:       # BB#0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    andl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $64, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl $.L.str, {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl $0
+; X86-NEXT:    pushl $64
+; X86-NEXT:    pushl $.L.str
+; X86-NEXT:    pushl {{[0-9]+}}(%esp)
 ; X86-NEXT:    calll memcmp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    testl %eax, %eax
 ; X86-NEXT:    sete %al
-; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: length64_eq_const:
index ad34381..051c8a7 100644 (file)
@@ -12,6 +12,8 @@ declare void @inreg(i32 %a, i32 inreg %b, i32 %c, i32 %d)
 declare x86_thiscallcc void @thiscall(%class.Class* %class, i32 %a, i32 %b, i32 %c, i32 %d)
 declare void @oneparam(i32 %a)
 declare void @eightparams(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h)
+declare void @eightparams16(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f, i16 %g, i16 %h)
+declare void @eightparams64(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i64 %h)
 declare void @struct(%struct.s* byval %a, i32 %b, i32 %c, i32 %d)
 declare void @inalloca(<{ %struct.s }>* inalloca)
 
@@ -416,3 +418,117 @@ entry:
   call void @B_func(%struct.B* sret %tmp, %struct.B* %ref.tmp, i32 1)
   ret void
 }
+
+; NORMAL-LABEL: pr34863_16
+; NORMAL:       movl  4(%esp), %eax
+; NORMAL-NEXT:  pushl  $65535
+; NORMAL-NEXT:  pushl  $0
+; NORMAL-NEXT:  pushl  %eax
+; NORMAL-NEXT:  pushl  %eax
+; NORMAL-NEXT:  pushl  %eax
+; NORMAL-NEXT:  pushl  %eax
+; NORMAL-NEXT:  pushl  %eax
+; NORMAL-NEXT:  pushl  %eax
+; NORMAL-NEXT:  calll  _eightparams16
+; NORMAL-NEXT:  addl  $32, %esp
+;
+; NOPUSH-LABEL: pr34863_16
+; NOPUSH:       subl  $32, %esp       
+; NOPUSH-NEXT:  movl  36(%esp), %eax  
+; NOPUSH-NEXT:  movl  %eax, 20(%esp)  
+; NOPUSH-NEXT:  movl  %eax, 16(%esp)  
+; NOPUSH-NEXT:  movl  %eax, 12(%esp)  
+; NOPUSH-NEXT:  movl  %eax, 8(%esp)   
+; NOPUSH-NEXT:  movl  %eax, 4(%esp)   
+; NOPUSH-NEXT:  movl  %eax, (%esp)    
+; NOPUSH-NEXT:  movl  $65535, 28(%esp)
+; NOPUSH-NEXT:  andl  $0, 24(%esp)    
+; NOPUSH-NEXT:  calll  _eightparams16  
+; NOPUSH-NEXT:   addl  $32, %esp
+define void @pr34863_16(i16 %x) minsize nounwind {
+entry:
+  tail call void @eightparams16(i16 %x, i16 %x, i16 %x, i16 %x, i16 %x, i16 %x, i16 0, i16 -1)
+  ret void
+}
+
+; NORMAL-LABEL: pr34863_32
+; NORMAL:      movl  4(%esp), %eax
+; NORMAL-NEXT: pushl  $-1
+; NORMAL-NEXT: pushl  $0
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: calll  _eightparams
+; NORMAL-NEXT: addl  $32, %esp
+;
+; NOPUSH-LABEL: pr34863_32
+; NOPUSH:      subl  $32, %esp     
+; NOPUSH-NEXT: movl  36(%esp), %eax
+; NOPUSH-NEXT: movl  %eax, 20(%esp)
+; NOPUSH-NEXT: movl  %eax, 16(%esp)
+; NOPUSH-NEXT: movl  %eax, 12(%esp)
+; NOPUSH-NEXT: movl  %eax, 8(%esp) 
+; NOPUSH-NEXT: movl  %eax, 4(%esp) 
+; NOPUSH-NEXT: movl  %eax, (%esp)  
+; NOPUSH-NEXT: orl  $-1, 28(%esp)     
+; NOPUSH-NEXT: andl  $0, 24(%esp)  
+; NOPUSH-NEXT: calll  _eightparams  
+; NOPUSH-NEXT: addl  $32, %esp     
+define void @pr34863_32(i32 %x) minsize nounwind {
+entry:
+  tail call void @eightparams(i32 %x, i32 %x, i32 %x, i32 %x, i32 %x, i32 %x, i32 0, i32 -1)
+  ret void
+}
+
+; NORMAL-LABEL: pr34863_64
+; NORMAL:      movl  4(%esp), %eax
+; NORMAL-NEXT: movl  8(%esp), %ecx
+; NORMAL-NEXT: pushl  $-1
+; NORMAL-NEXT: pushl  $-1
+; NORMAL-NEXT: pushl  $0
+; NORMAL-NEXT: pushl  $0
+; NORMAL-NEXT: pushl  %ecx
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %ecx
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %ecx
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %ecx
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %ecx
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: pushl  %ecx
+; NORMAL-NEXT: pushl  %eax
+; NORMAL-NEXT: calll  _eightparams64
+; NORMAL-NEXT: addl  $64, %esp
+;
+; NOPUSH-LABEL: pr34863_64
+; NOPUSH:      subl  $64, %esp     
+; NOPUSH-NEXT: movl  68(%esp), %eax
+; NOPUSH-NEXT: movl  72(%esp), %ecx
+; NOPUSH-NEXT: movl  %ecx, 44(%esp)
+; NOPUSH-NEXT: movl  %eax, 40(%esp)
+; NOPUSH-NEXT: movl  %ecx, 36(%esp)
+; NOPUSH-NEXT: movl  %eax, 32(%esp)
+; NOPUSH-NEXT: movl  %ecx, 28(%esp)
+; NOPUSH-NEXT: movl  %eax, 24(%esp)
+; NOPUSH-NEXT: movl  %ecx, 20(%esp)
+; NOPUSH-NEXT: movl  %eax, 16(%esp)
+; NOPUSH-NEXT: movl  %ecx, 12(%esp)
+; NOPUSH-NEXT: movl  %eax, 8(%esp) 
+; NOPUSH-NEXT: movl  %ecx, 4(%esp) 
+; NOPUSH-NEXT: movl  %eax, (%esp)  
+; NOPUSH-NEXT: orl  $-1, 60(%esp)     
+; NOPUSH-NEXT: orl  $-1, 56(%esp)     
+; NOPUSH-NEXT: andl  $0, 52(%esp)  
+; NOPUSH-NEXT: andl  $0, 48(%esp)  
+; NOPUSH-NEXT: calll  _eightparams64
+; NOPUSH-NEXT: addl  $64, %esp     
+define void @pr34863_64(i64 %x) minsize nounwind {
+entry:
+  tail call void @eightparams64(i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 0, i64 -1)
+  ret void
+}
index 1f4aa18..76dd740 100644 (file)
@@ -4,6 +4,9 @@
 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -no-x86-call-frame-opt | FileCheck %s -check-prefix=NOPUSH
 
 declare void @seven_params(i32 %a, i64 %b, i32 %c, i64 %d, i32 %e, i64 %f, i32 %g)
+declare void @eightparams(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h)
+declare void @eightparams16(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f, i16 %g, i16 %h)
+declare void @eightparams64(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i64 %h)
 declare void @ten_params(i32 %a, i64 %b, i32 %c, i64 %d, i32 %e, i64 %f, i32 %g, i64 %h, i32 %i, i64 %j)
 declare void @ten_params_ptr(i32 %a, i64 %b, i32 %c, i64 %d, i32 %e, i64 %f, i32 %g, i8* %h, i32 %i, i64 %j)
 declare void @cannot_push(float %a, float %b, float %c, float %d, float %e, float %f, float %g, float %h, float %i)
@@ -191,3 +194,33 @@ define void @test10(float %p1) {
   call void @ten_params(i32 1, i64 2, i32 3, i64 4, i32 5, i64 6, i32 7, i64 8, i32 9, i64 10)
   ret void
 }
+
+; NORMAL-LABEL: pr34863_16
+; NORMAL:  pushq  ${{-1|65535}}
+; NORMAL-NEXT:  pushq  $0
+; NORMAL-NEXT:  call
+define void @pr34863_16(i16 %x) minsize nounwind {
+entry:
+  tail call void @eightparams16(i16 %x, i16 %x, i16 %x, i16 %x, i16 %x, i16 %x, i16 0, i16 -1)
+  ret void
+}
+
+; NORMAL-LABEL: pr34863_32
+; NORMAL:  pushq  ${{-1|65535}}
+; NORMAL-NEXT:  pushq  $0
+; NORMAL-NEXT:  call
+define void @pr34863_32(i32 %x) minsize nounwind {
+entry:
+  tail call void @eightparams(i32 %x, i32 %x, i32 %x, i32 %x, i32 %x, i32 %x, i32 0, i32 -1)
+  ret void
+}
+
+; NORMAL-LABEL: pr34863_64
+; NORMAL:  pushq  ${{-1|65535}}
+; NORMAL-NEXT:  pushq  $0
+; NORMAL-NEXT:  call
+define void @pr34863_64(i64 %x) minsize nounwind {
+entry:
+  tail call void @eightparams64(i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 0, i64 -1)
+  ret void
+}