[llvm] 46eef76 - [DAGCombiner] Fix bug in MatchBSwapHWordLow.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed May 18 09:28:15 PDT 2022
Author: Craig Topper
Date: 2022-05-18T09:23:18-07:00
New Revision: 46eef7687639eca1319a93d93d9e588ee0219f8c
URL: https://github.com/llvm/llvm-project/commit/46eef7687639eca1319a93d93d9e588ee0219f8c
DIFF: https://github.com/llvm/llvm-project/commit/46eef7687639eca1319a93d93d9e588ee0219f8c.diff
LOG: [DAGCombiner] Fix bug in MatchBSwapHWordLow.
This function tries to match (a >> 8) | (a << 8) as (bswap a) >> 16.
If the SRL isn't masked and the high bits aren't demanded, we still
need to ensure that bits 23:16 are zero. After the right shift they
will be in bits 15:8 which is where the important bits from the SHL
end up. It's only a bswap if the OR on bits 15:8 only takes the bits
from the SHL.
Fixes PR55484.
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D125641
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/AArch64/arm64-rev.ll
llvm/test/CodeGen/ARM/rev.ll
llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
llvm/test/CodeGen/Thumb/rev.ll
llvm/test/CodeGen/X86/bswap.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 2a03c777f3fa9..0cfbaf0fbd5e7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6490,19 +6490,23 @@ SDValue DAGCombiner::MatchBSwapHWordLow(SDNode *N, SDValue N0, SDValue N1,
// Make sure everything beyond the low halfword gets set to zero since the SRL
// 16 will clear the top bits.
unsigned OpSizeInBits = VT.getSizeInBits();
- if (DemandHighBits && OpSizeInBits > 16) {
+ if (OpSizeInBits > 16) {
// If the left-shift isn't masked out then the only way this is a bswap is
// if all bits beyond the low 8 are 0. In that case the entire pattern
// reduces to a left shift anyway: leave it for other parts of the combiner.
- if (!LookPassAnd0)
+ if (DemandHighBits && !LookPassAnd0)
return SDValue();
// However, if the right shift isn't masked out then it might be because
- // it's not needed. See if we can spot that too.
- if (!LookPassAnd1 &&
- !DAG.MaskedValueIsZero(
- N10, APInt::getHighBitsSet(OpSizeInBits, OpSizeInBits - 16)))
- return SDValue();
+ // it's not needed. See if we can spot that too. If the high bits aren't
+ // demanded, we only need bits 23:16 to be zero. Otherwise, we need all
+ // upper bits to be zero.
+ if (!LookPassAnd1) {
+ unsigned HighBit = DemandHighBits ? OpSizeInBits : 24;
+ if (!DAG.MaskedValueIsZero(N10,
+ APInt::getBitsSet(OpSizeInBits, 16, HighBit)))
+ return SDValue();
+ }
}
SDValue Res = DAG.getNode(ISD::BSWAP, SDLoc(N), VT, N00);
diff --git a/llvm/test/CodeGen/AArch64/arm64-rev.ll b/llvm/test/CodeGen/AArch64/arm64-rev.ll
index 7220abf14c878..563c426b68a07 100644
--- a/llvm/test/CodeGen/AArch64/arm64-rev.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-rev.ll
@@ -953,8 +953,9 @@ entry:
define i32 @pr55484(i32 %0) {
; CHECK-LABEL: pr55484:
; CHECK: // %bb.0:
-; CHECK-NEXT: rev w8, w0
-; CHECK-NEXT: asr w0, w8, #16
+; CHECK-NEXT: lsr w8, w0, #8
+; CHECK-NEXT: orr w8, w8, w0, lsl #8
+; CHECK-NEXT: sxth w0, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: pr55484:
diff --git a/llvm/test/CodeGen/ARM/rev.ll b/llvm/test/CodeGen/ARM/rev.ll
index d92794124bdf7..5c1bc87a77d47 100644
--- a/llvm/test/CodeGen/ARM/rev.ll
+++ b/llvm/test/CodeGen/ARM/rev.ll
@@ -183,10 +183,27 @@ entry:
}
define i32 @pr55484(i32 %0) {
-; CHECK-LABEL: pr55484:
-; CHECK: @ %bb.0:
-; CHECK-NEXT: revsh r0, r0
-; CHECK-NEXT: bx lr
+; CHECK-ARM-LABEL: pr55484:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: lsr r1, r0, #8
+; CHECK-ARM-NEXT: orr r0, r1, r0, lsl #8
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-V6-LABEL: pr55484:
+; CHECK-V6: @ %bb.0:
+; CHECK-V6-NEXT: lsls r1, r0, #8
+; CHECK-V6-NEXT: lsrs r0, r0, #8
+; CHECK-V6-NEXT: orrs r0, r1
+; CHECK-V6-NEXT: sxth r0, r0
+; CHECK-V6-NEXT: bx lr
+;
+; CHECK-V7-LABEL: pr55484:
+; CHECK-V7: @ %bb.0:
+; CHECK-V7-NEXT: lsrs r1, r0, #8
+; CHECK-V7-NEXT: orr.w r0, r1, r0, lsl #8
+; CHECK-V7-NEXT: sxth r0, r0
+; CHECK-V7-NEXT: bx lr
%2 = lshr i32 %0, 8
%3 = shl i32 %0, 8
%4 = or i32 %2, %3
diff --git a/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll b/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
index 22612fcf76419..8003136e1286c 100644
--- a/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
+++ b/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll
@@ -1657,14 +1657,18 @@ define i32 @pr55484(i32 %0) {
;
; RV32ZBB-LABEL: pr55484:
; RV32ZBB: # %bb.0:
-; RV32ZBB-NEXT: rev8 a0, a0
-; RV32ZBB-NEXT: srai a0, a0, 16
+; RV32ZBB-NEXT: srli a1, a0, 8
+; RV32ZBB-NEXT: slli a0, a0, 8
+; RV32ZBB-NEXT: or a0, a1, a0
+; RV32ZBB-NEXT: sext.h a0, a0
; RV32ZBB-NEXT: ret
;
; RV64ZBB-LABEL: pr55484:
; RV64ZBB: # %bb.0:
-; RV64ZBB-NEXT: rev8 a0, a0
-; RV64ZBB-NEXT: srai a0, a0, 48
+; RV64ZBB-NEXT: srli a1, a0, 8
+; RV64ZBB-NEXT: slli a0, a0, 8
+; RV64ZBB-NEXT: or a0, a1, a0
+; RV64ZBB-NEXT: sext.h a0, a0
; RV64ZBB-NEXT: ret
;
; RV32ZBKB-LABEL: pr55484:
diff --git a/llvm/test/CodeGen/Thumb/rev.ll b/llvm/test/CodeGen/Thumb/rev.ll
index e04f5d785335e..ba0a6d2458a63 100644
--- a/llvm/test/CodeGen/Thumb/rev.ll
+++ b/llvm/test/CodeGen/Thumb/rev.ll
@@ -67,7 +67,10 @@ entry:
define i32 @pr55484(i32 %0) {
; CHECK-LABEL: pr55484:
; CHECK: @ %bb.0:
-; CHECK-NEXT: revsh r0, r0
+; CHECK-NEXT: lsls r1, r0, #8
+; CHECK-NEXT: lsrs r0, r0, #8
+; CHECK-NEXT: orrs r0, r1
+; CHECK-NEXT: sxth r0, r0
; CHECK-NEXT: bx lr
%2 = lshr i32 %0, 8
%3 = shl i32 %0, 8
diff --git a/llvm/test/CodeGen/X86/bswap.ll b/llvm/test/CodeGen/X86/bswap.ll
index 16f68a327f44a..c010608f6046b 100644
--- a/llvm/test/CodeGen/X86/bswap.ll
+++ b/llvm/test/CodeGen/X86/bswap.ll
@@ -395,15 +395,20 @@ define i32 @pr55484(i32 %0) {
; CHECK-LABEL: pr55484:
; CHECK: # %bb.0:
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
-; CHECK-NEXT: bswapl %eax
-; CHECK-NEXT: sarl $16, %eax
+; CHECK-NEXT: movl %eax, %ecx
+; CHECK-NEXT: shrl $8, %ecx
+; CHECK-NEXT: shll $8, %eax
+; CHECK-NEXT: orl %ecx, %eax
+; CHECK-NEXT: cwtl
; CHECK-NEXT: retl
;
; CHECK64-LABEL: pr55484:
; CHECK64: # %bb.0:
; CHECK64-NEXT: movl %edi, %eax
-; CHECK64-NEXT: bswapl %eax
-; CHECK64-NEXT: sarl $16, %eax
+; CHECK64-NEXT: shrl $8, %eax
+; CHECK64-NEXT: shll $8, %edi
+; CHECK64-NEXT: orl %eax, %edi
+; CHECK64-NEXT: movswl %di, %eax
; CHECK64-NEXT: retq
%2 = lshr i32 %0, 8
%3 = shl i32 %0, 8
More information about the llvm-commits
mailing list