[llvm] r373850 - [DAGCombine] Match more patterns for half word bswap
Amaury Sechet via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 6 07:14:56 PDT 2019
Author: deadalnix
Date: Sun Oct 6 07:14:55 2019
New Revision: 373850
URL: http://llvm.org/viewvc/llvm-project?rev=373850&view=rev
Log:
[DAGCombine] Match more patterns for half word bswap
Summary: It ensures that the bswap is generated even when a part of the subtree already matches a bswap transform.
Reviewers: craig.topper, efriedma, RKSimon, lebedev.ri
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D68250
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/test/CodeGen/X86/bswap_tree.ll
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=373850&r1=373849&r2=373850&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Oct 6 07:14:55 2019
@@ -5517,6 +5517,23 @@ static bool isBSwapHWordElement(SDValue
return true;
}
+// Match 2 elements of a packed halfword bswap.
+static bool isBSwapHWordPair(SDValue N, MutableArrayRef<SDNode *> Parts) {
+ if (N.getOpcode() == ISD::OR)
+ return isBSwapHWordElement(N.getOperand(0), Parts) &&
+ isBSwapHWordElement(N.getOperand(1), Parts);
+
+ if (N.getOpcode() == ISD::SRL && N.getOperand(0).getOpcode() == ISD::BSWAP) {
+ ConstantSDNode *C = isConstOrConstSplat(N.getOperand(1));
+ if (!C || C->getAPIntValue() != 16)
+ return false;
+ Parts[0] = Parts[1] = N.getOperand(0).getOperand(0).getNode();
+ return true;
+ }
+
+ return false;
+}
+
/// Match a 32-bit packed halfword bswap. That is
/// ((x & 0x000000ff) << 8) |
/// ((x & 0x0000ff00) >> 8) |
@@ -5534,43 +5551,26 @@ SDValue DAGCombiner::MatchBSwapHWord(SDN
return SDValue();
// Look for either
- // (or (or (and), (and)), (or (and), (and)))
- // (or (or (or (and), (and)), (and)), (and))
- if (N0.getOpcode() != ISD::OR)
- return SDValue();
- SDValue N00 = N0.getOperand(0);
- SDValue N01 = N0.getOperand(1);
+ // (or (bswaphpair), (bswaphpair))
+ // (or (or (bswaphpair), (and)), (and))
+ // (or (or (and), (bswaphpair)), (and))
SDNode *Parts[4] = {};
- if (N1.getOpcode() == ISD::OR &&
- N00.getNumOperands() == 2 && N01.getNumOperands() == 2) {
+ if (isBSwapHWordPair(N0, Parts)) {
// (or (or (and), (and)), (or (and), (and)))
- if (!isBSwapHWordElement(N00, Parts))
- return SDValue();
-
- if (!isBSwapHWordElement(N01, Parts))
+ if (!isBSwapHWordPair(N1, Parts))
return SDValue();
- SDValue N10 = N1.getOperand(0);
- if (!isBSwapHWordElement(N10, Parts))
- return SDValue();
- SDValue N11 = N1.getOperand(1);
- if (!isBSwapHWordElement(N11, Parts))
- return SDValue();
- } else {
+ } else if (N0.getOpcode() != ISD::OR) {
// (or (or (or (and), (and)), (and)), (and))
if (!isBSwapHWordElement(N1, Parts))
return SDValue();
- if (!isBSwapHWordElement(N01, Parts))
- return SDValue();
- if (N00.getOpcode() != ISD::OR)
- return SDValue();
- SDValue N000 = N00.getOperand(0);
- if (!isBSwapHWordElement(N000, Parts))
+ SDValue N00 = N0.getOperand(0);
+ SDValue N01 = N0.getOperand(1);
+ if (!(isBSwapHWordElement(N01, Parts) && isBSwapHWordPair(N00, Parts)) &&
+ !(isBSwapHWordElement(N00, Parts) && isBSwapHWordPair(N01, Parts)))
return SDValue();
- SDValue N001 = N00.getOperand(1);
- if (!isBSwapHWordElement(N001, Parts))
- return SDValue();
- }
+ } else
+ return SDValue();
// Make sure the parts are all coming from the same node.
if (Parts[0] != Parts[1] || Parts[0] != Parts[2] || Parts[0] != Parts[3])
Modified: llvm/trunk/test/CodeGen/X86/bswap_tree.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bswap_tree.ll?rev=373850&r1=373849&r2=373850&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/bswap_tree.ll (original)
+++ llvm/trunk/test/CodeGen/X86/bswap_tree.ll Sun Oct 6 07:14:55 2019
@@ -79,30 +79,15 @@ define i32 @test3(i32 %x) nounwind {
; CHECK-LABEL: test3:
; CHECK: # %bb.0:
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
-; CHECK-NEXT: movl %eax, %ecx
-; CHECK-NEXT: andl $16711680, %ecx # imm = 0xFF0000
-; CHECK-NEXT: movl %eax, %edx
-; CHECK-NEXT: andl $-16777216, %edx # imm = 0xFF000000
-; CHECK-NEXT: shll $8, %ecx
-; CHECK-NEXT: shrl $8, %edx
-; CHECK-NEXT: orl %ecx, %edx
; CHECK-NEXT: bswapl %eax
-; CHECK-NEXT: shrl $16, %eax
-; CHECK-NEXT: orl %edx, %eax
+; CHECK-NEXT: roll $16, %eax
; CHECK-NEXT: retl
;
; CHECK64-LABEL: test3:
; CHECK64: # %bb.0:
; CHECK64-NEXT: movl %edi, %eax
-; CHECK64-NEXT: andl $16711680, %eax # imm = 0xFF0000
-; CHECK64-NEXT: movl %edi, %ecx
-; CHECK64-NEXT: andl $-16777216, %ecx # imm = 0xFF000000
-; CHECK64-NEXT: shll $8, %eax
-; CHECK64-NEXT: shrl $8, %ecx
-; CHECK64-NEXT: addl %ecx, %eax
-; CHECK64-NEXT: bswapl %edi
-; CHECK64-NEXT: shrl $16, %edi
-; CHECK64-NEXT: orl %edi, %eax
+; CHECK64-NEXT: bswapl %eax
+; CHECK64-NEXT: roll $16, %eax
; CHECK64-NEXT: retq
%byte2 = and i32 %x, 16711680 ; 0x00ff0000
%byte3 = and i32 %x, 4278190080 ; 0xff000000
More information about the llvm-commits
mailing list