[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