Previously we only formed MUL_IMM when we split a constant. This blocked load folding on those cases. We should also form MUL_IMM for 3/5/9 to favor LEA over load folding.
Differential Revision: https://reviews.llvm.org/D46040
llvm-svn: 330850
if (!C)
return SDValue();
uint64_t MulAmt = C->getZExtValue();
- if (isPowerOf2_64(MulAmt) || MulAmt == 3 || MulAmt == 5 || MulAmt == 9)
+ if (isPowerOf2_64(MulAmt))
return SDValue();
+ SDLoc DL(N);
+ if (MulAmt == 3 || MulAmt == 5 || MulAmt == 9)
+ return DAG.getNode(X86ISD::MUL_IMM, DL, VT, N->getOperand(0),
+ N->getOperand(1));
+
uint64_t MulAmt1 = 0;
uint64_t MulAmt2 = 0;
if ((MulAmt % 9) == 0) {
MulAmt2 = MulAmt / 3;
}
- SDLoc DL(N);
SDValue NewMul;
if (MulAmt2 &&
(isPowerOf2_64(MulAmt2) || MulAmt2 == 3 || MulAmt2 == 5 || MulAmt2 == 9)){
;
; X86-LABEL: mul3_32:
; X86: # %bb.0:
-; X86-NEXT: imull $3, {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,2), %eax
; X86-NEXT: retl
; But why?!
%mul = mul i32 %A, 3
;
; X86-LABEL: mul3_64:
; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,2), %ecx
; X86-NEXT: movl $3, %eax
; X86-NEXT: mull {{[0-9]+}}(%esp)
-; X86-NEXT: imull $3, {{[0-9]+}}(%esp), %ecx
; X86-NEXT: addl %ecx, %edx
; X86-NEXT: retl
%mul = mul i64 %A, 3
define i16 @test_mul_by_3(i16 %x) {
; X86-LABEL: test_mul_by_3:
; X86: # %bb.0:
-; X86-NEXT: imull $3, {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,2), %eax
; X86-NEXT: # kill: def $ax killed $ax killed $eax
; X86-NEXT: retl
;
define i16 @test_mul_by_5(i16 %x) {
; X86-LABEL: test_mul_by_5:
; X86: # %bb.0:
-; X86-NEXT: imull $5, {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,4), %eax
; X86-NEXT: # kill: def $ax killed $ax killed $eax
; X86-NEXT: retl
;
define i16 @test_mul_by_9(i16 %x) {
; X86-LABEL: test_mul_by_9:
; X86: # %bb.0:
-; X86-NEXT: imull $9, {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,8), %eax
; X86-NEXT: # kill: def $ax killed $ax killed $eax
; X86-NEXT: retl
;
define i32 @test_mul_by_3(i32 %x) {
; X86-LABEL: test_mul_by_3:
; X86: # %bb.0:
-; X86-NEXT: imull $3, {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,2), %eax
; X86-NEXT: retl
;
; X64-HSW-LABEL: test_mul_by_3:
define i32 @test_mul_by_5(i32 %x) {
; X86-LABEL: test_mul_by_5:
; X86: # %bb.0:
-; X86-NEXT: imull $5, {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,4), %eax
; X86-NEXT: retl
;
; X64-HSW-LABEL: test_mul_by_5:
define i32 @test_mul_by_9(i32 %x) {
; X86-LABEL: test_mul_by_9:
; X86: # %bb.0:
-; X86-NEXT: imull $9, {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,8), %eax
; X86-NEXT: retl
;
; X64-HSW-LABEL: test_mul_by_9:
define i64 @test_mul_by_3(i64 %x) {
; X86-LABEL: test_mul_by_3:
; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,2), %ecx
; X86-NEXT: movl $3, %eax
; X86-NEXT: mull {{[0-9]+}}(%esp)
-; X86-NEXT: imull $3, {{[0-9]+}}(%esp), %ecx
; X86-NEXT: addl %ecx, %edx
; X86-NEXT: retl
;
define i64 @test_mul_by_5(i64 %x) {
; X86-LABEL: test_mul_by_5:
; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,4), %ecx
; X86-NEXT: movl $5, %eax
; X86-NEXT: mull {{[0-9]+}}(%esp)
-; X86-NEXT: imull $5, {{[0-9]+}}(%esp), %ecx
; X86-NEXT: addl %ecx, %edx
; X86-NEXT: retl
;
define i64 @test_mul_by_9(i64 %x) {
; X86-LABEL: test_mul_by_9:
; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (%eax,%eax,8), %ecx
; X86-NEXT: movl $9, %eax
; X86-NEXT: mull {{[0-9]+}}(%esp)
-; X86-NEXT: imull $9, {{[0-9]+}}(%esp), %ecx
; X86-NEXT: addl %ecx, %edx
; X86-NEXT: retl
;