it turns out that when ".with.overflow" intrinsics were added to the X86
authorChris Lattner <sabre@nondot.org>
Sun, 5 Dec 2010 07:30:36 +0000 (07:30 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 5 Dec 2010 07:30:36 +0000 (07:30 +0000)
commitb20e0b1fddfd9099e12b84a71fbc8ccff5a12b10
tree2884b801b2801c045f90168b6d26c5fa2d4337bb
parent777dd0739460500feb1d19d92531a34367d92e86
it turns out that when ".with.overflow" intrinsics were added to the X86
backend that they were all implemented except umul.  This one fell back
to the default implementation that did a hi/lo multiply and compared the
top.  Fix this to check the overflow flag that the 'mul' instruction
sets, so we can avoid an explicit test.  Now we compile:

void *func(long count) {
      return new int[count];
}

into:

__Z4funcl:                              ## @_Z4funcl
movl $4, %ecx                ## encoding: [0xb9,0x04,0x00,0x00,0x00]
movq %rdi, %rax              ## encoding: [0x48,0x89,0xf8]
mulq %rcx                    ## encoding: [0x48,0xf7,0xe1]
seto %cl                     ## encoding: [0x0f,0x90,0xc1]
testb %cl, %cl                ## encoding: [0x84,0xc9]
movq $-1, %rdi               ## encoding: [0x48,0xc7,0xc7,0xff,0xff,0xff,0xff]
cmoveq %rax, %rdi              ## encoding: [0x48,0x0f,0x44,0xf8]
jmp __Znam                  ## TAILCALL

instead of:

__Z4funcl:                              ## @_Z4funcl
movl $4, %ecx                ## encoding: [0xb9,0x04,0x00,0x00,0x00]
movq %rdi, %rax              ## encoding: [0x48,0x89,0xf8]
mulq %rcx                    ## encoding: [0x48,0xf7,0xe1]
testq %rdx, %rdx              ## encoding: [0x48,0x85,0xd2]
movq $-1, %rdi               ## encoding: [0x48,0xc7,0xc7,0xff,0xff,0xff,0xff]
cmoveq %rax, %rdi              ## encoding: [0x48,0x0f,0x44,0xf8]
jmp __Znam                  ## TAILCALL

Other than the silly seto+test, this is using the o bit directly, so it's going in the right
direction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120935 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/X86/X86ISelDAGToDAG.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrArithmetic.td
lib/Target/X86/X86InstrInfo.td
test/CodeGen/X86/umul-with-overflow.ll