From 31b101a18613e1bbe6e3b5a630a2359be1be4f4b Mon Sep 17 00:00:00 2001 From: Zvi Rackover Date: Tue, 24 Oct 2017 12:13:05 +0000 Subject: [PATCH] X86CallFrameOptimization: Recognize 'store 0/-1 using and/or' idioms 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 | 36 ++- llvm/test/CodeGen/X86/memcmp-minsize.ll | 287 +++++++++-------------- llvm/test/CodeGen/X86/movtopush.ll | 116 +++++++++ llvm/test/CodeGen/X86/movtopush64.ll | 33 +++ 4 files changed, 288 insertions(+), 184 deletions(-) diff --git a/llvm/lib/Target/X86/X86CallFrameOptimization.cpp b/llvm/lib/Target/X86/X86CallFrameOptimization.cpp index 32b18b0..94beb38 100644 --- a/llvm/lib/Target/X86/X86CallFrameOptimization.cpp +++ b/llvm/lib/Target/X86/X86CallFrameOptimization.cpp @@ -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; diff --git a/llvm/test/CodeGen/X86/memcmp-minsize.ll b/llvm/test/CodeGen/X86/memcmp-minsize.ll index a55c40f..9c196b13 100644 --- a/llvm/test/CodeGen/X86/memcmp-minsize.ll +++ b/llvm/test/CodeGen/X86/memcmp-minsize.ll @@ -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: diff --git a/llvm/test/CodeGen/X86/movtopush.ll b/llvm/test/CodeGen/X86/movtopush.ll index ad34381..051c8a7 100644 --- a/llvm/test/CodeGen/X86/movtopush.ll +++ b/llvm/test/CodeGen/X86/movtopush.ll @@ -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 +} diff --git a/llvm/test/CodeGen/X86/movtopush64.ll b/llvm/test/CodeGen/X86/movtopush64.ll index 1f4aa18..76dd740 100644 --- a/llvm/test/CodeGen/X86/movtopush64.ll +++ b/llvm/test/CodeGen/X86/movtopush64.ll @@ -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 +} -- 2.7.4