summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-07-24 21:31:21 +0000
committerCraig Topper <craig.topper@intel.com>2018-07-24 21:31:21 +0000
commit5ddc0a2b149daf41a4df3d215555c96343326cf5 (patch)
treecb160ff0196511f5e702f587352411e775e9a612
parenta3fd11621951a8b1bf6a2ee2897228bcf05f1f51 (diff)
downloadbcm5719-llvm-5ddc0a2b149daf41a4df3d215555c96343326cf5.tar.gz
bcm5719-llvm-5ddc0a2b149daf41a4df3d215555c96343326cf5.zip
[X86] When expanding a multiply by a negative of one less than a power of 2, like 31, don't generate a negate of a subtract that we'll never optimize.
We generated a subtract for the power of 2 minus one then negated the result. The negate can be optimized away by swapping the subtract operands, but DAG combine doesn't know how to do that and we don't add any of the new nodes to the worklist anyway. This patch makes use explicitly emit the swapped subtract. llvm-svn: 337858
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp22
-rw-r--r--llvm/test/CodeGen/X86/imul.ll23
2 files changed, 23 insertions, 22 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index ef8a6d68395..12f6d409a60 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -33922,14 +33922,20 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
DAG.getConstant(Log2_64(NumSign * SignMulAmt - 1), DL,
MVT::i8)));
+ // To negate, subtract the number from zero
+ if (SignMulAmt < 0)
+ NewMul = DAG.getNode(ISD::SUB, DL, VT,
+ DAG.getConstant(0, DL, VT), NewMul);
} else if (IsPowerOf2_64MinusOne) {
// (mul x, 2^N - 1) => (sub (shl x, N), x)
- NewMul = DAG.getNode(
- ISD::SUB, DL, VT,
- DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
- DAG.getConstant(Log2_64(NumSign * SignMulAmt + 1), DL,
- MVT::i8)),
- N->getOperand(0));
+ NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
+ DAG.getConstant(Log2_64(NumSign * SignMulAmt + 1),
+ DL, MVT::i8));
+ // To negate, reverse the operands of the subtract.
+ if (SignMulAmt < 0)
+ NewMul = DAG.getNode(ISD::SUB, DL, VT, N->getOperand(0), NewMul);
+ else
+ NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
} else if (IsPowerOf2_64MinusTwo && NumSign == 1) {
// (mul x, 2^N - 1) => (sub (shl x, N), x)
NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
@@ -33938,10 +33944,6 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
NewMul = DAG.getNode(ISD::SUB, DL, VT, NewMul, N->getOperand(0));
}
- // To negate, subtract the number from zero
- if (NewMul && NumSign == -1)
- NewMul =
- DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), NewMul);
}
}
diff --git a/llvm/test/CodeGen/X86/imul.ll b/llvm/test/CodeGen/X86/imul.ll
index 761484c069b..14f15143b95 100644
--- a/llvm/test/CodeGen/X86/imul.ll
+++ b/llvm/test/CodeGen/X86/imul.ll
@@ -324,17 +324,16 @@ define i32 @test1(i32 %a) {
; X64: # %bb.0: # %entry
; X64-NEXT: movl %edi, %eax
; X64-NEXT: shll $5, %eax
-; X64-NEXT: subl %edi, %eax
-; X64-NEXT: negl %eax
+; X64-NEXT: subl %eax, %edi
+; X64-NEXT: movl %edi, %eax
; X64-NEXT: retq
;
; X86-LABEL: test1:
; X86: # %bb.0: # %entry
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl %ecx, %eax
-; X86-NEXT: shll $5, %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl %eax, %ecx
+; X86-NEXT: shll $5, %ecx
; X86-NEXT: subl %ecx, %eax
-; X86-NEXT: negl %eax
; X86-NEXT: retl
entry:
%tmp3 = mul i32 %a, -31
@@ -414,8 +413,8 @@ define i64 @test5(i64 %a) {
; X64: # %bb.0: # %entry
; X64-NEXT: movq %rdi, %rax
; X64-NEXT: shlq $5, %rax
-; X64-NEXT: subq %rdi, %rax
-; X64-NEXT: negq %rax
+; X64-NEXT: subq %rax, %rdi
+; X64-NEXT: movq %rdi, %rax
; X64-NEXT: retq
;
; X86-LABEL: test5:
@@ -424,15 +423,15 @@ define i64 @test5(i64 %a) {
; X86-NEXT: .cfi_def_cfa_offset 8
; X86-NEXT: .cfi_offset %esi, -8
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl %eax, %esi
-; X86-NEXT: shll $5, %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl %esi, %eax
+; X86-NEXT: shll $5, %eax
; X86-NEXT: subl %eax, %esi
; X86-NEXT: movl $-31, %edx
; X86-NEXT: movl %ecx, %eax
; X86-NEXT: mull %edx
; X86-NEXT: subl %ecx, %edx
-; X86-NEXT: subl %esi, %edx
+; X86-NEXT: addl %esi, %edx
; X86-NEXT: popl %esi
; X86-NEXT: .cfi_def_cfa_offset 4
; X86-NEXT: retl
OpenPOWER on IntegriCloud