]> granicus.if.org Git - llvm/commitdiff
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316431 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 32b18b085ded05f18c196d55a2ee6613ebb79be2..94beb3881fefc4e260056d96567430a218926c27 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 a55c40f5bda821d5fbda07597006fbb23de19e0f..9c196b13d2e45584d8c71a4285287f37d2ef7ee6 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 ad34381f43e0540e109815f4aa0a1813773fe61e..051c8a710c859dc13f660723d569f80c4f09c931 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 1f4aa18c32273d60c9a9bd811a5f0085de43c5f8..76dd7402bfac63eec2fca8c20b0f754dc5c487d7 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
+}