summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp29
-rw-r--r--llvm/test/CodeGen/AArch64/align-down.ll3
-rw-r--r--llvm/test/CodeGen/AArch64/sub-of-bias.ll12
-rw-r--r--llvm/test/CodeGen/X86/align-down.ll42
-rw-r--r--llvm/test/CodeGen/X86/sub-of-bias.ll155
5 files changed, 138 insertions, 103 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5a8b4d456d9..3bfea38932f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -3104,31 +3104,20 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
DAG.getNode(ISD::SUB, DL, VT, N1.getOperand(1),
N1.getOperand(0)));
- // A - (A & (B - 1)) -> A & (~(B - 1)) -> A & (0 - B)
- if (N1.getOpcode() == ISD::AND && N1.hasOneUse()) {
+ // A - (A & B) -> A & (~B)
+ if (N1.getOpcode() == ISD::AND) {
SDValue A = N1.getOperand(0);
- SDValue BDec = N1.getOperand(1);
+ SDValue B = N1.getOperand(1);
if (A != N0)
- std::swap(A, BDec);
- if (A == N0 && BDec.getOpcode() == ISD::ADD &&
- isAllOnesOrAllOnesSplat(BDec->getOperand(1))) {
- SDValue B = BDec.getOperand(0);
- SDValue NegB =
- DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), B);
- return DAG.getNode(ISD::AND, DL, VT, A, NegB);
+ std::swap(A, B);
+ if (A == N0 &&
+ (N1.hasOneUse() || isConstantOrConstantVector(B, /*NoOpaques=*/true))) {
+ SDValue InvB =
+ DAG.getNode(ISD::XOR, DL, VT, B, DAG.getAllOnesConstant(DL, VT));
+ return DAG.getNode(ISD::AND, DL, VT, A, InvB);
}
}
- // A - (A & C) -> A & (~C)
- if (N1.getOpcode() == ISD::AND && N1.getOperand(0) == N0 &&
- isConstantOrConstantVector(N1.getOperand(1), /*NoOpaques=*/true)) {
- SDValue InvC =
- DAG.FoldConstantArithmetic(ISD::XOR, DL, VT, N1.getOperand(1).getNode(),
- DAG.getAllOnesConstant(DL, VT).getNode());
- assert(InvC && "Constant folding failed");
- return DAG.getNode(ISD::AND, DL, VT, N0, InvC);
- }
-
// fold (X - (-Y * Z)) -> (X + (Y * Z))
if (N1.getOpcode() == ISD::MUL && N1.hasOneUse()) {
if (N1.getOperand(0).getOpcode() == ISD::SUB &&
diff --git a/llvm/test/CodeGen/AArch64/align-down.ll b/llvm/test/CodeGen/AArch64/align-down.ll
index 4ad4d115157..659b69ca27b 100644
--- a/llvm/test/CodeGen/AArch64/align-down.ll
+++ b/llvm/test/CodeGen/AArch64/align-down.ll
@@ -127,8 +127,7 @@ define i32 @n8_not_lowbit_mask(i32 %ptr, i32 %alignment) nounwind {
; CHECK-LABEL: n8_not_lowbit_mask:
; CHECK: // %bb.0:
; CHECK-NEXT: add w8, w1, #1 // =1
-; CHECK-NEXT: and w8, w0, w8
-; CHECK-NEXT: sub w0, w0, w8
+; CHECK-NEXT: bic w0, w0, w8
; CHECK-NEXT: ret
%mask = add i32 %alignment, 1 ; not -1
%bias = and i32 %ptr, %mask
diff --git a/llvm/test/CodeGen/AArch64/sub-of-bias.ll b/llvm/test/CodeGen/AArch64/sub-of-bias.ll
index 8a80ff8d7b6..17b548cbeab 100644
--- a/llvm/test/CodeGen/AArch64/sub-of-bias.ll
+++ b/llvm/test/CodeGen/AArch64/sub-of-bias.ll
@@ -17,8 +17,7 @@
define i32 @t0_32(i32 %ptr, i32 %mask) nounwind {
; CHECK-LABEL: t0_32:
; CHECK: // %bb.0:
-; CHECK-NEXT: and w8, w0, w1
-; CHECK-NEXT: sub w0, w0, w8
+; CHECK-NEXT: bic w0, w0, w1
; CHECK-NEXT: ret
%bias = and i32 %ptr, %mask
%r = sub i32 %ptr, %bias
@@ -27,8 +26,7 @@ define i32 @t0_32(i32 %ptr, i32 %mask) nounwind {
define i64 @t1_64(i64 %ptr, i64 %mask) nounwind {
; CHECK-LABEL: t1_64:
; CHECK: // %bb.0:
-; CHECK-NEXT: and x8, x0, x1
-; CHECK-NEXT: sub x0, x0, x8
+; CHECK-NEXT: bic x0, x0, x1
; CHECK-NEXT: ret
%bias = and i64 %ptr, %mask
%r = sub i64 %ptr, %bias
@@ -38,8 +36,7 @@ define i64 @t1_64(i64 %ptr, i64 %mask) nounwind {
define i32 @t2_commutative(i32 %ptr, i32 %mask) nounwind {
; CHECK-LABEL: t2_commutative:
; CHECK: // %bb.0:
-; CHECK-NEXT: and w8, w1, w0
-; CHECK-NEXT: sub w0, w0, w8
+; CHECK-NEXT: bic w0, w0, w1
; CHECK-NEXT: ret
%bias = and i32 %mask, %ptr ; swapped
%r = sub i32 %ptr, %bias
@@ -87,8 +84,7 @@ define i32 @n5_different_ptrs_commutative(i32 %ptr0, i32 %ptr1, i32 %mask) nounw
define i32 @n6_not_lowbit_mask(i32 %ptr, i32 %mask) nounwind {
; CHECK-LABEL: n6_not_lowbit_mask:
; CHECK: // %bb.0:
-; CHECK-NEXT: and w8, w0, w1
-; CHECK-NEXT: sub w0, w0, w8
+; CHECK-NEXT: bic w0, w0, w1
; CHECK-NEXT: ret
%bias = and i32 %ptr, %mask
%r = sub i32 %ptr, %bias
diff --git a/llvm/test/CodeGen/X86/align-down.ll b/llvm/test/CodeGen/X86/align-down.ll
index 5ecdd133a2a..e14d3122161 100644
--- a/llvm/test/CodeGen/X86/align-down.ll
+++ b/llvm/test/CodeGen/X86/align-down.ll
@@ -214,22 +214,34 @@ define i32 @n7_different_ptrs_commutative(i32 %ptr0, i32 %ptr1, i32 %alignment)
}
define i32 @n8_not_lowbit_mask(i32 %ptr, i32 %alignment) nounwind {
-; X86-LABEL: n8_not_lowbit_mask:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: incl %ecx
-; X86-NEXT: andl %eax, %ecx
-; X86-NEXT: subl %ecx, %eax
-; X86-NEXT: retl
+; NOBMI-X86-LABEL: n8_not_lowbit_mask:
+; NOBMI-X86: # %bb.0:
+; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: incl %eax
+; NOBMI-X86-NEXT: notl %eax
+; NOBMI-X86-NEXT: andl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: retl
;
-; X64-LABEL: n8_not_lowbit_mask:
-; X64: # %bb.0:
-; X64-NEXT: movl %edi, %eax
-; X64-NEXT: incl %esi
-; X64-NEXT: andl %edi, %esi
-; X64-NEXT: subl %esi, %eax
-; X64-NEXT: retq
+; BMI-X86-LABEL: n8_not_lowbit_mask:
+; BMI-X86: # %bb.0:
+; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; BMI-X86-NEXT: incl %eax
+; BMI-X86-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax
+; BMI-X86-NEXT: retl
+;
+; NOBMI-X64-LABEL: n8_not_lowbit_mask:
+; NOBMI-X64: # %bb.0:
+; NOBMI-X64-NEXT: movl %esi, %eax
+; NOBMI-X64-NEXT: incl %eax
+; NOBMI-X64-NEXT: notl %eax
+; NOBMI-X64-NEXT: andl %edi, %eax
+; NOBMI-X64-NEXT: retq
+;
+; BMI-X64-LABEL: n8_not_lowbit_mask:
+; BMI-X64: # %bb.0:
+; BMI-X64-NEXT: incl %esi
+; BMI-X64-NEXT: andnl %edi, %esi, %eax
+; BMI-X64-NEXT: retq
%mask = add i32 %alignment, 1 ; not -1
%bias = and i32 %ptr, %mask
%r = sub i32 %ptr, %bias
diff --git a/llvm/test/CodeGen/X86/sub-of-bias.ll b/llvm/test/CodeGen/X86/sub-of-bias.ll
index a51b909bf93..8a51ac1bd62 100644
--- a/llvm/test/CodeGen/X86/sub-of-bias.ll
+++ b/llvm/test/CodeGen/X86/sub-of-bias.ll
@@ -18,65 +18,94 @@
; The basic positive tests
define i32 @t0_32(i32 %ptr, i32 %mask) nounwind {
-; X86-LABEL: t0_32:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: andl %eax, %ecx
-; X86-NEXT: subl %ecx, %eax
-; X86-NEXT: retl
+; NOBMI-X86-LABEL: t0_32:
+; NOBMI-X86: # %bb.0:
+; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: notl %eax
+; NOBMI-X86-NEXT: andl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: retl
;
-; X64-LABEL: t0_32:
-; X64: # %bb.0:
-; X64-NEXT: movl %edi, %eax
-; X64-NEXT: andl %edi, %esi
-; X64-NEXT: subl %esi, %eax
-; X64-NEXT: retq
+; BMI-X86-LABEL: t0_32:
+; BMI-X86: # %bb.0:
+; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; BMI-X86-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax
+; BMI-X86-NEXT: retl
+;
+; NOBMI-X64-LABEL: t0_32:
+; NOBMI-X64: # %bb.0:
+; NOBMI-X64-NEXT: movl %esi, %eax
+; NOBMI-X64-NEXT: notl %eax
+; NOBMI-X64-NEXT: andl %edi, %eax
+; NOBMI-X64-NEXT: retq
+;
+; BMI-X64-LABEL: t0_32:
+; BMI-X64: # %bb.0:
+; BMI-X64-NEXT: andnl %edi, %esi, %eax
+; BMI-X64-NEXT: retq
%bias = and i32 %ptr, %mask
%r = sub i32 %ptr, %bias
ret i32 %r
}
define i64 @t1_64(i64 %ptr, i64 %mask) nounwind {
-; X86-LABEL: t1_64:
-; X86: # %bb.0:
-; X86-NEXT: pushl %esi
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: andl %edx, %ecx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
-; X86-NEXT: andl %eax, %esi
-; X86-NEXT: subl %esi, %eax
-; X86-NEXT: sbbl %ecx, %edx
-; X86-NEXT: popl %esi
-; X86-NEXT: retl
+; NOBMI-X86-LABEL: t1_64:
+; NOBMI-X86: # %bb.0:
+; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; NOBMI-X86-NEXT: notl %eax
+; NOBMI-X86-NEXT: andl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: notl %edx
+; NOBMI-X86-NEXT: andl {{[0-9]+}}(%esp), %edx
+; NOBMI-X86-NEXT: retl
;
-; X64-LABEL: t1_64:
-; X64: # %bb.0:
-; X64-NEXT: movq %rdi, %rax
-; X64-NEXT: andq %rdi, %rsi
-; X64-NEXT: subq %rsi, %rax
-; X64-NEXT: retq
+; BMI-X86-LABEL: t1_64:
+; BMI-X86: # %bb.0:
+; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; BMI-X86-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax
+; BMI-X86-NEXT: andnl {{[0-9]+}}(%esp), %ecx, %edx
+; BMI-X86-NEXT: retl
+;
+; NOBMI-X64-LABEL: t1_64:
+; NOBMI-X64: # %bb.0:
+; NOBMI-X64-NEXT: movq %rsi, %rax
+; NOBMI-X64-NEXT: notq %rax
+; NOBMI-X64-NEXT: andq %rdi, %rax
+; NOBMI-X64-NEXT: retq
+;
+; BMI-X64-LABEL: t1_64:
+; BMI-X64: # %bb.0:
+; BMI-X64-NEXT: andnq %rdi, %rsi, %rax
+; BMI-X64-NEXT: retq
%bias = and i64 %ptr, %mask
%r = sub i64 %ptr, %bias
ret i64 %r
}
define i32 @t2_commutative(i32 %ptr, i32 %mask) nounwind {
-; X86-LABEL: t2_commutative:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: andl %eax, %ecx
-; X86-NEXT: subl %ecx, %eax
-; X86-NEXT: retl
+; NOBMI-X86-LABEL: t2_commutative:
+; NOBMI-X86: # %bb.0:
+; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: notl %eax
+; NOBMI-X86-NEXT: andl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: retl
;
-; X64-LABEL: t2_commutative:
-; X64: # %bb.0:
-; X64-NEXT: movl %edi, %eax
-; X64-NEXT: andl %edi, %esi
-; X64-NEXT: subl %esi, %eax
-; X64-NEXT: retq
+; BMI-X86-LABEL: t2_commutative:
+; BMI-X86: # %bb.0:
+; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; BMI-X86-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax
+; BMI-X86-NEXT: retl
+;
+; NOBMI-X64-LABEL: t2_commutative:
+; NOBMI-X64: # %bb.0:
+; NOBMI-X64-NEXT: movl %esi, %eax
+; NOBMI-X64-NEXT: notl %eax
+; NOBMI-X64-NEXT: andl %edi, %eax
+; NOBMI-X64-NEXT: retq
+;
+; BMI-X64-LABEL: t2_commutative:
+; BMI-X64: # %bb.0:
+; BMI-X64-NEXT: andnl %edi, %esi, %eax
+; BMI-X64-NEXT: retq
%bias = and i32 %mask, %ptr ; swapped
%r = sub i32 %ptr, %bias
ret i32 %r
@@ -150,20 +179,30 @@ define i32 @n5_different_ptrs_commutative(i32 %ptr0, i32 %ptr1, i32 %mask) nounw
}
define i32 @n6_not_lowbit_mask(i32 %ptr, i32 %mask) nounwind {
-; X86-LABEL: n6_not_lowbit_mask:
-; X86: # %bb.0:
-; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: andl %eax, %ecx
-; X86-NEXT: subl %ecx, %eax
-; X86-NEXT: retl
+; NOBMI-X86-LABEL: n6_not_lowbit_mask:
+; NOBMI-X86: # %bb.0:
+; NOBMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: notl %eax
+; NOBMI-X86-NEXT: andl {{[0-9]+}}(%esp), %eax
+; NOBMI-X86-NEXT: retl
;
-; X64-LABEL: n6_not_lowbit_mask:
-; X64: # %bb.0:
-; X64-NEXT: movl %edi, %eax
-; X64-NEXT: andl %edi, %esi
-; X64-NEXT: subl %esi, %eax
-; X64-NEXT: retq
+; BMI-X86-LABEL: n6_not_lowbit_mask:
+; BMI-X86: # %bb.0:
+; BMI-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; BMI-X86-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax
+; BMI-X86-NEXT: retl
+;
+; NOBMI-X64-LABEL: n6_not_lowbit_mask:
+; NOBMI-X64: # %bb.0:
+; NOBMI-X64-NEXT: movl %esi, %eax
+; NOBMI-X64-NEXT: notl %eax
+; NOBMI-X64-NEXT: andl %edi, %eax
+; NOBMI-X64-NEXT: retq
+;
+; BMI-X64-LABEL: n6_not_lowbit_mask:
+; BMI-X64: # %bb.0:
+; BMI-X64-NEXT: andnl %edi, %esi, %eax
+; BMI-X64-NEXT: retq
%bias = and i32 %ptr, %mask
%r = sub i32 %ptr, %bias
ret i32 %r
OpenPOWER on IntegriCloud