| commit fadd20f80d6968a5a8623e0d1f804337ce084dcb |
| Author: Simon Pilgrim <llvm-dev@redking.me.uk> |
| Date: Sun Feb 27 11:25:17 2022 +0000 |
| |
| [DAG] Ensure type is legal for bswap(shl(x,c)) -> zext(bswap(trunc(shl(x,c-bw/2)))) fold |
| |
| As reported on D120192 |
| |
| diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |
| index c3bb838aac5c..996974452c1b 100644 |
| --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |
| +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |
| @@ -9618,7 +9618,8 @@ SDValue DAGCombiner::visitBSWAP(SDNode *N) { |
| EVT HalfVT = EVT::getIntegerVT(*DAG.getContext(), BW / 2); |
| if (ShAmt && ShAmt->getAPIntValue().ult(BW) && |
| ShAmt->getZExtValue() >= (BW / 2) && |
| - (ShAmt->getZExtValue() % 16) == 0 && TLI.isTruncateFree(VT, HalfVT) && |
| + (ShAmt->getZExtValue() % 16) == 0 && TLI.isTypeLegal(HalfVT) && |
| + TLI.isTruncateFree(VT, HalfVT) && |
| (!LegalOperations || hasOperation(ISD::BSWAP, HalfVT))) { |
| SDValue Res = N0.getOperand(0); |
| if (uint64_t NewShAmt = (ShAmt->getZExtValue() - (BW / 2))) |
| diff --git a/llvm/test/CodeGen/AArch64/arm64-rev.ll b/llvm/test/CodeGen/AArch64/arm64-rev.ll |
| index aa223eefbbfa..f48b46641821 100644 |
| --- a/llvm/test/CodeGen/AArch64/arm64-rev.ll |
| +++ b/llvm/test/CodeGen/AArch64/arm64-rev.ll |
| @@ -645,3 +645,38 @@ fail: |
| ret void |
| } |
| declare i16 @llvm.bswap.i16(i16) |
| + |
| +; Reduced regression from D120192 |
| +define void @test_bswap32_narrow(i32* %p0, i16* %p1) nounwind { |
| +; CHECK-LABEL: test_bswap32_narrow: |
| +; CHECK: // %bb.0: |
| +; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill |
| +; CHECK-NEXT: ldrh w8, [x0, #2] |
| +; CHECK-NEXT: mov x19, x1 |
| +; CHECK-NEXT: lsl w8, w8, #16 |
| +; CHECK-NEXT: rev w0, w8 |
| +; CHECK-NEXT: bl gid_tbl_len |
| +; CHECK-NEXT: strh wzr, [x19] |
| +; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload |
| +; CHECK-NEXT: ret |
| +; |
| +; GISEL-LABEL: test_bswap32_narrow: |
| +; GISEL: // %bb.0: |
| +; GISEL-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill |
| +; GISEL-NEXT: ldr w8, [x0] |
| +; GISEL-NEXT: mov x19, x1 |
| +; GISEL-NEXT: and w8, w8, #0xffff0000 |
| +; GISEL-NEXT: rev w0, w8 |
| +; GISEL-NEXT: bl gid_tbl_len |
| +; GISEL-NEXT: strh wzr, [x19] |
| +; GISEL-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload |
| +; GISEL-NEXT: ret |
| + %ld = load i32, i32* %p0, align 4 |
| + %and = and i32 %ld, -65536 |
| + %bswap = tail call i32 @llvm.bswap.i32(i32 %and) |
| + %and16 = zext i32 %bswap to i64 |
| + %call17 = tail call i32 bitcast (i32 (...)* @gid_tbl_len to i32 (i64)*)(i64 %and16) |
| + store i16 0, i16* %p1, align 4 |
| + ret void |
| +} |
| +declare i32 @gid_tbl_len(...) |
| diff --git a/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll b/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll |
| index 7579d550efb8..14a0162d5269 100644 |
| --- a/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll |
| +++ b/llvm/test/CodeGen/AArch64/load-combine-big-endian.ll |
| @@ -442,8 +442,8 @@ define i32 @zext_load_i32_by_i8(i32* %arg) { |
| ; CHECK-LABEL: zext_load_i32_by_i8: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ldrh w8, [x0] |
| -; CHECK-NEXT: rev w8, w8 |
| -; CHECK-NEXT: lsr w0, w8, #16 |
| +; CHECK-NEXT: lsl w8, w8, #16 |
| +; CHECK-NEXT: rev w0, w8 |
| ; CHECK-NEXT: ret |
| %tmp = bitcast i32* %arg to i8* |
| %tmp1 = getelementptr inbounds i8, i8* %tmp, i32 0 |
| diff --git a/llvm/test/CodeGen/AArch64/load-combine.ll b/llvm/test/CodeGen/AArch64/load-combine.ll |
| index d743ab3f643c..066ecb21dc10 100644 |
| --- a/llvm/test/CodeGen/AArch64/load-combine.ll |
| +++ b/llvm/test/CodeGen/AArch64/load-combine.ll |
| @@ -499,8 +499,8 @@ define i32 @zext_load_i32_by_i8_bswap(i32* %arg) { |
| ; CHECK-LABEL: zext_load_i32_by_i8_bswap: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ldrh w8, [x0] |
| -; CHECK-NEXT: rev w8, w8 |
| -; CHECK-NEXT: lsr w0, w8, #16 |
| +; CHECK-NEXT: lsl w8, w8, #16 |
| +; CHECK-NEXT: rev w0, w8 |
| ; CHECK-NEXT: ret |
| |
| %tmp = bitcast i32* %arg to i8* |