Skip to content

Commit 46eef76

Browse files
committed
[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
1 parent 302158d commit 46eef76

File tree

6 files changed

+56
-22
lines changed

6 files changed

+56
-22
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6490,19 +6490,23 @@ SDValue DAGCombiner::MatchBSwapHWordLow(SDNode *N, SDValue N0, SDValue N1,
64906490
// Make sure everything beyond the low halfword gets set to zero since the SRL
64916491
// 16 will clear the top bits.
64926492
unsigned OpSizeInBits = VT.getSizeInBits();
6493-
if (DemandHighBits && OpSizeInBits > 16) {
6493+
if (OpSizeInBits > 16) {
64946494
// If the left-shift isn't masked out then the only way this is a bswap is
64956495
// if all bits beyond the low 8 are 0. In that case the entire pattern
64966496
// reduces to a left shift anyway: leave it for other parts of the combiner.
6497-
if (!LookPassAnd0)
6497+
if (DemandHighBits && !LookPassAnd0)
64986498
return SDValue();
64996499

65006500
// However, if the right shift isn't masked out then it might be because
6501-
// it's not needed. See if we can spot that too.
6502-
if (!LookPassAnd1 &&
6503-
!DAG.MaskedValueIsZero(
6504-
N10, APInt::getHighBitsSet(OpSizeInBits, OpSizeInBits - 16)))
6505-
return SDValue();
6501+
// it's not needed. See if we can spot that too. If the high bits aren't
6502+
// demanded, we only need bits 23:16 to be zero. Otherwise, we need all
6503+
// upper bits to be zero.
6504+
if (!LookPassAnd1) {
6505+
unsigned HighBit = DemandHighBits ? OpSizeInBits : 24;
6506+
if (!DAG.MaskedValueIsZero(N10,
6507+
APInt::getBitsSet(OpSizeInBits, 16, HighBit)))
6508+
return SDValue();
6509+
}
65066510
}
65076511

65086512
SDValue Res = DAG.getNode(ISD::BSWAP, SDLoc(N), VT, N00);

llvm/test/CodeGen/AArch64/arm64-rev.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,8 +953,9 @@ entry:
953953
define i32 @pr55484(i32 %0) {
954954
; CHECK-LABEL: pr55484:
955955
; CHECK: // %bb.0:
956-
; CHECK-NEXT: rev w8, w0
957-
; CHECK-NEXT: asr w0, w8, #16
956+
; CHECK-NEXT: lsr w8, w0, #8
957+
; CHECK-NEXT: orr w8, w8, w0, lsl #8
958+
; CHECK-NEXT: sxth w0, w8
958959
; CHECK-NEXT: ret
959960
;
960961
; GISEL-LABEL: pr55484:

llvm/test/CodeGen/ARM/rev.ll

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,27 @@ entry:
183183
}
184184

185185
define i32 @pr55484(i32 %0) {
186-
; CHECK-LABEL: pr55484:
187-
; CHECK: @ %bb.0:
188-
; CHECK-NEXT: revsh r0, r0
189-
; CHECK-NEXT: bx lr
186+
; CHECK-ARM-LABEL: pr55484:
187+
; CHECK-ARM: @ %bb.0:
188+
; CHECK-ARM-NEXT: lsr r1, r0, #8
189+
; CHECK-ARM-NEXT: orr r0, r1, r0, lsl #8
190+
; CHECK-ARM-NEXT: sxth r0, r0
191+
; CHECK-ARM-NEXT: bx lr
192+
;
193+
; CHECK-V6-LABEL: pr55484:
194+
; CHECK-V6: @ %bb.0:
195+
; CHECK-V6-NEXT: lsls r1, r0, #8
196+
; CHECK-V6-NEXT: lsrs r0, r0, #8
197+
; CHECK-V6-NEXT: orrs r0, r1
198+
; CHECK-V6-NEXT: sxth r0, r0
199+
; CHECK-V6-NEXT: bx lr
200+
;
201+
; CHECK-V7-LABEL: pr55484:
202+
; CHECK-V7: @ %bb.0:
203+
; CHECK-V7-NEXT: lsrs r1, r0, #8
204+
; CHECK-V7-NEXT: orr.w r0, r1, r0, lsl #8
205+
; CHECK-V7-NEXT: sxth r0, r0
206+
; CHECK-V7-NEXT: bx lr
190207
%2 = lshr i32 %0, 8
191208
%3 = shl i32 %0, 8
192209
%4 = or i32 %2, %3

llvm/test/CodeGen/RISCV/bswap-bitreverse.ll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,14 +1657,18 @@ define i32 @pr55484(i32 %0) {
16571657
;
16581658
; RV32ZBB-LABEL: pr55484:
16591659
; RV32ZBB: # %bb.0:
1660-
; RV32ZBB-NEXT: rev8 a0, a0
1661-
; RV32ZBB-NEXT: srai a0, a0, 16
1660+
; RV32ZBB-NEXT: srli a1, a0, 8
1661+
; RV32ZBB-NEXT: slli a0, a0, 8
1662+
; RV32ZBB-NEXT: or a0, a1, a0
1663+
; RV32ZBB-NEXT: sext.h a0, a0
16621664
; RV32ZBB-NEXT: ret
16631665
;
16641666
; RV64ZBB-LABEL: pr55484:
16651667
; RV64ZBB: # %bb.0:
1666-
; RV64ZBB-NEXT: rev8 a0, a0
1667-
; RV64ZBB-NEXT: srai a0, a0, 48
1668+
; RV64ZBB-NEXT: srli a1, a0, 8
1669+
; RV64ZBB-NEXT: slli a0, a0, 8
1670+
; RV64ZBB-NEXT: or a0, a1, a0
1671+
; RV64ZBB-NEXT: sext.h a0, a0
16681672
; RV64ZBB-NEXT: ret
16691673
;
16701674
; RV32ZBKB-LABEL: pr55484:

llvm/test/CodeGen/Thumb/rev.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ entry:
6767
define i32 @pr55484(i32 %0) {
6868
; CHECK-LABEL: pr55484:
6969
; CHECK: @ %bb.0:
70-
; CHECK-NEXT: revsh r0, r0
70+
; CHECK-NEXT: lsls r1, r0, #8
71+
; CHECK-NEXT: lsrs r0, r0, #8
72+
; CHECK-NEXT: orrs r0, r1
73+
; CHECK-NEXT: sxth r0, r0
7174
; CHECK-NEXT: bx lr
7275
%2 = lshr i32 %0, 8
7376
%3 = shl i32 %0, 8

llvm/test/CodeGen/X86/bswap.ll

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,15 +395,20 @@ define i32 @pr55484(i32 %0) {
395395
; CHECK-LABEL: pr55484:
396396
; CHECK: # %bb.0:
397397
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
398-
; CHECK-NEXT: bswapl %eax
399-
; CHECK-NEXT: sarl $16, %eax
398+
; CHECK-NEXT: movl %eax, %ecx
399+
; CHECK-NEXT: shrl $8, %ecx
400+
; CHECK-NEXT: shll $8, %eax
401+
; CHECK-NEXT: orl %ecx, %eax
402+
; CHECK-NEXT: cwtl
400403
; CHECK-NEXT: retl
401404
;
402405
; CHECK64-LABEL: pr55484:
403406
; CHECK64: # %bb.0:
404407
; CHECK64-NEXT: movl %edi, %eax
405-
; CHECK64-NEXT: bswapl %eax
406-
; CHECK64-NEXT: sarl $16, %eax
408+
; CHECK64-NEXT: shrl $8, %eax
409+
; CHECK64-NEXT: shll $8, %edi
410+
; CHECK64-NEXT: orl %eax, %edi
411+
; CHECK64-NEXT: movswl %di, %eax
407412
; CHECK64-NEXT: retq
408413
%2 = lshr i32 %0, 8
409414
%3 = shl i32 %0, 8

0 commit comments

Comments
 (0)